【问题标题】:How to perform a Cepstrum for pitch detection如何执行倒谱以进行音高检测
【发布时间】:2015-02-06 21:24:14
【问题描述】:

好的,这里有很多问题,谷歌上有很多阅读材料,但我不知何故无法弄清楚这一点。我想获得一段语音的基频。基本步骤应该是:

  • 对窗口信号进行 FFT
  • 将 FFT 从直角坐标转换为极坐标(这样就可以得到幅度)
  • 丢弃阶段信息
  • 取平方,然后是每个大小的 bin 的自然对数
  • 再做一次 FFT(或者有些消息来源说取反 fft?)

这是我在 AS3 中的实现方式:

var signal:Vector.<Number> = my1024PointSignal; // an audio signal 1024 samples long
var imx:Vector.<Number> = new Vector.<Number>(signal.length); // 1024 point vector to hold imaginary part of fft

hammingWindow(signal); // window it
zeroFill(imx); // fill imx with zeros

FFT(signal, imx); // convert signal into real and imaginary components of fft

toPolar(signal, imx); // convert fft to polar coordinates

// square each bin, and take the log of each bin, discard phase
for (var i:int = 0, l:int = signal.length; i < l; i++) {
    signal[i] = Math.log(Math.pow(signal[i], 2));
    imx[i] = 0;
}

FFT(signal, imx); // or maybe inverseFFT(signal, imx), i don't know

现在,当我这样做并以 FFT 结束时,当我绘制它时,bin 似乎是相反的顺序?我还看到二次谐波的峰值比基频的峰值更大。当我这样做并进行逆 FFT 时,我得到一个看起来反射在 N/2 附近的音频信号,并且峰值似乎再次反转。整个事情也相当嘈杂。我做错了什么?

【问题讨论】:

    标签: signal-processing fft pitch-tracking pitch-detection


    【解决方案1】:

    对于倒谱,我一直习惯于这个步骤:

    1. 在信号中应用汉明窗(1024 或 2048 点)
    2. 应用 FFT
    3. 获取震级
    4. 只使用前半部分的值
    5. 转换为对数刻度
    6. 应用IFFT
    7. 找到高峰

    倒谱方程:

     IFFT(log(abs(FFT(s))))
    

    也许您看到反映是因为您没有完成第四步 (4)

    以IFFT结尾和以FFT结尾的区别?

    不同之处在于比例表示,如果您最终使用 FFT,您只需提取真实信息,对于以下两个方程,您将获得相同的形状:

    IFFT(log(abs(FFT(s)))) == real(FFT(log(abs(FFT(s)))))
    

    从倒谱绘制示例:

    对于IFFT(log(abs(FFT(s))))

    对于real(FFT(log(abs(FFT(s)))))

    这是一个倒谱示例,来自 440hz 的 4096 点正弦,在 44100hz 采样

    【讨论】:

    • 你知道以IFFT结尾和以FFT结尾有什么区别吗?
    • 很抱歉,之前没有看到您的评论。看看编辑。
    猜你喜欢
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2021-02-06
    • 1970-01-01
    • 2021-01-21
    • 2010-11-30
    相关资源
    最近更新 更多