0

我一直试图在 MATLAB 中使用 Harmonic Product Spectrum 找到基本音符。我遇到了一个算法并尝试使用它。我用 C 大调音阶(钢琴)和音符 C4 D4 E4 F4 G4 A4 B4 C5 B4 A4 G4 F4 E4 D4 C4测试了它

除了最后一个 C4 音符外,我得到了所有音符的正确(几乎接近)频率值,因为那时我得到了错误

矩阵尺寸必须一致。

这是显示错误的行

f_ym = (1*seg_fft) .* (1.0*seg_fft2) .* (1*seg_fft3)  .* (1*seg_fft4);

我不太确定这里出了什么问题。我找到了音符的起始点并在每个起始点上执行了 FFT,并将其用于谐波乘积频谱。这是执行 HPS 的部分

h = 1;
for i = 2:No_of_peaks

song_seg = song(max_col(i-1):max_col(i)-1);
L = length(song_seg); 
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
seg_fft = fft(song_seg,NFFT);%/L;

%HPS
seg_fft = seg_fft(1 : size(seg_fft,1) / 2);
seg_fft = abs(seg_fft);

%HPS: downsampling
for i = 1:length(seg_fft)
    seg_fft2(i,1) = 1;
    seg_fft3(i,1) = 1;
    seg_fft4(i,1) = 1;
%    f_x5(i,1) = 1;
end

for i = 1:floor((length(seg_fft)-1)/2)
    seg_fft2(i,1) = (seg_fft(2*i,1) + seg_fft((2*i)+1,1))/2;
end

for i = 1:floor((length(seg_fft)-2)/3)
    seg_fft3(i,1) = (seg_fft(3*i,1) + seg_fft((3*i)+1,1) + seg_fft((3*i)+2,1))/3;    
end

for i = 1:floor((length(seg_fft)-3)/4)
    seg_fft4(i,1) = (seg_fft(4*i,1) + seg_fft((4*i)+1,1) + seg_fft((4*i)+2,1) + seg_fft((4*i)+3,1))/4;
end


%HPS, PartII: calculate product
f_ym = (1*seg_fft) .* (1.0*seg_fft2) .* (1*seg_fft3)  .* (1*seg_fft4);


%HPS, PartIII: find max
f_y1 = max(f_ym);

for c = 1 : size(f_ym)
    if(f_ym(c, 1) == f_y1)
        index = c;
    end
end

% Convert that to a frequency
f_y(h) = (index / NFFT) * FS


    h=h+1;
    f_y = abs(f_y)';

 end

好吧,我试图在存在谐波的情况下找到基频。谐波乘积频谱是一种实现方式,这就是上述代码中实现的方式。当我做乘法时, 的大小seg_fft似乎是 的一半seg_fft2, seg_fft3, seg_fft4。我不知道如何使尺寸具有相同的尺寸。这就是我需要帮助的地方。非常感谢您的快速帮助。提前谢谢:)

4

1 回答 1

0

如果没有更多解释,很难准确理解您要做什么。但是在尝试对多个矩阵进行逐元素乘法时会出错。此错误消息意味着并非所有矩阵都具有相同的大小,这是逐元素操作所必需的。要调试此类错误,最简单的方法通常是检查各种矩阵的大小。因此,在给出错误的行之前添加这些行:

disp(size(seg_fft))
disp(size(seg_fft2))
disp(size(1*seg_fft3))
disp(size(seg_fft4))

这可能应该向您表明其中一个的大小与您的预期不同。在此之后,尝试修复你的 for 循环,使它们都具有相同的大小。

于 2013-11-07T11:59:37.833 回答