Home > fcn > synthesizer.m

synthesizer

PURPOSE ^

SYNTHESIZER Synthesizes the output from the vocal tract

SYNOPSIS ^

function data = synthesizer(X,dt,idxremove)

DESCRIPTION ^

 SYNTHESIZER    Synthesizes the output from the vocal tract
 data = synthesizer(X,dt);
 Where X is a 10xN matrix containing N time-points of Maeda parameters
       X(1,:)      : Jaw aperture  (0 to 1; 1=jaw high)
       X(2:4,:)    : Tongue shape  (0 to 1; 1/1/1=tongue back/tongue high/tongue tip high)
       X(5,:)      : Lip aperture  (0 to 1; 1=lips open)
       X(6,:)      : Lip protrusion  (0 to 1; 1=lip protruded)
       X(7,:)      : Larynx height (0 to 1; 1=larynx high)
       X(8,:)      : Voicing (0 to 1; 1=voiced)
       X(9,:)      : Pressure (0 to 1)
       X(10,:)     : F0 (in Hz)
 and data is a structure with fields:
       sig         : sound wave
       Fs          : sampling frequency
       Af          : area function
       Plot        : vocal tract contour

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function data = synthesizer(X,dt,idxremove)
0002 % SYNTHESIZER    Synthesizes the output from the vocal tract
0003 % data = synthesizer(X,dt);
0004 % Where X is a 10xN matrix containing N time-points of Maeda parameters
0005 %       X(1,:)      : Jaw aperture  (0 to 1; 1=jaw high)
0006 %       X(2:4,:)    : Tongue shape  (0 to 1; 1/1/1=tongue back/tongue high/tongue tip high)
0007 %       X(5,:)      : Lip aperture  (0 to 1; 1=lips open)
0008 %       X(6,:)      : Lip protrusion  (0 to 1; 1=lip protruded)
0009 %       X(7,:)      : Larynx height (0 to 1; 1=larynx high)
0010 %       X(8,:)      : Voicing (0 to 1; 1=voiced)
0011 %       X(9,:)      : Pressure (0 to 1)
0012 %       X(10,:)     : F0 (in Hz)
0013 % and data is a structure with fields:
0014 %       sig         : sound wave
0015 %       Fs          : sampling frequency
0016 %       Af          : area function
0017 %       Plot        : vocal tract contour
0018 %
0019 
0020 % alfnie@bu.edu
0021 
0022 
0023 persistent doam
0024 
0025 if nargin<3, 
0026   idxremove=[];
0027 end
0028 
0029 X0=cat(2,X(:,1),X);
0030 X(:,idxremove)=[];
0031 X=cat(2,X(:,1),X);
0032 Kmaeda=4;
0033 [N,Nt]=size(X);
0034 if N~=10,
0035   error('wrong dimensionality');
0036 end
0037 
0038 if isempty(doam),
0039   load('synthesizer.mat');
0040 end
0041 if 0, % use this to initialize Area function and VocalTract contour fitting functions
0042     X=max(-Kmaeda,min(Kmaeda, 2*randn(7,1e4)));
0043     Af=zeros([2,17,size(X,2)]); P1=zeros([4,29,size(X,2)]);
0044     for n1=1:size(X,2),
0045       [nill,nill,nill,Af(:,:,n1),nill,P1(:,:,n1)]=doAM(X(:,n1));
0046     end
0047     cd('fcn');
0048     if 1,
0049       Y=cat(1,shiftdim(Af(1,:,:),1),shiftdim(20*Af(2,1,:),1));
0050       [Y_fit,params]=ppr(cat(1,X,ones(1,size(X,2))),Y,...
0051                          'components',32,'control',5,'order',2);
0052         disp(100*(1-sum(sum(abs(Y-Y_fit).^2))/sum(sum(abs(Y-repmat(mean(Y,2),[1,size(Y,2)])).^2))));
0053         load synthesizer.mat;
0054         doam.Af=params;
0055         save synthesizer.mat doam;
0056     end
0057     if 1,
0058         Y=reshape(P1,4*29,size(P1,3));
0059         [Y_fit,params]=ppr(cat(1,X,ones(1,size(X,2))),Y,...
0060                            'components',16,'control',5,'order',2);
0061         disp(100*(1-sum(sum(abs(Y-Y_fit).^2))/sum(sum(abs(Y-repmat(mean(Y,2),[1,size(Y,2)])).^2))));
0062         load synthesizer.mat;
0063         doam.VocalTract=params;
0064         save synthesizer.mat doam;
0065     end
0066     cd('..');
0067 end
0068 
0069 % Computes Area function and Vocaltract contour
0070 t=ppr(cat(1,Kmaeda*(2*X(1:7,:)-1),ones(1,Nt)),doam.Af);
0071 data.Af=t(1:end-1,:);
0072 data.dx=repmat(t(end,:)/20,[size(t,1)-1,1]);
0073 t=ppr(cat(1,Kmaeda*(2*X(1:7,:)-1),ones(1,Nt)),doam.VocalTract);
0074 opt.P1=reshape(t,[4,29,size(t,2)]);
0075 opt.Af=data.Af;
0076 
0077 Fs=(size(data.Af,1))*1000; 
0078 data.fs=Fs;
0079 Np=round(dt*(Nt-1)*Fs);
0080 
0081 % Modifies area function (physical models)
0082 Af=data.Af/50;
0083 xAf=linspace(0,1,size(data.Af,1))';
0084 Af=Af.*repmat(.5+1.5*sin(.9*pi*xAf),[1,size(data.Af,2)]);
0085 % interaction of articulator-pressure and air-pressure
0086 pAf=.001*(X(9+zeros(1,size(Af,1)),:).^2)+.5*Af;
0087 Af=max( pAf, Af );
0088 idx=find(diff(min(Af,[],1)>0,1,2)==1);
0089 Af=max(0, Af);
0090 Af=2*max(0, Af).^1.5;
0091 Af=cat(1,.01+zeros(1,size(Af,2)),Af,ones(1,size(Af,2)));
0092 Nl=31;
0093 for n1=1:length(idx),
0094   % pressure build-up
0095   X(9,min(Nt,1+idx(n1)+(0:Nl-1))) = ...
0096       1*(1+10*linspace(1,0,Nl).^2.*max(0,-.5+X(9,min(Nt,1+idx(n1)+(0:Nl-1))))).*...
0097       X(9,min(Nt,1+idx(n1)+(0:Nl-1)));
0098 end;
0099 
0100 % Generates impulse response
0101 rf=lpcaa2rf(max(eps,Af'));
0102 [ar,arp,aru,g]=lpcrf2ar(rf);  %g=abs(g).^1.5;
0103 im=lpcar2im(ar./(eps+g(:,ones(1,size(ar,2)))),3*64)';
0104 im=im.*repmat(exp(-linspace(0,5,size(im,1)))',[1,size(im,2)]);
0105 
0106 % Generates source
0107 sfilt=hamming(round(Fs*dt)+1); sfilt=sfilt/sum(sfilt);
0108 F0=repmat(60+60*X0(10,:),[round(Fs*dt),1]); F0=convn(F0(:),sfilt,'valid');
0109 F0(repmat(round(Fs*dt)*(idxremove(:)-1)',[round(Fs*dt),1])+repmat((1:round(Fs*dt))',[1,length(idxremove)]))=[]; % correct phase when synthesizing only a portion of a sound
0110 
0111 Ag0=repmat(X(8,:),[round(Fs*dt),1]); 
0112 Ag0=convn(Ag0(:),sfilt,'valid');
0113 
0114 AgP=repmat(X(9,:),[round(Fs*dt),1]); 
0115 AgP=convn(AgP(:),sfilt,'valid');
0116 
0117 Ag0=max(.01,min(1,1-Ag0)).^2;
0118 phase=cumsum(F0/Fs);
0119 %phase=cumsum((F0+10*randn(size(F0)))/Fs);
0120 noise=convn(randn([Np,1]),convn(exp(-.0005*(0:100).^2)',[-1;.5;1]),'same'); 
0121 noise=noise-mean(noise); noise=noise/sqrt(mean(abs(noise).^2))/4;
0122 
0123 glottal=glotlf(2,phase,[.8,.085,.2])+10*glotlf(1,phase,[.8,.085,.2]); 
0124 glottal=convn(glottal-mean(glottal),hamming(5),'same'); 
0125 glottal=glottal/sqrt(mean(abs(glottal).^2));
0126 
0127 % adult
0128 sig0=(AgP).*(sqrt(1-max(0,min(1,Ag0)).^2).*glottal + 1*max(0,min(1,Ag0)).*noise); 
0129 
0130 % Convolve to generate sound
0131 Nf=size(im,1);
0132 time=linspace(1,Nt,Np); 
0133 timel=floor(time); 
0134 timer=time-timel; 
0135 timel1=timel+1; 
0136 timel1(end)=Nt;
0137 
0138 if length(sig0)>Fs, % breaks into blocks to avoid memory problems
0139   sig=zeros(size(sig0'));
0140   for n1=1:ceil(length(sig0)/Fs),
0141     idx=max(0,Fs*(n1-1)-Nf+1)+1:min(length(sig0),n1*Fs);
0142     Sig=sample_window(sig0(idx),Nf,Nf-1,'hanning','same');
0143     idxvalid=find(idx>Fs*(n1-1)-ceil(Nf/2)+1);
0144     sig(idx(idxvalid)) = ...
0145         (1-timer(idx(idxvalid))) .* ...
0146         sum(Sig(:,idxvalid).*im(:,timel(idx(idxvalid))),1) + ...
0147         timer(idx(idxvalid)).*sum(Sig(:,idxvalid).*im(:,timel1(idx(idxvalid))),1);
0148   end
0149 else,
0150     Sig=sample_window(sig0,Nf,Nf-1,'hanning','same');
0151     sig=(1-timer).*sum(Sig.*im(:,timel),1) + timer.*sum(Sig.*im(:,timel1),1);
0152 end
0153 %sig=sig*5;
0154 
0155 % corrects possible clicks
0156 sig=sig./max(1,convn(abs(sig),30*hamming(51)/sum(hamming(51)),'same')); 
0157 
0158 data.sig=sig;
0159 data.Plot.P1=opt.P1;
0160 data.Plot.Af=opt.Af;
0161

Generated on Tue 27-Mar-2007 12:06:24 by m2html © 2003