noteMatch.asv
上传用户:abcwxk
上传日期:2016-05-20
资源大小:434k
文件大小:1k
源码类别:

midi

开发平台:

Visual C++

  1. function [names_top10, costs_top10] = noteMatch(notes_steps);
  2. L2 = length(notes_steps);
  3. % 读取库
  4. load midLib; % 库中一首歌的midi音符序列
  5. count = midLib{1,1};
  6. midData = midLib{1,2};
  7. costs_top10 = [NaN NaN NaN NaN NaN...
  8.     NaN NaN NaN NaN NaN;...
  9.     0 0 0 0 0 0 0 0 0 0];
  10. names_top10 = cell(1,10);
  11. % 遍历,寻找top10最低差错的序列,返回
  12. for n = 1:count
  13.     % 读取第n个歌曲的相对音高序列
  14.     notes_relative = midData{n,2};
  15.     
  16.     % 在歌曲中寻找最小距离的一段
  17.     
  18.     % 2字符串的相似矩阵 M,相同表示0,不同表示1
  19.     % 例如:1 2 -2 4 -3 0 
  20.     L1 = length(notes_relative);
  21.     M = zeros(L1, L2);
  22.     
  23.     for i = 1:L1
  24.         for j=1:L2
  25.             M(i,j) = (notes_relative(i) ~= notes_steps(j));
  26.         end
  27.     end
  28.     
  29.     % 寻找最相似的片段起始位置,并计算错误字符数
  30.     sim = zeros(1,(L1 - L2 +1));
  31.     for i = L2: L1
  32.         sum = 0;
  33.         for j = 1: L2
  34.             sum = sum + M( j+i-L2, j);
  35.         end
  36.         sim(i - L2 + 1) = sum;
  37.     end
  38.     [cost,N] = min(sim);
  39.     
  40.     % 更新costs_top10
  41.     if sum(costs_top10(1,:)==NaN) ~= 0 % 包含NaN
  42.         tmp1 = find(costs_top10 == NaN);
  43.     [tmp1,tmp2] = max(costs_top10(1,:)); % 找到costs中最大的一个,更新这个
  44.     if cost < tmp1;
  45.         costs_top10(1, tmp2) = cost;
  46.         costs_top10(2, tmp2) = N;
  47.     end
  48. end
  49. for i = 1:10
  50.     names_top10(i) = midData{costs_top10(2,i),1};
  51. end
  52. costs_top10 = costs_top10(1,:);
  53. return;