function au2=vsdFeaExtract(au, vsdOpt, showPlot) % vsdFeaExtract: Wave to feature conversion for s/u/v detection % % Usage: % au2=vsdFeaExtract(au, showPlot) % % Example: % auFile='khair_1_01.wav'; % auFile='D:\dataSet\public\MIR-1K\Wavfile/Ani_2_03.wav'; % vsdOpt=vsdOptSet; % showPlot=1; % au2=vsdFeaExtract(auFile, vsdOpt, showPlot); % Roger Jang, 20040910, 20070417, 20130201, 20170203, 20200112 if nargin<1, selfdemo; return; end if nargin<2, vsdOpt=vsdOptSet; end if nargin<3, showPlot=0; end %% Read the given audio file if ischar(au), au=myAudioRead(au); end % au is actual the wave file name %au=waveFormatConvert(au, 8000, 8, 1); % Format conversion to mono, 8KHz, 8bits %% Read the given pitch file pvFile=strrep(au.file, vsdOpt.audioDir, vsdOpt.pitchDir); % Replace the audioDir with pitchDir pvFile=[pvFile(1:end-3), 'pv']; if ~exist(pvFile, 'file') % Cannot find the pv file to specify the groundtruth warning('Cannot fine the pv file %s!', pvFile); feature=[]; frameClass=[]; other=[]; au2=au; au2.feature=feature; au2.tOutput=frameClass; au2.other=other; return end %% MFCC extraction mfccOpt=mfccOptSet(au.fs); mfccOpt.frameSize=vsdOpt.frameSize; mfccOpt.overlap=vsdOpt.overlap; y=mean(au.signal, 2); feature=wave2mfcc(y, au.fs, mfccOpt); frameNum=size(feature,2); % ====== add annotation annotation=cell(frameNum); for i=1:frameNum annoStr=sprintf('%s\n%s', au.file, int2str(i)); annoStr=strrep(annoStr, '\', '/'); annoStr=strrep(annoStr, '_', '\_'); annotation{i}=annoStr; end other.annotation=annotation; % ====== Read human-labeled pitch file frameClass=[]; if exist(pvFile, 'file') targetPitch=asciiRead(pvFile); if length(targetPitch)>frameNum, targetPitch=targetPitch(1:frameNum); end % Due to the difference between buffer.m (used before) and buffer2.m (used now) frameClass=targetPitch>0; frameClass=frameClass+1; % {0,1} ===> {1,2} frameClass=frameClass(:)'; end other.inputName={'1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'}; % index for MFCC other.frameTime=frame2sampleIndex(1:frameNum, vsdOpt.frameSize, vsdOpt.overlap)/au.fs; other.tPitch=targetPitch; % === Put everything together for output au2=au; au2.feature=feature; au2.tOutput=frameClass; au2.other=other; if showPlot plotTitle=strrep(au.file, '\', '/'); plotTitle=strrep(plotTitle, '_', '\_'); DS.input=feature; DS.output=frameClass; DS.inputName=other.inputName; DS.outputName=vsdOpt.outputName; DS.annotation=other.annotation; subplot(211); dsScatterPlot(DS); title(['Raw data: ', plotTitle]); feature2=inputNormalize(feature(1:2, :)); DS.input=feature2(1:2, :); DS.output=frameClass; subplot(212); dsScatterPlot(DS); title(['Normalized data: ', plotTitle]); end % ====== Self demo function selfdemo mObj=mFileParse(which(mfilename)); strEval(mObj.example);