rmeddis@38
|
1 function [iih,IPIhisttime,IPIhistweight]=track_formants_from_IPI_guy(IFRAN_pattern, sfreq)
|
rmeddis@38
|
2 %
|
rmeddis@38
|
3 % tracks the formants according to an analysis proposed in Secker-Walker
|
rmeddis@38
|
4 % JASA 1990, section V.A
|
rmeddis@38
|
5 % Tim Jürgens, February 2011, code from Guy Brown included
|
rmeddis@38
|
6 %
|
rmeddis@38
|
7 % input: IFRAN_pattern: pattern of the auditory model (dependend on the number of modules used)
|
rmeddis@38
|
8 % first dimension: frequency channel,
|
rmeddis@38
|
9 % second dimension: time (samples)
|
rmeddis@38
|
10 % sfreq: sampling frequency
|
rmeddis@38
|
11 % output: iih: interpeak-interval histogram, matrix very similar
|
rmeddis@38
|
12 % the plot 5 in the Secker-Walker paper
|
rmeddis@38
|
13 %
|
rmeddis@38
|
14 %
|
rmeddis@38
|
15 %
|
rmeddis@38
|
16
|
rmeddis@38
|
17
|
rmeddis@38
|
18 time_axis = 0:1/sfreq:(size(IFRAN_pattern,2)-1)/sfreq;
|
rmeddis@38
|
19
|
rmeddis@38
|
20 %find how many samples of AN_pattern are 10ms and 3ms
|
rmeddis@38
|
21 %one_sample_is_a_time_of = time_axis(2);
|
rmeddis@38
|
22 [tmp, start_time_index] = min(abs(0-time_axis));
|
rmeddis@38
|
23 [tmp, stop10_time_index] = min(abs(0.010-time_axis));
|
rmeddis@38
|
24 number_of_samples10ms = stop10_time_index - start_time_index;
|
rmeddis@38
|
25
|
rmeddis@38
|
26 [tmp, stop3_time_index] = min(abs(0.003-time_axis));
|
rmeddis@38
|
27 number_of_samples3ms = stop3_time_index - start_time_index;
|
rmeddis@38
|
28 every_3ms = 1:number_of_samples3ms:size(IFRAN_pattern,2)-number_of_samples10ms;
|
rmeddis@38
|
29
|
rmeddis@38
|
30 hamm_window = hamming(11);
|
rmeddis@38
|
31 halfHamming = (length(hamm_window)-1)/2;
|
rmeddis@38
|
32
|
rmeddis@38
|
33 % window normalization
|
rmeddis@38
|
34
|
rmeddis@38
|
35 norm = conv(ones(1,floor(number_of_samples10ms/2)),hamm_window);
|
rmeddis@38
|
36 norm = norm(5+1:end-5)';
|
rmeddis@38
|
37 win_size = number_of_samples10ms;
|
rmeddis@38
|
38 half_win_size = floor(win_size/2);
|
rmeddis@38
|
39 hop_size = number_of_samples3ms;
|
rmeddis@38
|
40
|
rmeddis@38
|
41
|
rmeddis@38
|
42 %pre-allocation due to speed
|
rmeddis@38
|
43 %Acorr = zeros(size(IFRAN_pattern,1),size(every_3ms,2),number_of_samples10ms*2+1);
|
rmeddis@38
|
44 %RAcorr = zeros(size(IFRAN_pattern,1),size(every_3ms,2),number_of_samples10ms*2+1);
|
rmeddis@38
|
45 %SRAcorr = zeros(size(IFRAN_pattern,1),size(every_3ms,2),number_of_samples10ms*2+1-10);
|
rmeddis@38
|
46 IPIhisttime = zeros(size(IFRAN_pattern,1),size(every_3ms,2),3);
|
rmeddis@38
|
47 IPIhistweight = zeros(size(IFRAN_pattern,1),size(every_3ms,2),3); %maximum 3 peaks from the SRA
|
rmeddis@38
|
48 iih = zeros(half_win_size,size(every_3ms,2));
|
rmeddis@38
|
49
|
rmeddis@38
|
50
|
rmeddis@38
|
51
|
rmeddis@38
|
52
|
rmeddis@38
|
53 for iCounter = 1:size(IFRAN_pattern,1) %each channel
|
rmeddis@38
|
54 fprintf('Channel No. %i\n',iCounter);
|
rmeddis@38
|
55 %time_counter = 1;
|
rmeddis@38
|
56 %for jCounter = every_3ms %every 3ms time segment
|
rmeddis@38
|
57
|
rmeddis@38
|
58
|
rmeddis@38
|
59
|
rmeddis@38
|
60 %% Guy's code
|
rmeddis@38
|
61 % enframe this signal
|
rmeddis@38
|
62
|
rmeddis@38
|
63 frames = enframe(IFRAN_pattern(iCounter,:),win_size,hop_size);
|
rmeddis@38
|
64
|
rmeddis@38
|
65 % compute the autocorrelation
|
rmeddis@38
|
66
|
rmeddis@38
|
67 acf = real(ifft(abs(fft(frames,[],2)).^2,[],2));
|
rmeddis@38
|
68 acf(acf<0)=0;
|
rmeddis@38
|
69 acf = sqrt(acf(:,1:half_win_size));
|
rmeddis@38
|
70
|
rmeddis@38
|
71 % smooth with hamming window and take the root
|
rmeddis@38
|
72
|
rmeddis@38
|
73 for frame=1:size(acf,1)
|
rmeddis@38
|
74
|
rmeddis@38
|
75 %%debug
|
rmeddis@38
|
76 %if iCounter == 130
|
rmeddis@38
|
77 % disp('here');
|
rmeddis@38
|
78 %end
|
rmeddis@38
|
79
|
rmeddis@38
|
80
|
rmeddis@38
|
81 sra = conv(acf(frame,:),hamm_window);
|
rmeddis@38
|
82 sra = sra(halfHamming+1:end-halfHamming)./norm';
|
rmeddis@38
|
83 df = [0 ; diff(sra')];
|
rmeddis@38
|
84 idx = find((df(1:end-1)>=0)&(df(2:end)<0));
|
rmeddis@38
|
85 % interpolate
|
rmeddis@38
|
86 a=df(idx);
|
rmeddis@38
|
87 b=df(idx+1);
|
rmeddis@38
|
88 idx = (idx-1+a./(a-b));
|
rmeddis@38
|
89 % get rid of a zero peak, if it exists
|
rmeddis@38
|
90 idx = idx(idx>1);
|
rmeddis@38
|
91 %include the zeroth peak
|
rmeddis@38
|
92 %idx = [1 idx']';
|
rmeddis@38
|
93 % peak values corresponding to these intervals
|
rmeddis@38
|
94 amp = interp1(1:length(sra),sra,idx,'linear');
|
rmeddis@38
|
95 % if required, remove peaks that lie below the mean sra
|
rmeddis@38
|
96 % note that we disregard the value at zero delay
|
rmeddis@38
|
97 %if (params.removePeaksBelowMean)
|
rmeddis@38
|
98 valid = find(amp>1.2*mean(sra(1:end)));
|
rmeddis@38
|
99 idx = idx(valid);
|
rmeddis@38
|
100 amp = amp(valid);
|
rmeddis@38
|
101 %end
|
rmeddis@38
|
102 % only use the first four peaks (three intervals)
|
rmeddis@38
|
103 idx = idx(1:min(4,length(idx)));
|
rmeddis@38
|
104 % find the intervals
|
rmeddis@38
|
105 interval = diff(idx);
|
rmeddis@38
|
106 % now histogram the intervals
|
rmeddis@38
|
107 if (~isempty(interval))
|
rmeddis@38
|
108 for k=1:length(interval),
|
rmeddis@38
|
109 iih(round(interval(k)),frame) = iih(round(interval(k)),frame)+amp(k);
|
rmeddis@38
|
110 IPIhisttime(iCounter,frame,k) = interval(k)/sfreq;
|
rmeddis@38
|
111 IPIhistweight(iCounter,frame,k) = amp(k);
|
rmeddis@38
|
112 end
|
rmeddis@38
|
113 end
|
rmeddis@38
|
114
|
rmeddis@38
|
115 end
|
rmeddis@38
|
116
|
rmeddis@38
|
117
|
rmeddis@38
|
118
|
rmeddis@38
|
119
|
rmeddis@38
|
120 %% end Guy's code
|
rmeddis@38
|
121
|
rmeddis@38
|
122
|
rmeddis@38
|
123 % %take the autocorrelation (ACF) of a 10ms-segment of each channel
|
rmeddis@38
|
124 % Acorr(iCounter,time_counter,:) = xcorr(IFRAN_pattern(iCounter,jCounter:number_of_samples10ms+jCounter),'biased'); %biased scales the ACF by the reciprocal of the length of the segment
|
rmeddis@38
|
125 % %root calculation
|
rmeddis@38
|
126 % RAcorr(iCounter,time_counter,:) = sqrt(abs(Acorr(iCounter,time_counter,:)));
|
rmeddis@38
|
127 %
|
rmeddis@38
|
128 % %smoothing using the 11-point hamming window
|
rmeddis@38
|
129 % for kCounter = 6:size(RAcorr(iCounter,time_counter,:),3)-5 %start with 6 and end with 5 samples
|
rmeddis@38
|
130 % %less the length of time_axis not to get in conflict with the length of
|
rmeddis@38
|
131 % %the hamm_window
|
rmeddis@38
|
132 % SRAcorr(iCounter,time_counter,kCounter-5) = ...
|
rmeddis@38
|
133 % squeeze(RAcorr(iCounter,time_counter,(kCounter-5):(kCounter+5)))'*hamm_window./sum(hamm_window);
|
rmeddis@38
|
134 % end
|
rmeddis@38
|
135 %
|
rmeddis@38
|
136 % %mean value of actual SRA
|
rmeddis@38
|
137 % SRA_mean = mean(SRAcorr(iCounter,time_counter,:));
|
rmeddis@38
|
138 %
|
rmeddis@38
|
139 % %find signed zero-crossings of the first derivative (=difference)
|
rmeddis@38
|
140 % z_crossings_indices = find(diff(sign(diff(squeeze(SRAcorr(iCounter,time_counter,:))))) < 0)+1; %+1 is necessary, because diff shortens vector by 1
|
rmeddis@38
|
141 % middle_index = ceil(size(SRAcorr(iCounter,time_counter,:),3)/2);
|
rmeddis@38
|
142 %
|
rmeddis@38
|
143 % validCounter = 1;
|
rmeddis@38
|
144 % valid_z_crossings_indices = [];
|
rmeddis@38
|
145 % %find valid zero-crossings (peak higher than meanvalue and within first 5 ms of SRA)
|
rmeddis@38
|
146 % for lCounter = 1:length(z_crossings_indices)
|
rmeddis@38
|
147 % if (SRAcorr(iCounter,time_counter,z_crossings_indices(lCounter)) > SRA_mean) && ...
|
rmeddis@38
|
148 % (abs(z_crossings_indices(lCounter)-middle_index) < round(number_of_samples10ms/2));
|
rmeddis@38
|
149 % valid_z_crossings_indices(validCounter) = z_crossings_indices(lCounter);
|
rmeddis@38
|
150 % validCounter = validCounter+1;
|
rmeddis@38
|
151 % end
|
rmeddis@38
|
152 % end
|
rmeddis@38
|
153 %
|
rmeddis@38
|
154 % %find main peak in the ACF
|
rmeddis@38
|
155 % [tmp,index_of_z_crossings_main_index] = min(abs(middle_index-valid_z_crossings_indices));
|
rmeddis@38
|
156 % if ~tmp == 0
|
rmeddis@38
|
157 % disp('middle peak not appropriately found');
|
rmeddis@38
|
158 % end
|
rmeddis@38
|
159 %
|
rmeddis@38
|
160 % %%% for debugging
|
rmeddis@38
|
161 % % if iCounter == 130
|
rmeddis@38
|
162 % % disp('here');
|
rmeddis@38
|
163 % % figure, plot(squeeze(SRAcorr(iCounter,time_counter,:)));
|
rmeddis@38
|
164 % % hold on, plot([1 length(squeeze(SRAcorr(iCounter,time_counter,:)))],[SRA_mean SRA_mean],'r-');
|
rmeddis@38
|
165 % % end
|
rmeddis@38
|
166 % %%%
|
rmeddis@38
|
167 %
|
rmeddis@38
|
168 % %generate IPI-histogram: take the first 3 intervals of SRAcorr
|
rmeddis@38
|
169 % %(positive delay) in the first 5 ms
|
rmeddis@38
|
170 % histcounter = 1;
|
rmeddis@38
|
171 % for lCounter = index_of_z_crossings_main_index+1:min([length(valid_z_crossings_indices(index_of_z_crossings_main_index+1:end)) 3])+index_of_z_crossings_main_index
|
rmeddis@38
|
172 % sampledifference = abs(valid_z_crossings_indices(lCounter)-valid_z_crossings_indices(lCounter-1));
|
rmeddis@38
|
173 % %the difference between two adjacent peaks in the SRA is taken
|
rmeddis@38
|
174 % %as IPI estimate
|
rmeddis@38
|
175 % IPIhisttime(iCounter,time_counter,histcounter) = sampledifference*one_sample_is_a_time_of;
|
rmeddis@38
|
176 % %the amplitude of the SRA at the start of the SRA interval is
|
rmeddis@38
|
177 % %taken as the IPIweight
|
rmeddis@38
|
178 % IPIhistweight(iCounter,time_counter,histcounter) = SRAcorr(iCounter,time_counter,valid_z_crossings_indices(lCounter-1));
|
rmeddis@38
|
179 % histcounter = histcounter + 1;
|
rmeddis@38
|
180 % end
|
rmeddis@38
|
181
|
rmeddis@38
|
182 %time_counter = time_counter+1;
|
rmeddis@38
|
183 end
|
rmeddis@38
|
184
|