pv=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 47.485736 48.330408 48.917323 49.836778 50.478049 50.807818 50.478049 50.807818 50.478049 49.836778 50.154445 49.836778 50.154445 50.478049 49.524836 0 0 52.930351 52.930351 52.930351 52.558029 52.193545 51.836577 51.836577 51.836577 52.558029 52.558029 52.930351 52.558029 52.193545 51.836577 51.486821 49.218415 48.330408 48.621378 48.917323 49.836778 50.478049 50.478049 50.154445 50.478049 50.807818 50.807818 50.154445 50.154445 50.154445 0 0 0 54.505286 55.349958 55.349958 55.788268 55.788268 55.788268 55.788268 55.788268 55.788268 55.788268 55.788268 55.349958 55.349958 54.505286 54.505286 54.922471 55.788268 55.788268 56.237965 55.788268 55.349958 55.349958 55.349958 55.349958 55.349958 55.349958 55.349958 55.349958 55.349958 55.349958 54.922471 54.922471 54.097918 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49.218415 49.218415 48.917323 49.218415 49.836778 50.478049 50.478049 50.154445 49.836778 50.154445 49.524836 49.836778 49.524836 0 0 55.788268 53.699915 53.699915 53.310858 53.310858 53.310858 53.310858 52.930351 52.930351 52.930351 52.930351 52.930351 52.558029 52.193545 51.486821 50.154445 49.836778 49.836778 50.154445 50.478049 50.478049 50.154445 49.836778 49.836778 49.524836 49.524836 49.524836 0 0 0 0 56.699654 57.661699 58.163541 58.163541 57.661699 57.661699 57.661699 57.661699 57.661699 57.661699 57.661699 57.661699 58.163541 57.173995 56.699654 56.237965 55.788268 56.237965 56.699654 56.699654 56.237965 55.788268 56.237965 56.237965 56.237965 56.237965 56.237965 56.237965 56.237965 55.788268 54.097918 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50.154445 50.154445 50.478049 51.143991 51.143991 50.807818 50.154445 51.143991 50.154445 50.478049 50.807818 50.478049 0 0 0 60.330408 61.524836 62.154445 62.807818 62.807818 62.807818 62.807818 62.807818 63.486821 63.486821 63.486821 63.486821 62.807818 62.807818 61.524836 59.213095 58.163541 58.680365 59.213095 59.762739 59.762739 59.762739 59.762739 59.762739 59.762739]; pv(pv==0)=[]; % Delete rests (刪除休止符) origPv=pv; pvLen=length(origPv); % Note representation, where the time unit of note duration is 1/64 seconds note=[60 29 60 10 62 38 60 38 65 38 64 77 60 29 60 10 62 38 60 38 67 38 65 77 60 29 60 10 72 38 69 38 65 38 64 38 62 77 0 77 70 29 70 10 69 38 65 38 67 38 65 38]; frameRate=8000/256; pv2=note2pv(note, frameRate); noteMean=mean(pv2(1:length(pv))); shiftedPv=pv-mean(pv)+noteMean; % Key transposition notePitch=note(1:2:end); % Use pitch only (只取音高) notePitch(notePitch==0)=[]; % Delete rests (刪除休止符) % Linear search of 81 times within [-2 2] (上下平移 81 次,得到最短距離) clear minDist dtwPath shift=linspace(-2, 2, 81); for i=1:length(shift) newPv=shiftedPv+shift(i); [minDist(i), dtwPath{i}] = dtw3(newPv, notePitch, 1, 0); end [minValue, minIndex]=min(minDist); bestShift=shift(minIndex); bestShiftedPv=shiftedPv+bestShift; inducedPv=notePitch(dtwPath{minIndex}(2,:)); plot(1:pvLen, origPv, '.-', 1:pvLen, bestShiftedPv, '.-', 1:pvLen, inducedPv, '.-'); legend('Original PV', 'Best shifted PV', 'Induced PV', 4); fprintf('Best shift = %f\n', bestShift); fprintf('Min. distance = %f\n', minValue); %fprintf('Hit return to hear the original pitch vector...\n'); pause; pvPlay(origPv, 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); fs=16000; wavwrite(note2wave(inducedNote, 1, fs), fs, 8, 'inducedNote2.wav');