0001 function [c,qq,ff,tt,po]=modspect(s,fs,m,nf,nq,p)
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
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 persistent PP
0134 if isempty(PP)
0135
0136
0137
0138
0139 PP.logr=120;
0140 PP.tagc=0;
0141 PP.tagt=2;
0142 PP.tinc=0.25e-3;
0143 PP.tovl=16;
0144 PP.tpad=30e-3;
0145
0146 PP.trnd=1;
0147 PP.twin='m';
0148 PP.fpow='p';
0149 PP.fmin=40;
0150 PP.fmax=10000;
0151 PP.fwin='t';
0152 PP.fbin=0.1;
0153 PP.ppow='a';
0154 PP.pinc=16e-3;
0155 PP.povl=2;
0156 PP.pwin='m';
0157 PP.ppad=200e-3;
0158
0159 PP.prnd=1;
0160 PP.mpow='p';
0161 PP.mwin='t';
0162 PP.mbin=15;
0163 PP.mmin=50;
0164 PP.mmax=400;
0165 PP.qpow='a';
0166 PP.qdcq=0;
0167 PP.qdcp=0;
0168 PP.dzcq=0;
0169 PP.dzcp=0;
0170 PP.dncp=30;
0171 PP.dncq=15;
0172 PP.ddet=0;
0173 PP.ddnt=2;
0174 PP.ddep=0;
0175 PP.ddnp=1;
0176 PP.unit=0;
0177 PP.dplt=0;
0178
0179 PP.cent=0.2;
0180 PP.cchk=0.2;
0181 end
0182 po=PP;
0183 switch nargin
0184 case 0
0185
0186 nn=sort(fieldnames(PP));
0187 cnn=char(nn);
0188 fprintf('%d Voicebox parameters:\n',length(nn));
0189
0190 for i=1:length(nn);
0191 if ischar(PP.(nn{i}))
0192 fmt=' %s = %s\n';
0193 else
0194 fmt=' %s = %g\n';
0195 end
0196 fprintf(fmt,cnn(i,:),PP.(nn{i}));
0197 end
0198 return
0199 case 1
0200 error('no sample frequency specified');
0201 case 2
0202 p=[];
0203 case 3
0204 if isstruct(m)
0205 p=m;
0206 m='';
0207 else
0208 p=[];
0209 end
0210 nf=[];
0211 nq=[];
0212 case 4
0213 if isstruct(nf)
0214 p=nf;
0215 nf=[];
0216 else
0217 p=[];
0218 end
0219 nq=[];
0220 case 5
0221 if isstruct(nq)
0222 p=nq;
0223 nq=[];
0224 else
0225 p=[];
0226 end
0227 end
0228 if isstruct(p)
0229 nn=fieldnames(p);
0230 for i=1:length(nn)
0231 if isfield(po,nn{i})
0232 po.(nn{i})=p.(nn{i});
0233 end
0234 end
0235 end
0236
0237
0238
0239 for i=1:length(m)
0240 switch m(i)
0241 case 'g'
0242 po.tagc=1;
0243 case {'r','n','m'}
0244 po.twin=m(i);
0245 po.pwin=m(i);
0246 case {'T','N','M'}
0247 po.fwin=lower(m(i));
0248 po.mwin=po.fwin;
0249 case {'a','c'}
0250 po.fpow=m(i);
0251 case {'p','l'}
0252 po.ppow=m(i);
0253 case 'A'
0254 po.mpow=lower(m(i));
0255 case {'P','L'}
0256 po.qpow=lower(m(i));
0257 case 'f'
0258 po.qdcq=1;
0259 case 'F'
0260 po.qdcp=1;
0261 case 'z'
0262 po.dzcq=1;
0263 case 'Z'
0264 po.dzcp=1;
0265 case 'd'
0266 po.ddet=1;
0267 case 'D'
0268 po.ddep=1;
0269 case 'u'
0270 po.unit=1;
0271 case 's'
0272 po.dplt=bitor(po.dplt,31+512);
0273 case 'S'
0274 po.dplt=bitor(po.dplt,1023);
0275 end
0276 end
0277
0278 if ~nargout
0279 po.dplt=bitor(po.dplt,4);
0280 end
0281 if ~isempty(nf)
0282 po.dncp=nf;
0283 end
0284 if ~isempty(nq)
0285 po.dncq=nq;
0286 end
0287
0288 lnf=length(nf);
0289 if lnf>=1
0290 po.fbin=nf(1);
0291 if lnf>=2
0292 po.fmin=nf(2);
0293 if lnf>=3
0294 po.fmax=nf(3);
0295 if lnf>=4
0296 po.dncp=nf(4);
0297 end
0298 end
0299 end
0300 end
0301 lnq=length(nq);
0302 if lnq>=1
0303 po.mbin=nq(1);
0304 if lnq>=2
0305 po.mmin=nq(2);
0306 if lnq>=3
0307 po.mmax=nq(3);
0308 if lnq>=4
0309 po.dncq=nq(4);
0310 end
0311 end
0312 end
0313 end
0314
0315
0316
0317 po.ddep=po.ddep & (po.qdcp==0);
0318 po.dzcq=po.dzcq | (po.qdcq==0);
0319 po.dzcp=po.dzcp | (po.qdcp==0);
0320
0321 logth=10^(-po.logr/10);
0322 ns=length(s);
0323 axhandle=[];
0324
0325
0326
0327 if po.tagc
0328 tau=po.tagt*fs;
0329 ax2=[1 -exp(-1/tau)];
0330 bx2=sum(ax2);
0331 sm=mean(s(1:min(ns,round(tau))).^2);
0332 if sm>0
0333 s=s./sqrt(filter(bx2,ax2,s.^2,-ax2(2)*sm));
0334 end
0335 end
0336 if bitand(po.dplt,32)
0337 if bitand(po.dplt,1)
0338 figure;
0339 end
0340 plot((1:ns)/fs,s);
0341 axhandle(end+1)=gca;
0342 title('Input after AGC');
0343 xlabel('Time (s)');
0344 end
0345
0346
0347
0348 ni=ceil(po.tinc*fs);
0349 nw=ni*po.tovl;
0350 nf=ceil(max(nw,po.tpad*fs));
0351 if po.trnd
0352 nf=2^nextpow2(nf);
0353 else
0354 nf=round(nf);
0355 end
0356 switch po.twin
0357 case 'm'
0358 w=hamming(nw+1)'; w(end)=[];
0359 case 'n'
0360 w=hanning(nw-1)';
0361 case 'r'
0362 w=ones(nw,1);
0363 end
0364 fx=rfft(enframe(s,w,ni),nf,2);
0365 [nft,nff]=size(fx);
0366 if bitand(po.dplt,64)
0367 if bitand(po.dplt,1)
0368 figure;
0369 end
0370 fp=fx.*conj(fx);
0371 imagesc(((0:nft-1)*ni+(nw+1)/2)/fs,(0:nff-1)*fs*0.001/nf,10*log10(max(fp,max(fp(:))*1e-6))');
0372 axhandle(end+1)=gca;
0373 hanc= colorbar;
0374 set(get(hanc,'ylabel'),'String','dB');
0375 axis('xy');
0376 title('Input Spectrogram');
0377 xlabel('Time (s)');
0378 ylabel('Frequency (kHz)');
0379 end
0380 [mbk,ffm]=melbankm(po.fbin,nf,fs,po.fmin/fs,min(po.fmax/fs+(po.fmax==0),0.5),po.fwin);
0381 switch [po.fpow po.ppow]
0382 case 'aa'
0383 px=abs(fx)*mbk';
0384 case {'ap','al'}
0385 px=(abs(fx)*mbk').^2;
0386 case 'pa'
0387 px=sqrt((fx.*conj(fx))*mbk');
0388 case {'pp','pl'}
0389 px=(fx.*conj(fx))*mbk';
0390 case 'ca'
0391 px=abs(fx*mbk');
0392 case {'cp','cl'}
0393 px=fx*mbk';
0394 px=px.*conj(px);
0395 end
0396 if po.ppow=='l'
0397 px=log(max((px),max(px(:))*logth));
0398 end
0399 if bitand(po.dplt,128)
0400 if bitand(po.dplt,1)
0401 figure;
0402 end
0403 switch po.ppow
0404 case 'a'
0405 imagesc(((0:nft-1)*ni+(nw+1)/2)/fs,ffm/1000,20*log10(max(px,max(px(:))*1e-3))');
0406 case 'p'
0407 imagesc(((0:nft-1)*ni+(nw+1)/2)/fs,ffm/1000,10*log10(max(px,max(px(:))*1e-6))');
0408 case 'l'
0409 imagesc(((0:nft-1)*ni+(nw+1)/2)/fs,ffm/1000,max(px*10/log(10),max(px(:))*10/log(10)-60)');
0410 end
0411 axhandle(end+1)=gca;
0412 hanc= colorbar;
0413 set(get(hanc,'ylabel'),'String','dB');
0414 axis('xy');
0415 title('Mel Spectrogram');
0416 xlabel('Time (s)');
0417 ylabel('Frequency (k-mel)');
0418 end
0419 npf=length(ffm);
0420 mni=ceil(po.pinc*fs/ni);
0421 mnw=mni*po.povl;
0422 mnf=ceil(max(mnw,po.ppad*fs/ni));
0423 if po.prnd
0424 mnf=2^nextpow2(mnf);
0425 else
0426 mnf=round(mnf);
0427 end
0428 nmt=fix((nft-mnw+mni)/mni);
0429 ix=repmat((1:mnw)',1,nmt)+repmat((0:nmt-1)*mni,mnw,1);
0430 mx=rfft(reshape(px(ix(:),:),mnw,nmt*npf),mnf,1);
0431
0432 [qbk,qqm]=melbankm(po.mbin,mnf,100*fs/ni,po.mmin*ni/fs,min(po.mmax*ni/fs+(po.mmax==0),0.5),po.mwin);
0433 nqq=length(qqm);
0434 switch po.mpow
0435 case 'a'
0436 qx=reshape(qbk*abs(mx),nqq,nmt,npf);
0437 case 'p'
0438 qx=reshape(qbk*(mx.*conj(mx)),nqq,nmt,npf);
0439 end
0440 switch [po.mpow po.qpow]
0441 case 'aa'
0442 qx=reshape(qbk*abs(mx),nqq,nmt,npf);
0443 case {'ap','al'}
0444 qx=reshape(qbk*abs(mx),nqq,nmt,npf).^2;
0445 case 'pa'
0446 qx=sqrt(reshape(qbk*(mx.*conj(mx)),nqq,nmt,npf));
0447 case {'pp','pl'}
0448 qx=reshape(qbk*(mx.*conj(mx)),nqq,nmt,npf);
0449 end
0450 if po.qpow=='l'
0451 qx=log(max((qx),max(qx(:))*logth));
0452 end
0453 tt=((1+mnw*ni+nw-ni)/2+(0:nmt-1)*mni*ni)/fs;
0454
0455 if bitand(po.dplt,256) && (~bitand(po.dplt,4) || po.qdcq>0 || po.qdcp>0)
0456 if bitand(po.dplt,1)
0457 figure;
0458 end
0459 switch po.qpow
0460 case 'a'
0461 dqx=20*log10(max(qx,max(qx(:))*1e-3));
0462 case 'p'
0463 dqx=10*log10(max(qx,max(qx(:))*1e-6));
0464 case 'l'
0465 dqx=max(qx*10/log(10),max(qx(:))*10/log(10)-60);
0466 end
0467 dqx(end+1,:,:)=max(dqx(:));
0468 dqx=reshape(permute(dqx,[2,1,3]),nmt,(nqq+1)*npf);
0469 ffq=ffm(1)+((0:(nqq+1)*npf)-(nqq-1)/2)*(ffm(2)-ffm(1))/(nqq+1);
0470 imagesc(tt,ffq/1000,dqx');
0471 axhandle(end+1)=gca;
0472 hanc= colorbar;
0473 set(get(hanc,'ylabel'),'String','dB');
0474 axis('xy');
0475 title('Modulation Spectrogram');
0476 xlabel('Time (s)');
0477 ylabel('Frequency (k-mel)');
0478 end
0479 ndq=nqq;
0480 if po.qdcq
0481 dx=reshape(rdct(reshape(qx,nqq,nmt*npf)),nqq,nmt,npf);
0482 ndq=min(ndq,po.dncq+1);
0483 else
0484 dx=qx;
0485 end
0486 ndf=npf;
0487 if po.qdcp
0488 dx=permute(reshape(rdct(reshape(permute(qx,[3,1,2]),npf,nqq*nmt)),npf,nqq,nmt),[2 3 1]);
0489 ndf=min(ndf,po.dncp+1);
0490 elseif po.ddep
0491 nv=po.ddnp;
0492 vv=(-nv:nv)*-3/(nv*(nv+1)*(2*nv+1)*(ffm(2)-ffm(1)));
0493 dxdp=filter(vv,1,dx,[],3);
0494 dxdp=dxdp(:,:,[repmat(2*nv+1,1,nv) 2*nv+1:npf repmat(npf,1,nv)]);
0495 end
0496 if po.ddet
0497 nv=po.ddnt;
0498 vv=(-nv:nv)*-3/(nv*(nv+1)*(2*nv+1)*(tt(2)-tt(1)));
0499 dxdt=filter(vv,1,dx,[],2);
0500 dxdt=dxdt(:,[repmat(2*nv+1,1,nv) 2*nv+1:nmt repmat(nmt,1,nv)],:);
0501 end
0502 nqj=ndq-(po.dzcq==0);
0503 nqk=nqj+ndq*(po.ddep+po.ddet);
0504 npk=ndf-(po.dzcp==0);
0505 c=zeros(nqk,npk,nmt);
0506 c(1:nqj,:,:)=permute(dx(1+ndq-nqj:ndq,:,1+ndf-npk:ndf),[1,3,2]);
0507 if bitand(po.dplt,512)
0508 if bitand(po.dplt,1)
0509 figure;
0510 end
0511 ffx=repmat(mel2frq(ffm(:)),1,nqq)/1000;
0512 qqx=repmat(mel2frq(qqm(:)')/100,npf,1);
0513 plot(qqx,ffx,'xb');
0514 axis([[qqx(1) qqx(end)]*[1.1 -0.1; -0.1 1.1] [ffx(1) ffx(end)]*[1.1 -0.1; -0.1 1.1]]);
0515 title('Frequency bin centres');
0516 xlabel(sprintf('%.1f : %.1f : %.1f mod-mel = Modulation Frequency (Hz)',qqm(1)/100,(qqm(2)-qqm(1))/100,qqm(end)/100));
0517 ylabel(sprintf('%.0f : %.0f : %.0f mel = Frequency (kHz)',ffm(1),ffm(2)-ffm(1),ffm(end)));
0518 end
0519 if bitand(po.dplt,4)
0520 if bitand(po.dplt,1)
0521 figure;
0522 end
0523 dqx=dx(1+ndq-nqj:ndq,:,1+ndf-npk:ndf);
0524 dqxmx=max(abs(dqx(:)));
0525 dqxge=dqx>=0;
0526 dbfact=2-(po.qpow=='p');
0527 dqxa=max(abs(dqx),dqxmx*10^(-6/dbfact));
0528 dqxmn=min(dqxa(:));
0529 dblab='';
0530 if(mean(dqxa(:)>dqxmn+po.cent*(dqxmx-dqxmn)))<po.cchk
0531 dboff=abs(round(dbfact*10*log10(dqxmn)));
0532 dblab='{\pm}dB';
0533 if ~all(dqxge(:))
0534 dqxa=dqxa/dqxmn;
0535 if dqxmn>1 && dboff~=0
0536 dblab=sprintf('{\\pm}dB - %d',dboff);
0537 else
0538 dblab=sprintf('{\\pm}dB + %d',dboff);
0539 end
0540 else
0541 dblab='dB';
0542 end
0543 dqx=dbfact*10*log10(dqxa).*(2*dqxge-1);
0544 end
0545 dqx(end+1,:,:)=max(dqx(:));
0546 dqx=reshape(permute(dqx,[2,1,3]),nmt,(nqj+1)*npk);
0547 ffq=ffm(1)+((0:(nqj+1)*npf)-(nqj-1)/2)*(ffm(2)-ffm(1))/(nqj+1);
0548 imagesc(tt,ffq/1000,dqx');
0549 axhandle(end+1)=gca;
0550 hanc= colorbar;
0551 set(get(hanc,'ylabel'),'String',dblab);
0552 axis('xy');
0553 if po.qdcq
0554 title('Modulation spectrum DCT');
0555 else
0556 title('Modulation spectrum');
0557 end
0558 xlabel('Time (s)');
0559 if po.qdcp
0560 ylabel('Quefrency (k-mel^{-1})');
0561 else
0562 ylabel('Frequency (k-mel)');
0563 end
0564 end
0565
0566 if po.ddep
0567 c(nqj+1:nqj+ndq,:,:)=permute(dxdp(1:ndq,:,1+ndf-npk:ndf),[1,3,2]);
0568 if bitand(po.dplt,8)
0569 if bitand(po.dplt,1)
0570 figure;
0571 end
0572 dqx=dxdp(1:ndq,:,1+ndf-npk:ndf);
0573 dqxmx=max(abs(dqx(:)));
0574 dqxge=dqx>=0;
0575 dbfact=2-(po.qpow=='p');
0576 dqxa=max(abs(dqx),dqxmx*10^(-6/dbfact));
0577 dqxmn=min(dqxa(:));
0578 dblab='';
0579 if(mean(dqxa(:)>dqxmn+po.cent*(dqxmx-dqxmn)))<po.cchk
0580 dboff=abs(round(dbfact*10*log10(dqxmn)));
0581 dblab='{\pm}dB';
0582 if ~all(dqxge(:))
0583 dqxa=dqxa/dqxmn;
0584 if dqxmn>1 && dboff~=0
0585 dblab=sprintf('{\\pm}dB - %d',dboff);
0586 else
0587 dblab=sprintf('{\\pm}dB + %d',dboff);
0588 end
0589 else
0590 dblab='dB';
0591 end
0592 dqx=dbfact*10*log10(dqxa).*(2*dqxge-1);
0593 end
0594 dqx(end+1,:,:)=max(dqx(:));
0595 dqx=reshape(permute(dqx,[2,1,3]),nmt,(ndq+1)*npk);
0596 ffq=ffm(1)+((0:(ndq+1)*npf)-(ndq-1)/2)*(ffm(2)-ffm(1))/(ndq+1);
0597 imagesc(tt,ffq/1000,dqx');
0598 axhandle(end+1)=gca;
0599 hanc= colorbar;
0600 set(get(hanc,'ylabel'),'String',dblab);
0601 axis('xy');
0602 if po.qdcq
0603 title('Modulation spectrum DCT = freq derivative');
0604 else
0605 title('Modulation spectrum = freq derivative');
0606 end
0607 xlabel('Time (s)');
0608 if po.qdcp
0609 ylabel('Quefrency (k-mel^{-1})');
0610 else
0611 ylabel('Frequency (k-mel)');
0612 end
0613 end
0614 end
0615 if po.ddet
0616 c(nqk-ndq+1:nqk,:,:)=permute(dxdt(1:ndq,:,1+ndf-npk:ndf),[1,3,2]);
0617 if bitand(po.dplt,16)
0618 if bitand(po.dplt,1)
0619 figure;
0620 end
0621 dqx=dxdt(1:ndq,:,1+ndf-npk:ndf);
0622 dqxmx=max(abs(dqx(:)));
0623 dqxge=dqx>=0;
0624 dbfact=2-(po.qpow=='p');
0625 dqxa=max(abs(dqx),dqxmx*10^(-6/dbfact));
0626 dqxmn=min(dqxa(:));
0627 dblab='';
0628 if(mean(dqxa(:)>dqxmn+po.cent*(dqxmx-dqxmn)))<po.cchk
0629 dboff=abs(round(dbfact*10*log10(dqxmn)));
0630 dblab='{\pm}dB';
0631 if ~all(dqxge(:))
0632 dqxa=dqxa/dqxmn;
0633 if dqxmn>1 && dboff~=0
0634 dblab=sprintf('{\\pm}dB - %d',dboff);
0635 else
0636 dblab=sprintf('{\\pm}dB + %d',dboff);
0637 end
0638 else
0639 dblab='dB';
0640 end
0641 dqx=dbfact*10*log10(dqxa).*(2*dqxge-1);
0642 end
0643 dqx(end+1,:,:)=max(dqx(:));
0644 dqx=reshape(permute(dqx,[2,1,3]),nmt,(ndq+1)*npk);
0645 ffq=ffm(1)+((0:(nqj+1)*npf)-(nqj-1)/2)*(ffm(2)-ffm(1))/(nqj+1);
0646 imagesc(tt,ffq/1000,dqx');
0647 axhandle(end+1)=gca;
0648 hanc= colorbar;
0649 set(get(hanc,'ylabel'),'String',dblab);
0650 axis('xy');
0651 if po.qdcq
0652 title('Modulation spectrum DCT = time derivative');
0653 else
0654 title('Modulation spectrum = time derivative');
0655 end
0656 xlabel('Time (s)');
0657 if po.qdcp
0658 ylabel('Quefrency (k-mel^{-1})');
0659 else
0660 ylabel('Frequency (k-mel)');
0661 end
0662 end
0663 end
0664 if po.unit
0665 ff=ffm;
0666 qq=qqm/100;
0667 else
0668 ff=mel2frq(ffm);
0669 qq=mel2frq(qqm)/100;
0670 end
0671 if length(axhandle)>1
0672 if ~bitand(po.dplt,32+64)
0673 linkaxes(axhandle)
0674 else
0675 linkaxes(axhandle,'x')
0676 end
0677 end
0678
0679