谐波乘积谱的 MATLAB 代码

Posted

技术标签:

【中文标题】谐波乘积谱的 MATLAB 代码【英文标题】:MATLAB code for Harmonic Product Spectrum 【发布时间】:2013-11-04 10:10:35 【问题描述】:

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

假设我的 fft 信号是“FFT1”

那么代码大概是这样的

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

hps = FFT1.*hps1.*hps2;

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

【问题讨论】:

不清楚你在问什么。你应该更具体 嗯,我想在执行 STFT 后对我的音频信号进行谐波乘积频谱分析,以便在存在谐波时获得正确的基频。我不熟悉 HPS,所以我需要一些帮助来编写实现它的 MATLAB 代码...... 【参考方案1】:

好的,你不能为每个下采样数据做"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 通常会产生一个错误,显示音高一个八度,我稍微更改一下代码,见上文 :-)

【讨论】:

非常感谢.. 不过我确实有疑问。我认为初始 FFT 数据被 2,3 等下采样。但是在您的代码中,您使用 hps3 = downsample(hps2,3); 对已经下采样的信号进行下采样。那里有点困惑...为什么使用“correctFactor” ? 看看这里link,你可以在这张图片中看到abs(FFT)下采样了/1,/2,/3,/N,是的,我刚刚在已经下采样的情况下测试了下采样,但你可以用 FFT 来做,correctFactor 只是为了增加正弦测试的结果 好的,谢谢..我会尝试两种方式,看看..顺便说一句,你到底是如何得出正确因子值的??有数学程序可以遵循吗?如果我不使用正确的因子,算法是否仍然有效?? 您好,修改一下上面的代码,我只通过观察来测量正确因子,是的,这项工作没有正确因子,怎么说呢,我只在正弦曲线中进行了测试,我相信您需要改进一些事情,我昨天只是按照一些论文做的:-) 谢谢。但可悲的是,即使您进行了更正,它似乎对我不起作用:(

以上是关于谐波乘积谱的 MATLAB 代码的主要内容,如果未能解决你的问题,请参考以下文章

Matlab计算波形的总谐波失真--THD(附完整代码)

Matlab计算波形的总谐波失真--THD(附完整代码)

Matlab计算波形的总谐波失真--THD(附完整代码)

湍流基于matlab kolmogorov结合次谐波补偿大气湍流相位屏含Matlab源码 2178期

matlab谐波生成方法

matlab谐波生成方法