如何生成MFCC算法的三角窗口并如何使用它们?

9

我正在使用Java实现MFCC算法。

这里有一个Matlab的示例代码:http://www.ee.columbia.edu/~dpwe/muscontent/practical/mfcc.m。但是,我在mel滤波器银行处理方面遇到了一些问题。如何生成三角形窗口以及如何使用它们?

PS1:这篇文章中有一部分描述了MFCC:http://arxiv.org/pdf/1003.4083

PS2:如果有一份关于MFCC算法步骤基础的文档,那就太好了。

PS3:我的主要问题与Java线性和对数滤波器的MFCC有关,一些实现同时使用线性和对数滤波器,而另一些则不使用。那些滤波器是什么,中心频率概念是什么。我遵循这段代码:MFCC Java,那和这段代码有什么区别:MFCC Matlab


如果你使用Matlab的话,VoiceBox工具箱有用于完成这个任务的Matlab代码。也许你可以进行代码移植。 - Phonon
2个回答

4
三角形窗口作为频带滤波器并不难实现。你需要在每个频带(定义为中心频率i-1和中心频率i+1之间的频率空间)内集成FFT数据。
你基本上要寻找像这样的东西,
for(int bandIdx = 0; bandIdx < numBands; bandIdx++) {
    int startFreqIdx  = centerFreqs[bandIdx-1];
    int centerFreqIdx = centerFreqs[bandIdx];
    int stopFreqIdx   = centerFreqs[bandIdx+1];

    for(int freq = startFreqIdx; i < centerFreqIdx; i++) {
        magnitudeScale = centerFreqIdx-startFreqIdx;
        bandData[bandIdx] += fftData[freq]*(i-startFreqIdx)/magnitudeScale;
    }

    for(int freq = centerFreqIdx; i <= stopFreqIdx; i++) {
        magnitudeScale = centerFreqIdx-stopFreqIdx;
        bandData[bandIdx] += fftData[freq]*(i-stopFreqIdx)/magnitudeScale;
    }
}

如果您不理解“中心频率”、“带宽”或“滤波器”的概念,请参考一本初级信号处理教材--在了解算法的作用之前,您不应该实现它。
至于确切的中心频率是什么,这取决于您。尝试并选择(或从出版物中找到)捕捉您想要从数据中隔离出来的信息的值。没有确定的值或甚至是值得规模,原因是此算法试图近似人耳,而人耳是一个非常复杂的听觉设备。某个比例尺可能更适用于语音,而另一个比例尺可能更适用于音乐等。选择合适的取决于您。

MFCC Java 说:mel[0] = freqToMel(lowerFilterFreq); mel[1] = freqToMel(samplingRate / 2); 这是什么意思?它是否意味着从 lowerFilterFreq 到 samplingRate / 2 运行滤波器?如果我想扫描到1000 Hz,我应该写1000而不是samplingRate / 2吗? - kamaci
@kamaci:不知道freqToMel的上下文或细节是无法确定的。我假设samplingRate指的是采样率。也就是说,如果您以44.1kHz的采样率对音频进行采样,则samplingRate/2为22.05kHz。如果您以1000 Hz进行采样,则samplingRate/2为500 Hz。如果您不清楚“采样率”的概念,那么您应该像我之前说的那样阅读信号书籍。 - Thomas Minor
1
采样率的一半不是最大频率吗? - kamaci
samplingRate/2 是 奈奎斯特频率。任何高于 samplingRate/2 的频率将被折叠到 0 和 samplingRate/2 之间。 - Thomas Minor
我知道这不是一个过滤器,但你能告诉我centerFreq()方法在做什么吗? - kamaci
显示剩余5条评论

3

第二个问题的答案:我找到了这篇教程,它真正帮助我计算MFCC。

至于三角形窗口和滤波器组,据我所知,它们重叠,不会延伸到负频率,并且从FFT频谱计算它们并将其应用回去的整个过程如下:

  1. 选择过滤器的最小和最大频率(例如,最小频率= 300Hz-最小语音频率,最大频率=您的采样率/2。也许这就是您应该选择1000Hz限制的地方)
  2. 从所选最小和最大频率计算mel值。公式在此处
  3. 在这两个mel值之间计算N个等距值。 (我看过使用不同N值的示例,甚至可以在此工作中找到不同值的效率比较,对于我的测试,我选择了26)
  4. 将这些值转换回Hz。(您可以在同一维基页面上找到公式)=> N + 2个滤波器值的数组
  5. 为每三个连续值计算一个滤波器组(滤波器三角形),可以像Thomas上面建议的那样(注意索引)或者像本帖子开头推荐的教程中一样进行)=>数组的数组,大小为NxM,假设您的FFT返回了2 * M个值,您只使用了M。
  6. 将整个功率谱(从FFT获得的M值)通过每个三角形滤波器以获取每个滤波器的“滤波器组能量”(对于每个滤波器组(N循环),将FFT后获得的每个幅度乘以相应滤波器组(M循环)中的每个值并添加所获得的M值)=> N大小的能量数组。

这些是您可以进一步应用对数,应用DCT并提取MFCC的滤波器组能量...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接