0001 function out=DIVA_VocalTract(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 out=[];
0037 global DIVA_VocalTract_data
0038
0039 for indexargin=1:2:nargin,
0040 switch(varargin{indexargin}),
0041 case 'init',
0042 SessionFolder=strcat(DIVA('SessionFolder'),filesep);
0043 if nargin<indexargin+1 | isempty(varargin{indexargin+1}),
0044 initfile='';
0045 else,
0046 initfile=[SessionFolder,'Session_',varargin{indexargin+1},filesep,mfilename,'.mat'];
0047 end
0048 if isempty(initfile) | isempty(dir(initfile)),
0049 disp([mfilename, ' : Defining new session...']);
0050
0051 DIVA_VocalTract_data.params=struct(...
0052 'nMaeda',7,...
0053 'nArtic',8,...
0054 'MaedaSpread',4,...
0055 'JawLip',0.2,...
0056 'Amplitude',10,...
0057 'usesynth',0,...
0058 'vtcalc_fs',10000,...
0059 'fs',10000,...
0060 'noise',[],...
0061 'delayToSoundChannel',.020,...
0062 'delayToSensoryChannel',.005);
0063
0064
0065
0066 else,
0067 data=load(initfile,'-mat');
0068 DIVA_VocalTract_data.params=data.params;
0069 end
0070
0071 DIVA_VocalTract_data.params.vt = d_opvt;
0072 DIVA_VocalTract_data.params.TimeStep = DIVA('TimeStep');
0073 DIVA_VocalTract_data.params.delayToForwardModel=...
0074 DIVA_VocalTract_data.params.delayToSoundChannel+0*...
0075 DIVA('SoundChannel','delayToCochlea')+DIVA('Cochlea','delayToForwardModel');
0076
0077
0078 DIVA_VocalTract_data.params.current=struct(...
0079 'sound',[],...
0080 'configuration',[]);
0081
0082
0083
0084 out={'motor'};
0085
0086
0087 case 'save',
0088 SessionFolder=strcat(DIVA('SessionFolder'),filesep);
0089 if nargin<indexargin+1,
0090 initfile=[SessionFolder,'Session_','default',filesep,mfilename,'.mat'];
0091 else,
0092 initfile=[SessionFolder,'Session_',varargin{indexargin+1},filesep,mfilename,'.mat'];
0093 end
0094 params=DIVA_VocalTract_data.params;
0095 save(initfile,'params');
0096
0097 case 'exit',
0098 clear DIVA_VocalTract_data;
0099
0100
0101
0102 case 'disp',
0103 disp(DIVA_VocalTract_data.params);
0104 out=fieldnames(DIVA_VocalTract_data.params);
0105
0106
0107
0108 case 'motor',
0109 Ar0=varargin{indexargin+1};
0110 if(isempty(Ar0)),
0111 Ar0 = zeros(DIVA_VocalTract_data.params.nArtic,1);
0112 end
0113
0114
0115
0116 if(size(Ar0,1)>DIVA_VocalTract_data.params.nArtic),
0117 Ar0=M2Ar(Ar0);
0118 end
0119 Ar=Ar0;
0120
0121
0122 Maeda=zeros(DIVA_VocalTract_data.params.nMaeda,size(Ar,2));
0123 Maeda([1:4,6:7],:) = Ar(1:6,:);
0124 Art_val = -1.2;
0125 Ar_old = Ar;
0126 max_pos = 2;
0127 min_pos = 0.5;
0128
0129
0130 Ar(7,:) = (Ar(7,:)+DIVA_VocalTract_data.params.MaedaSpread)/...
0131 (2*DIVA_VocalTract_data.params.MaedaSpread)*(max_pos-(-min_pos))+(-min_pos);
0132 Ar(8,:) = (Ar(8,:)+DIVA_VocalTract_data.params.MaedaSpread)/...
0133 (2*DIVA_VocalTract_data.params.MaedaSpread)*(min_pos-(-max_pos))+(-max_pos);
0134
0135
0136 val = (Ar(7,:)<Ar(8,:)).*Ar(8,:);
0137 dAr7 = (val~=0).*((val-(-min_pos))/(max_pos-(-min_pos))*...
0138 (2*DIVA_VocalTract_data.params.MaedaSpread)-...
0139 DIVA_VocalTract_data.params.MaedaSpread-Ar_old(7,:));
0140 Ar_new = Ar_old;
0141 Ar_new(7,:) = Ar_old(7,:)+dAr7;
0142 Ar(7,:) = (Ar_new(7,:)+DIVA_VocalTract_data.params.MaedaSpread)/...
0143 (2*DIVA_VocalTract_data.params.MaedaSpread)*(max_pos-(-min_pos))+(-min_pos);
0144 Maeda(5,:) = Art_val+(DIVA_VocalTract_data.params.MaedaSpread-Art_val)*...
0145 max(Ar(7,:)-Ar(8,:),0)/(2*max_pos);
0146
0147
0148 Maeda = min(max(Maeda,-DIVA_VocalTract_data.params.MaedaSpread),...
0149 DIVA_VocalTract_data.params.MaedaSpread);
0150
0151
0152 Ar(1:8,:) = min(max(Ar(1:8,:),-DIVA_VocalTract_data.params.MaedaSpread),...
0153 DIVA_VocalTract_data.params.MaedaSpread);
0154
0155
0156 if DIVA_VocalTract_data.params.usesynth>0,
0157
0158 if size(Maeda,2)==1,
0159 data = ...
0160 synthX(DIVA_VocalTract_data.params.vt, ...
0161 Maeda(:,ones(1,DIVA_VocalTract_data.params.windowsizeOverTimeStep)),...
0162 DIVA_VocalTract_data.params);
0163 else,
0164 data = synthX(DIVA_VocalTract_data.params.vt, Maeda, ...
0165 DIVA_VocalTract_data.params);
0166 end
0167
0168 if isempty(DIVA_VocalTract_data.params.noise),
0169 data.sig = data.sig;
0170 else,
0171 data.sig = ...
0172 data.sig+...
0173 DIVA_VocalTract_data.params.noise(1+mod(0:length(data.sig)-1,...
0174 length(DIVA_VocalTract_data.params.noise)));
0175 end
0176 out=data.sig;
0177
0178 else,
0179 out = DIVA('ForwardModel','motor',Maeda(1:7,:));
0180 end
0181
0182 DIVA_VocalTract_data.params.current.sound = out;
0183 DIVA_VocalTract_data.params.current.configuration = [Ar0;Maeda];
0184
0185 if ~nargout,
0186
0187 DIVA('SoundChannel','sound',out,DIVA_VocalTract_data.params.fs,...
0188 DIVA_VocalTract_data.params.delayToSoundChannel);
0189 DIVA('SensoryChannel','configuration',[Ar0;Maeda],...
0190 DIVA_VocalTract_data.params.delayToSensoryChannel);
0191 DIVA('ForwardModel','motor',Ar0,...
0192 DIVA_VocalTract_data.params.delayToForwardModel);
0193
0194 DIVA('GUI','other_weights','motor');
0195 DIVA('GUI','other_weights','motor_weight');
0196 DIVA('ModelStatePlot','VocalTract','motor');
0197 else,
0198 out={DIVA_VocalTract_data.params.current.sound, ...
0199 DIVA_VocalTract_data.params.current.configuration};
0200 end
0201
0202 case 'synthsound',
0203
0204
0205
0206 if(isempty(varargin{indexargin+1})),
0207
0208
0209
0210 else,
0211
0212
0213 if(size(varargin{indexargin+1},1)==DIVA_VocalTract_data.params.nArtic+3),
0214 outm = DIVA('VocalTract','motor',...
0215 varargin{indexargin+1}(1:DIVA_VocalTract_data.params.nArtic,:));
0216 outg = varargin{indexargin+1}(DIVA_VocalTract_data.params.nArtic+1:end,:);
0217 else,
0218 nMotor = DIVA('MotorCortex','nMotor');
0219 outm = DIVA('VocalTract','motor',varargin{indexargin+1}(1:nMotor,:));
0220 outg = varargin{indexargin+1}(nMotor+1:end,:);
0221 end
0222
0223 data.fs = DIVA_VocalTract_data.params.vtcalc_fs;
0224 data.duration = size(varargin{indexargin+1},2);
0225
0226
0227 data.X = outm{2}(DIVA_VocalTract_data.params.nArtic+1:end,:);
0228
0229
0230
0231
0232
0233 data.Ag0 = [[0:data.duration-1]',...
0234 outg(1,:)',...
0235 ones(data.duration,1)];
0236 data.AgP = [[0:data.duration-1]',...
0237 outg(2,:)',...
0238 ones(data.duration,1)];
0239 data.F0 = [[0:data.duration-1]',...
0240 outg(3,:)',...
0241 ones(data.duration,1)];
0242 end
0243
0244
0245
0246
0247 ssound = synth1(DIVA_VocalTract_data.params.vt,data);
0248 out = {0.99*ssound./(max(abs(ssound(:)))),DIVA_VocalTract_data.params.fs};
0249
0250 case 'plot',
0251
0252
0253 out=DIVA('VocalTract','motor',varargin{indexargin+1});
0254 Maeda=out{2}(DIVA_VocalTract_data.params.nArtic+1:end,:);
0255 Ar=out{2}(1:DIVA_VocalTract_data.params.nArtic,:);
0256 plot(DIVA_VocalTract_data.params.vt,Maeda,...
0257 sum(Ar(1:8,:),1)~=0,Ar);
0258
0259
0260
0261 otherwise,
0262 if isfield(DIVA_VocalTract_data.params,varargin{indexargin}),
0263 if indexargin==nargin,
0264 out=DIVA_VocalTract_data.params.(varargin{indexargin});
0265 else,
0266 DIVA_VocalTract_data.params.(varargin{indexargin})=varargin{indexargin+1};
0267 end
0268 else,
0269 warning('DIVA_VocalTract: wrong argument');
0270 end
0271 end
0272 end
0273