📄 mft6.m
字号:
disp(' ');
disp('SCRIPT: mft6.m ***********************************************');
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% McCandless Formant Tracker attempt #6
% This is the final version used in jmw's dissertation
%
% jmw
% 2/15/94
% 12/21/93
%
% uses last formant freqs for new estimates.
% AND starts at highest power and works forward andbackward
%
% this version saves formant tracks to hard disk (AND AMPLITUDES!)
%
% initial values are for MALE voices ONLY.
% See McCandless Paper for initial estimates for female voices ...
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PLT = 1; % flag to plot results
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
file_string = sprintf('temp/%s.mat', name);
s=sprintf('loading ./%s from hard disk ...',file_string);
disp(s);
s=sprintf('load %s', file_string);
eval(s);
signal = eval(name);
file_string = sprintf('temp/%s_Data.mat', name);
s=sprintf('loading ./%s from hard disk ...',file_string);
disp(s);
s=sprintf('load %s', file_string);
eval(s);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% do the entire sequence of steps for each v frame
VERB1 = 0; % verbosity flags
VERB2 = 0;
[m,n]=size(cofa); % get size of data
f1=zeros(1,m);
f2 = f1;
f3 = f1;
f4 = f1;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% find valid frame with highest power
[sort_power,power_index]=sort(power);
target_frame = 0;
for j=1:10,
if(target_frame==0 & VUS_voicetype(power_index(m-j+1))=='v')
target_frame = power_index(m-j+1);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('finding formants ...');
for i=target_frame:-1:1, % begin main loop backwards
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
allslotsfilled = 0;
MAXPASSES = 30;
r = 1.0;
passcnt = 1; % count number of passes
while( ~allslotsfilled & (passcnt<=MAXPASSES) & (r >= 0.88) ),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP #1: find peaks for all frames that are 'v'
p = [ 0 0 0 0 ]; % allocate mem for peaks for curremt frame
amp = [ 0 0 0 0 ]; % allocate mem for amplitudes of pks for curremt frame
if(VUS_voicetype(i)=='v') % find peaks if v
% adjust radius depending upon pass number
if (passcnt==1)
r = 1.0;
elseif (passcnt ==2)
r = 0.98;
else
r=r-0.004;
end;
[p,a]=fpeak4(cofa(i,:),r);
if (VERB1)
s=sprintf('pass %d ******** frame %d ***** (%d) **********',...
passcnt,i,range(i,1));
disp(s);
end;
if (VERB2 )
disp('p and a');
disp([p' a' ]);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP #2: fill slots with peaks using estimates as a guide
f_initial = [ 0 0 0 0 ]; % allocate mem
if(VUS_voicetype(i)=='v') % fill slots if v
% check if previous frame has valid formant values
f_prev = [f1(i+1) f2(i+1) f3(i+1) 3200];
f_prev_zero_index = find(f_prev == 0);
f_prev_valid = isempty(f_prev_zero_index);
if (f_prev_valid)
f_initial = fillslot(p, f_prev);
else
f_initial = fillslot(p);
end;
if (VERB2)
disp('f_initial');
disp([f_initial']);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP #3: remove duplicates using estimates as a guide
if (VUS_voicetype(i)=='v') % check slots if v
% check if previous frame has valid formant freqs
if (f_prev_valid)
f_nodup = rmdup4a(f_initial,f_prev);
else
f_nodup = rmdup4a(f_initial);
end;
if (VERB2)
disp('f_nodup');
disp([f_nodup']);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP 4: Deal with unassigned peaks
if (VUS_voicetype(i)=='v') % check unused pks if v
f_ed1 = redounas(f_nodup, p, a);
if (VERB2)
disp('f_ed1');
disp(f_ed1');
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save results in big array
if(VUS_voicetype(i)=='v')
f1(i) = f_ed1(1);
f2(i) = f_ed1(2);
f3(i) = f_ed1(3);
f4(i) = f_ed1(4);
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check if all slots filled if v
if(VUS_voicetype(i)=='v') % check if v
zeroindex = [];
fcheck = [f1(i) f2(i) f3(i) ]; % dont care about f4
zeroindex = find( fcheck == 0);
allslotsfilled = isempty(zeroindex);
if (VERB1 & allslotsfilled)
disp('ALL SLOTS FILLED');
elseif (VERB1 & ~allslotsfilled)
s=sprintf('formant %d NOT FILLED', zeroindex);
disp(s);
end;
passcnt = passcnt+1;
else
allslotsfilled = 1;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end; % end while loop
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end; % end main loop backwards
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=target_frame+1:m, % begin main loop forwards
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
allslotsfilled = 0;
MAXPASSES = 30;
r = 1.0;
passcnt = 1; % count number of passes
while( ~allslotsfilled & (passcnt<=MAXPASSES) & (r >= 0.88) ),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP #1: find peaks for all frames that are 'v'
p = [ 0 0 0 0 ]; % allocate mem for peaks for current frame
amp = [ 0 0 0 0 ]; % allocate mem for amplitudes of pks for curremt frame
if(VUS_voicetype(i)=='v') % find peaks if v
% adjust radius depending upon pass number
if (passcnt==1)
r = 1.0;
elseif (passcnt ==2)
r = 0.98;
else
r=r-0.004;
end;
[p,a]=fpeak4(cofa(i,:),r);
if (VERB1)
s=sprintf('pass %d ******** frame %d ***** (%d) **********',...
passcnt,i,range(i,1));
disp(s);
end;
if (VERB2 )
disp('p and a');
disp([p' a' ]);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP #2: fill slots with peaks using estimates as a guide
f_initial = [ 0 0 0 0 ]; % allocate mem
if(VUS_voicetype(i)=='v') % fill slots if v
% check if previous frame has valid formant values
f_prev = [f1(i-1) f2(i-1) f3(i-1) 3200];
f_prev_zero_index = find(f_prev == 0);
f_prev_valid = isempty(f_prev_zero_index);
if (f_prev_valid)
f_initial = fillslot(p, f_prev);
else
f_initial = fillslot(p);
end;
if (VERB2)
disp('f_initial');
disp([f_initial']);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP #3: remove duplicates using estimates as a guide
if (VUS_voicetype(i)=='v') % check slots if v
% check if previous frame has valid formant freqs
if (f_prev_valid)
f_nodup = rmdup4a(f_initial,f_prev);
else
f_nodup = rmdup4a(f_initial);
end;
if (VERB2)
disp('f_nodup');
disp([f_nodup']);
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP 4: Deal with unassigned peaks
if (VUS_voicetype(i)=='v') % check unused pks if v
f_ed1 = redounas(f_nodup, p, a);
if (VERB2)
disp('f_ed1');
disp(f_ed1');
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save results in big array
if(VUS_voicetype(i)=='v')
f1(i) = f_ed1(1);
f2(i) = f_ed1(2);
f3(i) = f_ed1(3);
f4(i) = f_ed1(4);
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check if all slots filled if v
if(VUS_voicetype(i)=='v') % check if v
zeroindex = [];
fcheck = [f1(i) f2(i) f3(i) ]; % dont care about f4
zeroindex = find( fcheck== 0);
allslotsfilled = isempty(zeroindex);
if (VERB1 & allslotsfilled)
disp('ALL SLOTS FILLED');
elseif (VERB1 & ~allslotsfilled)
s=sprintf('formant %d not filled', zeroindex);
disp(s);
end;
passcnt = passcnt+1;
else
allslotsfilled = 1;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end; % end while loop
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end; % end main loop forward
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% smooth out single zero values - This is a mod by jmw
ct=0;
for i =2:m-1,
if(f1(i)==0 & f1(i-1)~=0 & f1(i+1)~=0 )
f1(i) = (f1(i-1) +f1(i+1) ) /2.0;
ct = ct+1;
end;
if(f2(i)==0 & f2(i-1)~=0 & f2(i+1)~=0 )
f2(i) = (f2(i-1) +f2(i+1) ) /2.0;
ct = ct+1;
end;
if(f3(i)==0 & f3(i-1)~=0 & f3(i+1)~=0 )
f3(i) = (f3(i-1) +f3(i+1) ) /2.0;
ct = ct+1;
end;
end;
s=sprintf('SMOOTHING: eliminate single zero data values ... %d events',ct);
disp(s);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% smooth out double zero values - This is a mod by jmw
ct = 0;
for i =3:m-1,
if(f1(i)==0 & f1(i-1)==0 & f1(i-2)~=0 & f1(i+1)~=0 )
f1(i) = (f1(i-2) +f1(i+1) ) /2.0;
f1(i-1) = f1(i);
ct = ct+1;
end;
if(f2(i)==0 & f2(i-1)==0 & f2(i-2)~=0 & f2(i+1)~=0 )
f2(i) = (f2(i-2) +f2(i+1) ) /2.0;
f2(i-1) = f2(i);
ct = ct+1;
end;
if(f3(i)==0 & f3(i-1)==0 & f3(i-2)~=0 & f3(i+1)~=0 )
f3(i) = (f3(i-2) +f3(i+1) ) /2.0;
f3(i-1) = f3(i);
ct = ct+1;
end;
end;
s=sprintf('SMOOTHING: eliminate double zero data values ... %d events',ct);
disp(s);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% find amplitudes
disp('finding formant amplitudes ...');
N = 256;
a1 = zeros(m,1);
a2 = a1;
a3 = a1;
for i = 1:m,
if(VUS_voicetype(i)=='v')
% find formant amplitudes ...
[h1,w1]=freqz([1],cofa(i,:),N);
index1 = round(f1(i)/(5000/256));
a1(i) = abs(h1(index1+1));
index2 = round(f2(i)/(5000/256));
a2(i) = abs(h1(index2+1));
index3 = round(f3(i)/(5000/256));
a3(i) = abs(h1(index3+1));
end;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display results
titles = 1;
if (PLT)
disp('plotting results ...');
h=gcf;
figure(h);
clf;
subplot(311);
plot(signal);
grid on;
a=axis;
s=sprintf('%s',name);
if (titles)
title(s);
end;
subplot(313);
stairs(range(:,1),[f1' f2' f3' ]);
axis([a(1) a(2) 0 5000]);
grid on;
if (titles)
title('Formant Tracks: f1 f2 f3');
end;
subplot(312);
stairs(range(:,1),[20*log10(eps+a1) 20*log10(eps+a2) 20*log10(eps+a3) ]);
axis([a(1) a(2) 0 50]);
grid on;
if (titles)
title('Amplitude Tracks: a1 a2 a3');
end;
drawnow;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save results to hard disk
s=sprintf('saving ./%s_Ftrk to disk ...', name);
disp(s);
s=sprintf('save temp/%s_Ftrk.mat f1 f2 f3 f4 a1 a2 a3', name);
eval(s);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% clean up time
clear MAXPASSES f4 n
clear N f_ed1
clear PLT f_initial p
clear VERB1 f_nodup passcnt
clear VERB2 f_prev power
clear VUS_voicetype f_prev_valid power_index
clear a f_prev_zero_index r
clear a1 fcheck range
clear a2 file_string residue
clear a3 h signal
clear allslotsfilled h1 sort_power
clear amp i target_frame
clear cofa index1 voicetype
clear ct index2 w1
clear f1 index3 zeroindex
clear f2 j
clear f3 m titles
s=sprintf('clear %s',name);
eval(s);
clear s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -