有人可以告诉我如何在存在谐波的情况下使用MATLAB实现谐波乘积谱以找到音符的基本频率吗?我知道我应该对信号进行多次下采样(当然是在执行fft之后),然后将其与原始信号相乘。

假设我的信号是“FFT1”

然后代码大概会像

hps1 = downsample(FFT1,2);
hps2 = downsample(FFT1,3);

hps = FFT1.*hps1.*hps2;

此代码正确吗???我想知道是否正确地进行了下采样,并且由于每个变量的长度不同,所以将它们相乘会导致矩阵尺寸错误。.我真的需要一些真正的快速帮助,因为它对于项目工作非常不切实际。
提前感谢...

最佳答案

好的,您无法为每个降采样的数据执行"hps = FFT1.*hps1.*hps2;",您有不同的大小吗?

我为您提供了一个示例,说明如何使用5次谐波抽取(下采样)制作非常简单的谐波产品频谱(HPS),我仅在正弦信号中进行测试,在测试中得到的基频非常接近。

这段代码仅显示了如何计算算法的主要步骤,很有可能您需要对其进行改进!

资源:

%[x,fs] = wavread('ederwander_IN_250Hz.wav');

CorrectFactor = 0.986;
threshold = 0.2;

%F0 start test
f  = 250;
fs = 44100;

signal= 0.9*sin(2*pi*f/fs*(0:9999));
x=signal';

framed = x(1:4096);

windowed = framed .* hann(length(framed));

FFT = fft(windowed, 4096);

FFT = FFT(1 : size(FFT,1) / 2);

FFT = abs(FFT);

hps1 = downsample(FFT,1);
hps2 = downsample(FFT,2);
hps3 = downsample(FFT,3);
hps4 = downsample(FFT,4);
hps5 = downsample(FFT,5);

y = [];

for i=1:length(hps5)

      Product =   hps1(i)  * hps2(i) * hps3(i) * hps4(i) * hps5(i);
      y(i) = [Product];
end

[m,n]=findpeaks(y, 'SORTSTR', 'descend');

Maximum = n(1);

 %try fix octave error
if (y(n(1)) * 0.5) > (y(n(2))) %& ( ( m(2) / m(1) ) > threshold )

    Maximum  = n(length(n));

end

F0 =  ( (Maximum / 4096) * fs ) * CorrectFactor

plot(y)

HPS通常会产生一个错误,将音调显示一个 Octave ,我改变一点代码,请参见上面的:-)

10-08 12:33