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

midi

开发平台:

Visual C++

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