2011-04-29 68 views
10

简而言之: 大家都很简单......我只是想知道从FFT中获取MFCC所涉及的步骤。如何从FFT上获取MFCC信号?

方式:

大家好。我正在制作一个鼓声应用程序,用于分类声音。它只是一个匹配的应用程序,它会返回您在鼓上弹奏的音符的名称。

它是一个简单的印度大鼓。在那里只有几个可以玩的笔记。

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

这是我了解到目前为止。它基于非线性梅尔尺度频率上对数功率谱的线性余弦变换。

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

所以如果你有大约1000个从fft算法返回的值 - 声音的频谱,那么最好你会得到12个元素(即系数)。这个12元素的矢量用于分类乐器,包括演奏鼓...

这正是我想要的。

请问有人能帮我解决这个问题吗?我的编程技能没问题。我目前正在为iPhone创建一个应用程序。与openframeworks。

任何帮助将不胜感激。干杯

+2

通常我很讨厌引用维基百科的任何技术,但是[本页](http://en.wikipedia.org/wiki/Mel-frequency_cepstral_coefficient)基本上给你获取系数的步骤? – Dan 2011-04-30 16:18:08

回答

21

首先,您必须以10至30ms的小帧分割信号,应用窗口功能(建议在声音应用中哼唱),然后计算信号的傅立叶变换。随着DFT,计算梅尔Frequecy倒谱系数,你必须遵循以下步骤:

  1. 获取功率谱:| DFT |^2
  2. 计算三角形银行滤波器转换赫兹规模为美度
  3. 获取数谱
  4. 应用离散cossine变换

甲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。我希望这对你有所帮助!

+0

嗨, 你的意思是“file.wav”是一个帧(10ms到30ms)?如果不是,则需要将信号分成小帧,然后将所做的操作应用到每帧。 对于每一帧,你应该得出13个系数。 – engineerchuan 2011-05-03 03:36:42

+0

......我也很困惑。我以为他在谈论窗户的大小。这就是我们抓住这些值然后计算它上面的FFT的地方。请确认 – Pavan 2011-05-03 07:06:30

+0

但是一旦我有系数会发生什么?它们对他们有什么影响?即时我假设我得到的声音系数一个,然后系数的声音2 ...然后什么 – Pavan 2011-05-03 23:34:31