diff Code/Descriptors/Matlab/MPEG7/FromWeb/VoiceSauce/func_GetA1A2A3.m @ 4:92ca03a8fa99 tip

Update to ICASSP 2013 benchmark
author Dawn Black
date Wed, 13 Feb 2013 11:02:39 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Code/Descriptors/Matlab/MPEG7/FromWeb/VoiceSauce/func_GetA1A2A3.m	Wed Feb 13 11:02:39 2013 +0000
@@ -0,0 +1,190 @@
+function [A1, A2, A3] = func_GetA1A2A3(y, Fs, F0, F1, F2, F3, variables, textgridfile)
+% [A1, A2, A3] = func_GetA1A2A3(y, Fs, F0, F1, F2, F3, variables, textgridfile)
+% Input:  y - input signal
+%         Fs - sampling frequency
+%         F0 - fundamental frequency (vector)
+%         F1-F3 - formant frequencies (vectors)
+%         variables - settings from VS
+%         textgridfile - textgrid filename if available (optional)
+% Output: A1, A2, A3 - uncorrected amplitudes of the spectra at the formant
+% frequencies.
+%
+% Author: Yen-Liang Shue, Speech Processing and Auditory Perception Laboratory, UCLA
+% Copyright UCLA SPAPL 2009
+
+N_periods = variables.Nperiods;
+sampleshift = (Fs / 1000 * variables.frameshift);
+
+A1 = zeros(length(F0), 1) * NaN;
+A2 = zeros(length(F0), 1) * NaN;
+A3 = zeros(length(F0), 1) * NaN;
+
+if (nargin == 7)
+
+    for k=1:length(F0)
+        ks = round(k * sampleshift);
+        
+        if (ks <= 0 || ks > length(y))
+            continue;
+        end
+        
+        F0_curr = F0(k);
+        
+        if (isnan(F0_curr) || F0_curr == 0) 
+            continue; 
+        end
+
+        N0_curr = 1 / F0_curr * Fs;
+               
+        ystart = round(ks - N_periods/2*N0_curr);
+        yend = round(ks + N_periods/2*N0_curr) - 1;
+        
+        if (ystart <= 0) 
+            continue; 
+        end;
+        
+        if (yend > length(y)) 
+            continue; 
+        end;
+        
+        yseg = y(ystart:yend);
+        
+        % proceed if no NaNs detected
+        if (~isnan(F1(k)) && ~isnan(F2(k)) && ~isnan(F3(k)) && ~isnan(N0_curr))
+            [A1_, fmax] = ana_GetMagnitudeMax(yseg, F1(k), Fs, 8192);
+            [A2_, fmax] = ana_GetMagnitudeMax(yseg, F2(k), Fs, 8192);
+            [A3_, fmax] = ana_GetMagnitudeMax(yseg, F3(k), Fs, 8192);
+
+            A1(k) = A1_;
+            A2(k) = A2_;
+            A3(k) = A3_;
+        end    
+    end
+else
+    % use textgrids - get ignore string list
+    tbuffer = variables.tbuffer;
+    ignorelabels = textscan(variables.TextgridIgnoreList, '%s', 'delimiter', ',');
+    ignorelabels = ignorelabels{1};   
+    
+    [labels, start, stop] = func_readTextgrid(textgridfile);
+    labels_tmp = [];
+    start_tmp = [];
+    stop_tmp = [];
+    
+    for k=1:length(variables.TextgridTierNumber)
+        inx = variables.TextgridTierNumber(k);
+        if (inx <= length(labels))
+            labels_tmp = [labels_tmp; labels{inx}];
+            start_tmp = [start_tmp; start{inx}];
+            stop_tmp = [stop_tmp; stop{inx}];
+        end
+    end
+    
+    labels = labels_tmp;
+    start = start_tmp;
+    stop = stop_tmp; 
+    
+    
+    for m=1:length(start)
+        switch(labels{m})
+            case ignorelabels
+                continue;  % skip anything that is within the ignore list
+        end
+        
+        kstart = round((start(m) * 1000 - tbuffer) / variables.frameshift);
+        kstop = round((stop(m) * 1000 + tbuffer) / variables.frameshift);
+        kstart(kstart <= 0) = 1;
+        kstop(kstop > length(F0)) = length(F0);
+        
+        ystart = round(kstart * sampleshift);
+        ystop = round(kstop * sampleshift);
+        ystart(ystart <= 0) = 1;
+        ystop(ystop > length(y)) = length(y);
+        
+        ysegment = y(ystart:ystop);
+        F0seg = F0(kstart:kstop);
+        F1seg = F1(kstart:kstop);
+        F2seg = F2(kstart:kstop);
+        F3seg = F3(kstart:kstop);
+               
+        for k=1:length(F0seg)
+            ks = round(k*sampleshift);
+            
+            if (ks <= 0 || ks > length(ysegment))
+                continue;
+            end
+            
+            F0_curr = F0seg(k);
+            if (isnan(F0_curr) || F0_curr == 0)
+                continue;
+            end
+            
+            N0_curr = Fs/F0_curr;
+            ysstart = round(ks - N_periods/2 * N0_curr);
+            ysend = round(ks + N_periods/2 * N0_curr) - 1;
+            
+            if (isnan(F1seg(k)) || isnan(F2seg(k)) || isnan(F3seg(k)))
+                continue;
+            end
+            
+            if (ysstart <= 0) 
+                continue; 
+            end;
+            if (ysend > length(ysegment)) 
+                continue; 
+            end;
+            
+            yseg = ysegment(ysstart:ysend);
+            
+            [A1_, fmax] = ana_GetMagnitudeMax(yseg, F1seg(k), Fs, 8192);
+            [A2_, fmax] = ana_GetMagnitudeMax(yseg, F2seg(k), Fs, 8192);
+            [A3_, fmax] = ana_GetMagnitudeMax(yseg, F3seg(k), Fs, 8192);
+            
+            inx = kstart + k - 1;
+            if (inx <= length(A1))
+                A1(inx) = A1_;
+                A2(inx) = A2_;
+                A3(inx) = A3_;
+            end                
+        
+        end
+    
+    end
+end
+
+
+%------------------------------------------------------------------------
+function [M,fmax] = ana_GetMagnitudeMax(x, Fx, Fs, fftlen)
+% Get maximal spectral magnitude of signal x around position Fx Hz in dB
+% Fx can be a vector of frequency points
+% Note that the bigger fftlen the better the resolution
+
+if (isnan(Fx))
+  M = NaN;
+  fmax = NaN;
+else
+
+  len = length(x);
+  hamlen = min(fftlen, len);
+  %X = fft(hamming(hamlen).*x(1:hamlen), fftlen);
+  factor = 1;  %/length(x);  % not exactly Kosher but compatible to dfs_magn()
+  X = fft(x,fftlen);
+  X(X==0) = 0.000000001;  % guard against log(0) warnings
+  X = 20*log10(factor*abs(X(1:fftlen/2, :)));
+  fstep = Fs / fftlen;
+  lowf = Fx-0.1*Fx;
+  if (lowf<0) lowf=0; end
+  highf = Fx+0.1*Fx;
+  if (highf>Fs/2-fstep) highf=Fs/2-fstep; end
+
+  for cnt = 1:length(Fx)
+      [M(cnt),pos] = max(X(1+round(lowf(cnt)/fstep):1+round(highf(cnt)/fstep), :));
+      fmax(cnt) = (pos-1+round(lowf(cnt)/fstep))*fstep;
+  end
+  
+end
+
+% f=0:fstep:(Fs/2-fstep);
+% plot(f,X); hold;
+% plot(pos, M, 'rx'); hold off;
+% fprintf('End get_magnitude_max()\n');