首页 文章

谐波产品频谱的MATLAB代码

提问于
浏览
1

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

说我的fft信号是“FFT1”

然后代码大致会像

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

hps = FFT1.*hps1.*hps2;

这段代码是否正确?我想知道我是否正确地进行了采样,因为每个变量都有不同的长度乘以它们导致矩阵尺寸误差 . 我真的需要一些真正的快速帮助作为项目工作...真的很绝望.... Thanx提前....

1 回答

  • 2

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

相关问题