% ====== Read db songDb=songDbRead('childSong'); for i=1:length(songDb) terms=split(songDb(i).songName, '_'); songDb(i).songName=terms{1}; end % ====== Find the right track index=find(strcmp('生日快樂', {songDb.songName})); note=double(songDb(index).track)'; % ====== Pitch tracking waveFile='happyBirthday.wav'; %waveFile='twinkle_twinkle_little_star.wav'; au=myAudioRead(waveFile); pfType=1; % 0 for AMDF, 1 for ACF ptOpt=ptOptSet(au.fs, au.nbits, pfType); ptOpt.mainFun='maxPickingOverPf'; showPlot=0; [pv, clarity]=pitchTrack(au, ptOpt, showPlot); % ====== Compute pv from the given note sequence index=find(pv~=0); pv=pv(index(1):end); leadingZeroNum=index(1)-1; % Cut off leading zeros pvNoRest=pv; pvNoRest(pvNoRest==0)=[]; pvLen=length(pv); pvMean=mean(pvNoRest); zeroIndex=find(pv==0); pv(zeroIndex)=nan; frameRate=au.fs/(ptOpt.frameSize-ptOpt.overlap); pv2=note2pv(note, frameRate); noteMean=mean(pv2(1:length(pv))); shiftedPv=pv-pvMean+noteMean; % Key transposition notePitch=note(1:2:end); % Use pitch only (只取音高) notePitch(notePitch==0)=[]; % Delete rests (刪除休止符) % ====== Linear search of 101 times within [-2 2] (上下平移 101 次,得到最短距離) clear minDist dtwPath dtwOpt=dtw3withRestM('defaultOpt'); dtwOpt.endCorner=0; shift=linspace(-2, 2, 101); for i=1:length(shift) newPv=shiftedPv+shift(i); [minDist(i), dtwPath{i}] = dtw3withRestM(newPv, notePitch, dtwOpt); end [minValue, minIndex]=min(minDist); bestShift=shift(minIndex); bestShiftedPv=shiftedPv+bestShift; inducedPv=notePitch(dtwPath{minIndex}(2,:)); inducedPv(zeroIndex)=nan; % ====== Add back the leading zeros pv=[nan*ones(1,leadingZeroNum), pv]; bestShiftedPv=[nan*ones(1,leadingZeroNum), bestShiftedPv]; inducedPv=[nan*ones(1,leadingZeroNum), inducedPv]; pvLen=length(pv); % ====== Plotting and playback % === Plot the pitch without rest plot(1:pvLen, pv, '.-', 1:pvLen, bestShiftedPv, '.-', 1:pvLen, inducedPv, '.-'); legend('Original PV', 'Best shifted PV', 'Induced PV', 'location', 'NorthEast'); fprintf('Best shift = %f\n', bestShift); fprintf('Min. distance = %f\n', minValue); fprintf('Hit return to hear the original pitch vector...\n'); pause; pvPlay(pv, frameRate); fprintf('Hit return to hear the shifted pitch vector...\n'); pause; pvPlay(bestShiftedPv, frameRate); inducedNote=pv2noteStrict(inducedPv, frameRate); fprintf('Hit return to hear the induced pitch vector...\n'); pause; notePlay(inducedNote, 1); fs=16000; %wavwrite(note2wave(inducedNote, 1, fs), fs, 8, 'inducedNote2.wav');