如何从信号的F​​FT中获得MFCC?

时间:2011-04-29 17:57:22

标签: logging signal-processing fft

简短而简单: 嗨,非常简单...我只想知道从FFT获得MFCC所涉及的步骤。

具体:

大家好。我正在进行鼓声应用,我想对声音进行分类。它只是一个匹配的应用程序,它返回你在鼓上播放的音符的名称。

它是一个简单的印度大声鼓。那里只有几个可以玩的音符。

我已经实现了fft算法并成功获得了一个频谱。我现在想更进一步,从fft返回mfcc。

这是我目前所理解的。 它基于非线性梅尔频率范围上对数功率谱的线性余弦变换。

它使用三角测量来滤除频率并获得所需的系数。 http://instruct1.cit.cornell.edu/courses/ece576/FinalProjects/f2008/pae26_jsc59/pae26_jsc59/images/melfilt.png

因此,如果您从fft算法返回大约1000个值 - 声音的频谱,那么理想的是您将获得大约12个元素(即系数)。这个12元素的矢量用于对乐器进行分类,包括演奏的鼓......

这正是我想要的。

有人可以帮我解决如何做这样的事情吗?我的编程技巧没问题。我目前正在为iphone创建一个应用程序。使用openframeworks。

非常感谢任何帮助。干杯

1 个答案:

答案 0 :(得分:23)

首先,您必须将信号分成10到30ms的小帧,应用窗口函数(建议在声音应用中使用嗡嗡声),并计算信号的傅里叶变换。使用DFT,要计算Mel Frequecy Cepstral Coefficients,您必须遵循以下步骤:

  1. 获得功率谱:| DFT | ^ 2
  2. 计算三角形滤波器滤波器以将hz比例转换为mel scale
  3. 获取日志频谱
  4. 应用离散的cossine变换
  5. 一个python代码示例:

    import numpy
    from scipy.fftpack import dct
    from scipy.io import wavfile
    
    sampleRate, signal = wavfile.read("file.wav")
    numCoefficients = 13 # choose the sive of mfcc array
    minHz = 0
    maxHz = 22.000  
    
    complexSpectrum = numpy.fft(signal)
    powerSpectrum = abs(complexSpectrum) ** 2
    filteredSpectrum = numpy.dot(powerSpectrum, melFilterBank())
    logSpectrum = numpy.log(filteredSpectrum)
    dctSpectrum = dct(logSpectrum, type=2)  # MFCC :)
    
    def melFilterBank(blockSize):
        numBands = int(numCoefficients)
        maxMel = int(freqToMel(maxHz))
        minMel = int(freqToMel(minHz))
    
        # Create a matrix for triangular filters, one row per filter
        filterMatrix = numpy.zeros((numBands, blockSize))
    
        melRange = numpy.array(xrange(numBands + 2))
    
        melCenterFilters = melRange * (maxMel - minMel) / (numBands + 1) + minMel
    
        # each array index represent the center of each triangular filter
        aux = numpy.log(1 + 1000.0 / 700.0) / 1000.0
        aux = (numpy.exp(melCenterFilters * aux) - 1) / 22050
        aux = 0.5 + 700 * blockSize * aux
        aux = numpy.floor(aux)  # Arredonda pra baixo
        centerIndex = numpy.array(aux, int)  # Get int values
    
        for i in xrange(numBands):
            start, centre, end = centerIndex[i:i + 3]
            k1 = numpy.float32(centre - start)
            k2 = numpy.float32(end - centre)
            up = (numpy.array(xrange(start, centre)) - start) / k1
            down = (end - numpy.array(xrange(centre, end))) / k2
    
            filterMatrix[i][start:centre] = up
            filterMatrix[i][centre:end] = down
    
        return filterMatrix.transpose()
    
    def freqToMel(freq):
        return 1127.01048 * math.log(1 + freq / 700.0)
    
    def melToFreq(mel):
        return 700 * (math.exp(mel / 1127.01048) - 1)
    

    此代码基于MFCC Vamp example。我希望这能帮到你!