【问题标题】:HOW to get MFCC from an FFT on a signal?如何从信号上的 FFT 获得 MFCC?
【发布时间】:2011-08-15 16:30:05
【问题描述】:

简短: 大家好,非常简单...我只想知道从 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 创建一个应用程序。使用开放框架。

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

【问题讨论】:

  • 一般我不愿意引用维基百科的任何技术,但this page 基本上没有给你获取系数的步骤吗?

标签: logging signal-processing fft


【解决方案1】:

首先,您必须将信号拆分为 10 到 30 毫秒的小帧,应用窗口函数(建议在声音应用中使用嗡嗡声),并计算信号的傅立叶变换。使用 DFT,要计算梅尔频率倒谱系数,您必须遵循以下步骤:

  1. 获取功率谱:|DFT|^2
  2. 计算三角组滤波器以将 hz 标度转换为 mel 标度
  3. 获取对数谱
  4. 应用离散余弦变换

一个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。希望对您有所帮助!

【讨论】:

  • 嗨,你的意思是“file.wav”是一个帧(10ms 到 30ms)吗?如果没有,您需要将信号拆分为小帧,然后将您所做的操作应用于每个帧。对于每一帧,你应该得到 13 个系数。
  • ...我也对此感到困惑。我以为他在谈论窗户的大小。这是我们获取值然后计算 FFT 的地方。请确认
  • 但是一旦我有了系数会发生什么?它对他们有什么作用?我假设我得到了声音 1 的系数,然后得到了声音 2 的系数......然后是什么
  • 对不起!我从我的研究代码中提取它,然后我忘了做清楚。将“file.wav”视为 10ms 到 30ms 的声音帧!我认为只有系数是不够的。您需要通过 MFCC 进行算法对其进行分类。我在这里使用反向传播神经网络对打击乐进行分类。 william brandt's timbreID 是一个使用 MFCC 对鼓声和其他刺耳声音进行分类的有趣项目
  • melToFreq() 函数有一个错误,-1 应该在内括号之外
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
  • 2023-03-24
  • 2017-03-19
  • 1970-01-01
  • 2016-11-24
  • 2013-07-03
  • 2011-06-22
相关资源
最近更新 更多