mfcc

     在研究MFCC算法时,从网上下了一份代码,经过小改编译通过了,可程序一跑就蹦,费了好几天的功夫也没找到问题的原因。

化了一个月的时间边看资料,边整理代码,参照原有代码自己实现了一份。目前代码调通了,还没有能力验证结果的正确性。


     这里使用的FFT算法是从网上下载的。稍后也将其附上。欢迎有MFCC经验的朋友帮忙指正其中存在的问题。

      

#ifndef MFCC_H
#define MFCC_H
 
 
#include <stdio.h>
#include <math.h>
#include <QVector>
#include <QMap>
 
 
#define MOD_256  8
#define MOD_512  9
#define MOD_1024 10

 
 
class CMFCC
{
public:
    CMFCC(int Mod);
    int mfcc(double * data,int size);
 
 
protected:
    void preEmphasis();
    void procFrame();
    void procHammingWindows(double * buffer);
    void fft(double * buffer);
    int Melf(double * buffer);
    void DCT(double *lnpower,int len,double * dct,int dctnum);
private:
    double * m_data;
    int m_size;
    int m_frameSize;
    double m_factor;
    double m_hammingFactor;
    int m_mod;
    int m_resoultSize;
};


#include "MFCC.h"
#include <memory.h>
#include "FFT.h"
#include "Mel.h"
#include "PlotWidget.h"
#include <QDebug>
#include <math.h>
 
  
#define PI 3.141592653589793

 
  
CMFCC::CMFCC(int mod)
    :m_data(0),m_size(0),m_frameSize(pow(2,mod))
    ,m_factor(0.97),m_hammingFactor(0.46),m_mod(mod)
{
 
  
}
 
  
int CMFCC::mfcc(double * data,int size)
{
    m_data = data;
    m_size = size;
 
  
    this->preEmphasis();
    this->procFrame();
    return 0;
}
 
  
void CMFCC::preEmphasis()
{
    for(int i =1; i< m_size; i++)
    {
        m_data[i] = m_data[i] - m_factor * m_data[i-1];
    }
}
 
  
void CMFCC::procFrame()
{
    //plot("data",0,m_data,m_size,Qt::blue);
 
  
    int dis = m_frameSize - m_frameSize / 3;
 
  
    double * buffer = new double[m_frameSize];
 
  
    int i = 0;
    for(; i< m_size-m_frameSize; i+= dis)
    {
        double * s = m_data + i;
        //double * e = m_data + i + m_frameSize;
 
  
        memcpy(buffer,s,m_frameSize * sizeof(double));
        //plot("frame",0,buffer,m_frameSize,Qt::blue);
 
  
        this->procHammingWindows(buffer);
        //plot("ccc",0,buffer,m_frameSize,Qt::red);
 
  
        this->fft(buffer);
        //plot("fft",0,buffer,m_frameSize,Qt::red);
 
  
        this->Melf(buffer);
 
  
        //plot("fft",0,buffer,m_frameSize/2,Qt::red);
    }
 
  
    /*
    int n = i - m_size;
    if(n > 0)
    {
        memset(buffer,0,m_frameSize*sizeof(double));
        memcpy(buffer,m_data+m_size-n,m_frameSize*sizeof(double));
 
  
        //plot("frame",0,buffer,m_frameSize,Qt::blue);
 
  
        this->procHammingWindows(buffer);
        this->fft(buffer);
        this->Melf(buffer);
 
  
        //plot("fft",0,buffer,m_frameSize,Qt::red);
    }
    */
    delete[] buffer;
}
 
  
void CMFCC::procHammingWindows(double * buffer)
{
    int size = m_frameSize -1;
    for(int i=0; i<m_frameSize; i++)
    {
        double d = (2 * PI * i)/size;
        double w = (1-m_hammingFactor) - m_hammingFactor * cos(d);
        buffer[i] = buffer[i] * w;
    }
}
 
  
void CMFCC::fft(double * buffer)
{
    complex *tx = new complex[m_frameSize];
    for(int i = 0; i<m_frameSize; i++)
    {
        tx[i].real = buffer[i];
        tx[i].img = 0;
    }
 
  
    complex * dx = new complex[m_frameSize];
    complex * nex_t = new complex[m_frameSize];
    memset(dx,0,m_frameSize * sizeof(complex));
    memset(nex_t,0,m_frameSize * sizeof(complex));
 
  
    FFT(tx,dx,nex_t,m_frameSize,m_mod);
 
  
    for(int i=0; i<m_frameSize; i++)
    {
        buffer[i] = dx[i].real;
    }
 
  
    delete tx;
    delete dx;
    delete nex_t;
}
 
  
 
  
 
  
int CMFCC::Melf(double * buffer)
{
    CMel mel;
    int n = mel.mel(buffer,m_frameSize/2);
 
  
    //output("mel :",buffer,n);
 
  
    double dctNum = 10;
    double *dct = new double[dctNum];
    memset(dct,0,dctNum*sizeof(double));
 
  
    DCT(buffer,n,dct,dctNum);
 
  
    //output("dtc :",dct,dctNum);
    plot("dtc",0,dct,dctNum,Qt::red);
 
  
    delete[] dct;
 
  
    return dctNum;
}
 
  
void CMFCC::DCT(double *data,int len,double * dct,int dctnum)
{
    //double temp[100];
    //memset(temp,0,100*sizeof(double));
    //memcpy(temp,data,len*sizeof(double));
 
  
    double k = pow(2.0/(double)len,0.5);
    for(int i=0;i<dctnum;i++)
    {
        for(int j=0;j<len;j++)
        {
            double d = data[j];
            if(d > std::numeric_limits<double>::min())
            {
                double d1 = log(data[j]);
                double d2 = cos(i*(j-0.5)*3.141592653589793/len);
                double d3 = d1 * d2;
                double d5 = dct[i];
                d5 += d3;
                dct[i] += d3;
            }
            //dct[i] += log(data[j])*cos(i*(j-0.5)*3.141592653589793/len);
        }
 
  
        double md = dct[i];
        dct[i] *= k;
    }
 
  
    //double temp2[100];
    //memset(temp2,0,100*sizeof(double));
    //memcpy(temp2,dct,dctnum*sizeof(double));
 
  
    //int n = 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wolfseek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值