HRIR_Berechnung_translated.m 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. % This program evaluates the measured data resulted from the
  3. % HRTF-Measurements. The HRIRs associated to all measured
  4. % positions are determined by correction with the 'Empty-
  5. % Measurement'.
  6. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7. clear
  8. clc
  9. close all
  10. tic
  11. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  12. % Setup owl and condition (see also annotations.xlsx)
  13. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  14. % Define Parameters for saving
  15. owl = 'Merry' %#ok<NOPTS>
  16. condition = 'ruff_intact' %#ok<NOPTS>
  17. date_of_experiment = '2003-09-13' %#ok<NOPTS>
  18. % Data directories (in doctorade_datadir) and filename
  19. % Empty-Measurement:
  20. datadir_empty = 'Merry\normal';
  21. filepattern_empty = 'MerrynormalP0P0.dat';
  22. % HRTF-Measurement:
  23. datadir = 'Merry\normal';
  24. filepattern = '*0.dat';
  25. % Measured angles
  26. AZIMUTHS = (-160:20:160);
  27. ELEVATIONS = (-60:20:80);
  28. % AZIMUTHS = (-160:10:170);
  29. % ELEVATIONS = (-70:10:80);
  30. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. % Load doctorade_config, e.g. doctorade_datadir
  33. doctorade_datadir = 'D:\MATLAB\HRTF_Wagner_Lab\raw_data';
  34. doctorade_resultdir = 'D:\MATLAB\HRTF_Wagner_Lab\reults2';
  35. % Samplingrate
  36. samplingrate = 100000; % in Hz
  37. % Set parameters ("arbitrary" but fixed)
  38. window_length = 3.6; % length of the part of the HRIRs that is non-zero [in ms]
  39. hrir_length = 500; % corresponds to 5 ms
  40. begin = 400; % lower cutoff frequency of the band-pass filter [in Hz]
  41. ende = 9000; % upper cutoff frequency of the band-pass filter [in Hz]
  42. bandwidth = [num2str(begin) ' to ' num2str(ende) ' Hz'] %#ok<NOPTS>
  43. filterordnung = 10; % half of the filter order
  44. L_lang = 2 * 51000; % length of the FFT (twice as long as the measuremant)
  45. frequencies = (0:L_lang-1)*samplingrate/L_lang;
  46. % Matrices for saving the HRIRs
  47. hrirshifted_l = nan(numel(AZIMUTHS),numel(ELEVATIONS),L_lang);
  48. hrirshifted_r = nan(numel(AZIMUTHS),numel(ELEVATIONS),L_lang);
  49. % Highpass filter (top-hat filter with cutoff frequency 50Hz)
  50. highpass = zeros(1,L_lang/2);
  51. begin_high = 50;
  52. highpass(1,ceil(begin_high/100000*L_lang)+1:L_lang/2) = 1;
  53. highpass = [highpass 1 fliplr(highpass(1,2:length(highpass)))];
  54. % Band-pass filter (Butterworth filter with cutoff frequencies 400 and 9000 Hz and order 20)
  55. [z,p,k] = butter(filterordnung ,[begin/(samplingrate/2) ende/(samplingrate/2)], 'bandpass');
  56. sos = zp2sos(z,p,k);
  57. [h,f] = freqz(sos,L_lang/2,samplingrate);
  58. filter = [h.' 0 conj(fliplr(h(2:length(h)).'))];
  59. %% Empty-Measurement
  60. % The Empty-Measurement at (0°,0°) is used to determine the transfer functions of the loudspeakers, microphones, etc. These are needed later for correction.
  61. namesempty = dir(fullfile(doctorade_datadir, datadir_empty, filepattern_empty)); % lists all Empty-Measurements at (0°,0°)
  62. leftmeanallempty = zeros(length(namesempty),L_lang);
  63. rightmeanallempty = zeros(length(namesempty),L_lang);
  64. for i = 1:1:(length(namesempty)) % averages across five sweeps (every single measurement consits of five sweeps)
  65. filenameempty = namesempty(i).name;
  66. [rightempty , leftempty] = hrtf_dateilesen(fullfile(doctorade_datadir, datadir_empty, filenameempty));
  67. leftmeanempty = mean(leftempty(1:5,:));
  68. rightmeanempty = mean(rightempty(1:5,:));
  69. leftmeanempty = ifft(fft(leftmeanempty, L_lang) .* highpass);
  70. rightmeanempty = ifft(fft(rightmeanempty, L_lang) .* highpass);
  71. leftmeanallempty(i,:) = leftmeanempty;
  72. rightmeanallempty(i,:) = rightmeanempty;
  73. end
  74. leftmeanempty = mean(leftmeanallempty(1:i,:),1);% averages across five different measurements
  75. rightmeanempty = mean(rightmeanallempty(1:i,:),1);
  76. time = (0:L_lang-1)*1/samplingrate;
  77. fftleftempty = fft(leftmeanempty, L_lang);% is needed for corretion
  78. fftrightempty = fft(rightmeanempty, L_lang);
  79. %% Owl-HRIRs gets determined and transformed into matrix-form
  80. names = dir(fullfile(doctorade_datadir, datadir, filepattern)); % lists all owl-data
  81. for i = 1:1:(length(names))
  82. filename = names(i).name;
  83. disp(filename);
  84. [azi,ele] = filename2azel(filename); % determines azimuth and elevation of each measurement
  85. row = find(AZIMUTHS == azi);
  86. column = find(ELEVATIONS == ele);
  87. [right , left] = hrtf_dateilesen(fullfile(doctorade_datadir, datadir, filename));
  88. rightmean = mean(right(1:5,:)); % averages across five sweeps (every single measurement consits of five sweeps)
  89. leftmean = mean(left(1:5,:));
  90. rightmean = ifft(fft(rightmean, L_lang) .* highpass);
  91. leftmean = ifft(fft(leftmean, L_lang) .* highpass);
  92. fhr = fft(rightmean, L_lang);
  93. fhl = fft(leftmean, L_lang);
  94. fftIRright = (fhr./fftrightempty);% correction via division by Empty-Measurement in the frequency domain
  95. fftIRleft = (fhl./fftleftempty);
  96. fftIRleftband = fftIRleft .* filter;
  97. fftIRrightband = fftIRright .* filter;
  98. IRleftbandpass = ifft(fftIRleftband, 'symmetric');
  99. IRrightbandpass = ifft(fftIRrightband, 'symmetric');
  100. % Save HRIRs
  101. hrirshifted_l(row,column,:) = IRleftbandpass;
  102. hrirshifted_r(row,column,:) = IRrightbandpass;
  103. end
  104. %% Further transformations of the HRIR-Matrices
  105. % Correct the HRIR's offset (cyclic shift)
  106. [hrir_l, hrir_r, az_num, el_num] = offset(hrirshifted_l, hrirshifted_r, window_length, 1); % third argument in ms; fourth argument switches smoothing on or off
  107. % Shorten the HRIRs to a length of 5 ms (or p.r.n. a little bit more)
  108. limit = 1; % to make sure that the 5 ms window does not cut away information
  109. for i = 1:numel(AZIMUTHS)
  110. for j = 1:numel(ELEVATIONS)
  111. signal_l = squeeze(hrir_l(i,j,:)).';
  112. signal_r = squeeze(hrir_r(i,j,:)).';
  113. pos_l = find(signal_l ~= 0);
  114. pos_r = find(signal_r ~= 0);
  115. end_l = max(pos_l);
  116. end_r = max(pos_r);
  117. end_gesamt = max(end_l, end_r);
  118. if end_gesamt > limit
  119. limit = end_gesamt;
  120. end
  121. end
  122. end
  123. hrirshort_l = hrir_l(:, :, 1:max(hrir_length,limit));
  124. hrirshort_r = hrir_r(:, :, 1:max(hrir_length,limit));
  125. signallength_short = size(hrirshort_l,3);
  126. frequencies_short = (0:(signallength_short-1))*samplingrate/signallength_short; % frequencies from 0 to ~ 100000 Hz with a new step size
  127. time_short = (0:(signallength_short-1))*1/samplingrate;
  128. % Normalization of the HRIRs (for the EPhys-Experiments)
  129. idx_azi_0 = find(AZIMUTHS == 0);
  130. idx_ele_0 = find(ELEVATIONS == 0);
  131. left = squeeze(hrirshort_l(idx_azi_0,idx_ele_0,:)).';
  132. right = squeeze(hrirshort_r(idx_azi_0,idx_ele_0,:)).';
  133. energy_l = left * left.';
  134. energy_r = right * right.';
  135. energy = sqrt((energy_l + energy_r)/2);
  136. hrirshort_l = 1/energy * hrirshort_l;
  137. hrirshort_r = 1/energy * hrirshort_r;
  138. %% Create and save matlabfile for HRIR use in electrophysiological experiments
  139. hrir_l = hrirshort_l; % for saving the short HRIRs are renamed to hrir_l, hrir_r
  140. hrir_r = hrirshort_r;
  141. azimuths = AZIMUTHS';
  142. elevations = ELEVATIONS;
  143. dataname = [owl '__' condition '__hrir_result'];
  144. name = ['Owl: ' owl ';' ' Condition: ' condition ';' ' Date of experiment: ' num2str(date_of_experiment) '; ' 'Bandwidth: ' num2str(bandwidth)];
  145. save(fullfile(doctorade_resultdir, dataname), 'hrir_l' , 'hrir_r' , 'azimuths' , 'elevations' , 'samplingrate' , 'name');
  146. toc