Home > melodyRecognition > melodyCompare.m

melodyCompare

PURPOSE ^

melodyCompare: Melody comparison for a given pitch vector [對一個使用者輸入的音高向量進行旋律辨識]

SYNOPSIS ^

function [distVec, minIndexVec, scoreVec] = melodyCompare(songDb, pitch, mrParam)

DESCRIPTION ^

melodyCompare: Melody comparison for a given pitch vector [對一個使用者輸入的音高向量進行旋律辨識]
    Usage: [distVec, minIndexVec, scoreVec] = melodyCompare(songDb, pitch, mrParam)
        songDb: song collection
        pitch: input pitch vector
        mrParam: MR parameters

    The comparison results are written back into songDb's field "score".

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [distVec, minIndexVec, scoreVec] = melodyCompare(songDb, pitch, mrParam)
0002 %melodyCompare: Melody comparison for a given pitch vector [對一個使用者輸入的音高向量進行旋律辨識]
0003 %    Usage: [distVec, minIndexVec, scoreVec] = melodyCompare(songDb, pitch, mrParam)
0004 %        songDb: song collection
0005 %        pitch: input pitch vector
0006 %        mrParam: MR parameters
0007 %
0008 %    The comparison results are written back into songDb's field "score".
0009 
0010 pitch=pitch(:)';                    % Change to a row vector [改為列向量]
0011 pitch=restHandle(pitch, mrParam.useRest);        % Handle rests [處理休止符]
0012 pitch=pitch-mean(pitch);                % Shift the pitch to have zero mean [平移到平均值為零]
0013 pitchLen = length(pitch);                % Length of the pitch vector [音高向量長度(點數)]
0014 maxSongLen = round(mrParam.lengthRatio*pitchLen);    % The song length is equal to mrParam.lengthRatio times the pitch length [標準歌曲長度最多只有輸入音高向量長度的 mrParam.lengthRatio 倍]
0015 pitch=pitch(1:mrParam.pvrr:end);            % Down-sample to reduce computation [降點以減低運算量]
0016 songNum=length(songDb);
0017 distVec=zeros(1, songNum);
0018 minIndexVec=zeros(1, songNum);
0019 
0020 switch mrParam.method
0021     case 'dtw1'
0022         for i=1:length(songDb),
0023 %            fprintf('%d/%d\n', i, length(songDb));
0024             song=songDb(i).pv;
0025             % ====== Take a reference song of an appropriate length [擷取歌曲適當長度]
0026             song=song(1:min(maxSongLen, length(song)));
0027             songLen = length(song);
0028             % ====== Shift song to have zero mean [平移歌曲,盡量使其和輸入音高向量有相同的基準(在此為平移至平均值為零)]
0029             songMean=mean(song(1:min(pitchLen, songLen)));    % Get mean of the song with the same length as the pitch vector [抓出歌曲的平均值(取其長度和輸入音高向量相同)]
0030             song=song-songMean;                % Shift to mean [平移到平均值]
0031             % ====== Down-sample to reduce computation [降點以減低運算量]
0032             song=song(1:mrParam.pvrr:end);
0033             % ====== Set DTW parameters [設定 DTW 參數]
0034             beginCorner=mrParam.beginCorner;        % 1: anchored beginning [頭固定]
0035             endCorner=mrParam.endCorner;            % 0: free end [尾浮動]
0036             % ====== Compute DTW [計算 DTW]
0037             distVec(i)=dtw4mr(pitch, song, mrParam);
0038             % ====== Compute DTW [計算 DTW]
0039         %    distVec(i) = dtw2mex(pitch, song, beginCorner, endCorner);
0040         end
0041     case 'dtw2'
0042         for i=1:length(songDb),
0043 %            fprintf('%d/%d\n', i, length(songDb));
0044             song=songDb(i).pv;
0045             % ====== Take a reference song of an appropriate length [擷取歌曲適當長度]
0046             song=song(1:min(maxSongLen, length(song)));
0047             songLen = length(song);
0048             % ====== Shift song to have zero mean [平移歌曲,盡量使其和輸入音高向量有相同的基準(在此為平移至平均值為零)]
0049             songMean=mean(song(1:min(pitchLen, songLen)));    % Get mean of the song with the same length as the pitch vector [抓出歌曲的平均值(取其長度和輸入音高向量相同)]
0050             song=song-songMean;                % Shift to mean [平移到平均值]
0051             % ====== Down-sample to reduce computation [降點以減低運算量]
0052             song=song(1:mrParam.pvrr:end);
0053             % ====== Set up DTW parameters [設定 DTW 參數]
0054             beginCorner=mrParam.beginCorner;    % 1: anchored beginning [頭固定]
0055             endCorner=mrParam.endCorner;        % 0: free end [尾浮動]
0056             % ====== Compute DTW (計算 DTW)
0057             distVec(i) = dtw2mex(pitch, song, beginCorner, endCorner);
0058         end
0059     case 'dtw1fixedPoint'
0060         for i=1:length(songDb),
0061 %            fprintf('%d/%d\n', i, length(songDb));
0062             song=songDb(i).pv;
0063             % ====== Take a reference song of an appropriate length [擷取歌曲適當長度]
0064             song=song(1:min(maxSongLen, length(song)));
0065             song=song(1:mrParam.pvrr:end);    % Down-sample to reduce computation [降點以減低運算量]
0066             % ====== Set up parameters for dtwFixedPoint
0067             param.dtwFunc='dtw1mex';
0068             param.anchorBeginning=mrParam.beginCorner;    % 1: anchored beginning [頭固定]
0069             param.anchorEnd=mrParam.endCorner;        % 0: free end [尾浮動]
0070             param.maxIterationNum=mrParam.dtwCount;
0071             [minDist, allDist, allPitchShift]=dtwFixedPoint(pitch, song, param);
0072             distVec(i)=minDist;
0073         end
0074     case 'dtw2fixedPoint'
0075         for i=1:length(songDb),
0076 %            fprintf('%d/%d\n', i, length(songDb));
0077             song=songDb(i).pv;
0078             % ====== Take a reference song of an appropriate length [擷取歌曲適當長度]
0079             song=song(1:min(maxSongLen, length(song)));
0080             song=song(1:mrParam.pvrr:end);    % Down-sample to reduce computation [降點以減低運算量]
0081             % ====== Set up parameters for dtwFixedPoint
0082             param.dtwFunc='dtw2mex';
0083             param.anchorBeginning=mrParam.beginCorner;    % 1: anchored beginning [頭固定]
0084             param.anchorEnd=mrParam.endCorner;        % 0: free end [尾浮動]
0085             param.maxIterationNum=mrParam.dtwCount;
0086             [minDist, allDist, allPitchShift]=dtwFixedPoint(pitch, song, param);
0087             distVec(i)=minDist;
0088         end    
0089     case 'ls'
0090         % ====== Set up LS parameters [設定 LS 參數]
0091         lowerRatio=mrParam.lowerRatio;        % 0.5;
0092         upperRatio=mrParam.upperRatio;        % 2.0;
0093         resolution=mrParam.resolution;        % 11;
0094         [scaledVecSet, scaledVecLen]=vecLinScaling(pitch, lowerRatio, upperRatio, resolution);
0095         for i=1:length(songDb)    % Compare pitch to each song
0096         %    fprintf('\t%d/%d: title=%s\n', i, length(songDb), songDb(i).title);
0097             anchorNum=length(songDb(i).anchorPvIndex);
0098             distVecInSong=zeros(anchorNum, 1);
0099             minIndexInSong=zeros(anchorNum, 1);
0100             for j=1:anchorNum
0101             %    fprintf('\t\t%d/%d:\n', j, anchorNum); pause;
0102             %    song=songDb(i).pv(songDb(i).noteStartIndex(j):end);        % A song from the note start index
0103                 song=songDb(i).pv(songDb(i).anchorPvIndex(j):end);        % A song from the anchor index
0104                 % ====== Take a reference song of an appropriate length [擷取歌曲適當長度]
0105                 song=song(1:min(maxSongLen, length(song)));
0106                 songLen = length(song);
0107                 % ====== Down-sample to reduce computation (降點以減低運算量)
0108                 song=song(1:mrParam.pvrr:end);
0109             %    % ====== Compute LS (計算 LS)
0110             %    distVec(i)=linScalingMex(pitch, song, lowerRatio, upperRatio, resolution, mrParam.lsDistanceType);
0111                 % ====== Compute LS (計算 LS) at each anchor point
0112                 [distVecInSong(j), minIndexInSong(j)]=linScaling2Mex(scaledVecSet, scaledVecLen, song, mrParam.lsDistanceType);
0113             end
0114             [distVec(i), minIndex]=min(distVecInSong);    % distVec(i): distance to song i. minIndex: anchor index
0115             minIndexVec(i)=minIndexInSong(minIndex);    %
0116         end
0117     case 'noteLevelDtw2'
0118         for i=1:length(songDb),
0119 %            fprintf('%d/%d\n', i, length(songDb));
0120             % ====== Shift song to have zero mean [平移歌曲,盡量使其和輸入音高向量有相同的基準(在此為平移至平均值為零)]
0121             song=songDb(i).pv;
0122             songLen = length(song);
0123             songMean=mean(song(1:min(pitchLen, songLen)));    % Get mean of the song with the same length as the pitch vector [抓出歌曲的平均值(取其長度和輸入音高向量相同)]
0124             songNote=songDb(i).track(1:2:end)';        % Use pitch only [只取音高]
0125             songNote=songNote-songMean;        
0126             % ====== Note segmentation [進行音符切割]
0127             pitchTh=0.8;
0128             minNoteDuration=0.1;
0129             userNote = noteSegment(pitch, mrParam.timeStep, pitchTh, minNoteDuration);
0130             % ====== Use dtw2 to compute the distance between song and userNote. [使用 DTW2 來計算 song 和 userNote 之間的距離]
0131             userNote=userNote(1:2:end);        % Use pitch only [只取音高]
0132             beginCorner=mrParam.beginCorner;        % 1: anchored beginning [頭固定]
0133             endCorner=mrParam.endCorner;            % 0: free end [尾浮動]
0134             distVec(i) = dtw2mex(userNote, songNote, beginCorner, endCorner);
0135         end
0136     case 'dtw3'
0137         for i=1:length(songDb),
0138 %            fprintf('%d/%d\n', i, length(songDb));
0139             % ====== Shift song to have zero mean [平移歌曲,盡量使其和輸入音高向量有相同的基準(在此為平移至平均值為零)]
0140             song=songDb(i).pv;
0141             songLen = length(song);
0142             songMean=mean(song(1:min(pitchLen, songLen)));    % Get mean of the song with the same length as the pitch vector [抓出歌曲的平均值(取其長度和輸入音高向量相同)]
0143             songNote=songDb(i).track(1:2:end)';        % Use pitch only [只取音高]
0144             songNote=songNote-songMean;
0145             % ====== Down-sample to reduce computation [降點以減低運算量]
0146             song=song(1:mrParam.pvrr:end);
0147             % ====== Set up DTW parametrs [設定 DTW 參數]
0148             beginCorner=mrParam.beginCorner;    % 1: anchored beginning [頭固定]
0149             endCorner=mrParam.endCorner;        % 0: free end [尾浮動]
0150             % ====== 計算 DTW
0151             distVec(i) = dtw3mex(pitch, songNote, beginCorner, endCorner);
0152         end
0153     otherwise
0154         error('Unknown method!');
0155 end
0156 
0157 % [a, b] = gBellParam(1.27, 0.95, 1.60, 0.5);
0158 a=1.60;
0159 b=6.37;
0160 scoreVec=100./(1+(distVec/a).^(2*b));

Generated on Tue 01-Jun-2010 09:49:37 by m2html © 2003