有人可以告诉我如何使用 MATLAB 实现谐波积频谱以在存在谐波的情况下找到音符的基频?我知道我应该多次对我的信号进行降采样(当然是在执行 fft 之后),然后将它们与原始信号相乘。
假设我的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 通常会生成一个错误,显示音高一个八度,我更改了一点代码,见上文:-)