Скачиваний:
82
Добавлен:
01.05.2014
Размер:
4.84 Кб
Скачать
// MFCCExtract.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "stdio.h"


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

void FFT(TCPoint VecT[], TCPoint VecF[], UINT16 N)
{
	UINT16 i;
    TCPoint VecT0[MAX_FFT_LENGTH+1],VecT1[MAX_FFT_LENGTH+1];
    TCPoint VecF0[MAX_FFT_LENGTH+1],VecF1[MAX_FFT_LENGTH+1];
    TCPoint W,tmp;
	if ( N <= (UINT16)2)
	{
		VecF[0].Re = VecT[0].Re+VecT[1].Re;
        VecF[0].Im = VecT[0].Im+VecT[1].Im;
        VecF[1].Re = VecT[0].Re-VecT[1].Re;
        VecF[1].Im = VecT[0].Im-VecT[1].Im;
        return;
	}
    for (i=0;i<(UINT16)(N/2);i++)
	{
		VecT0[i] =VecT[2*i];
        VecT1[i] =VecT[2*i+1];
	}
    FFT(VecT0,VecF0,(UINT16)(N/2));
    FFT(VecT1,VecF1,(UINT16)(N/2));
    for (i=0;i<(UINT16)(N/2);i++)
	{
		W.Re = cos((DOUBLE)2*(DOUBLE)PI/(DOUBLE)N*(DOUBLE)i);
        W.Im =-sin((DOUBLE)2*(DOUBLE)PI/(DOUBLE)N*(DOUBLE)i);
        tmp.Re = VecF1[i].Re*W.Re-VecF1[i].Im*W.Im;
        tmp.Im = VecF1[i].Re*W.Im+VecF1[i].Im*W.Re;
        VecF[i].Re =VecF0[i].Re + tmp.Re;
        VecF[i].Im =VecF0[i].Im + tmp.Im;
        VecF[i+(UINT16)(N/2)].Re = VecF0[i].Re - tmp.Re;
        VecF[i+(UINT16)(N/2)].Im = VecF0[i].Im - tmp.Im;
	}

}


void CBlock::FFTransform(void)
{
    UINT16 f;
	DOUBLE alpha;
	alpha = (DOUBLE)0.95;
	TCPoint VecT[MAX_BLOCK_SIZE+1],VecF[MAX_BLOCK_SIZE+1];
    VecT[0].Re = (DOUBLE)Sample[0];
    VecT[0].Im = 0;

	for (UINT16 t=1; t<Size; t++)
	{
		VecT[t].Re = ((DOUBLE)Sample[t]-(DOUBLE)alpha*(DOUBLE)Sample[t-1]);
        VecT[t].Im = 0;
	}
	

	FFT(VecT,VecF,Size);
    

	AbsSpecter[0] = sqrt(VecF[0].Re*VecF[0].Re+VecF[0].Im*VecF[0].Im)/(DOUBLE)Size;

    for (f= 1; f<Size/2;f++)
		AbsSpecter[f] = (DOUBLE)2.0*sqrt(VecF[f].Re*VecF[f].Re+VecF[f].Im*VecF[f].Im)/(DOUBLE)Size;
}

void CBlock::GetCeipCoeffs(TFiltersSet* FiltersSet)
{
	DOUBLE S[MFCC_SIZE+1];   //средняя спектральная мощность фильтра

	//вычисление средней спектральной мощности фильтров
    for (UINT16 k=1;k<=MFCC_SIZE;k++)
    {
		S[k] = 0;
        for (UINT16 i=FiltersSet->M[k]+1; i<= FiltersSet->M[k]+FiltersSet->N[k]-1; i++)
			S[k] += (FiltersSet->w[k][i])*AbsSpecter[i];

		S[k] = S[k]/(DOUBLE)FiltersSet->N[k];
	}

    //
    for (UINT16 i=0;i<=MFCC_SIZE; i++)
	{
		CeipCoeff[i] = 0;
        for (k=1; k<=MFCC_SIZE; k++)
			CeipCoeff[i] += log10(S[k])*cos(PI*(DOUBLE)i/(DOUBLE)MFCC_SIZE*((DOUBLE)k-(DOUBLE)0.5));
	}

}

void CMainVector::Init(INT16* Buffer,UINT16 BufferLen, UINT16 BlockSize, UINT16 BlockStep)
{
	BlocksSize = BlockSize;
	Len = (BufferLen - BlockSize)/BlockStep+1;
    for (UINT16 i=0; i<Len;i++)
	{
		Block[i].Size = BlockSize;
		for (UINT16 j=0;j<BlockSize;j++)
			Block[i].Sample[j] = (DOUBLE)Buffer[i*BlockStep+j]*((DOUBLE)0.54+(DOUBLE)0.46*cos((DOUBLE)2.0*(DOUBLE)PI*(DOUBLE)((DOUBLE)j-(DOUBLE)BlockSize/(DOUBLE)2.0)/(DOUBLE)BlockSize));
	}
}

void CMainVector::FFTransform(void)
{
	for (UINT16 i=0;i< Len;i++)
		Block[i].FFTransform();
}

void CMainVector::GetCeipCoeffs(void)
{
	DOUBLE	MaxMel,StepMel,Mel,F;
    UINT16	NoGarm;
	
	//вычисляем начальные частоты фильтров
    MaxMel = 1125.0*log10((DOUBLE)0.0016*((DOUBLE)11025/2.0)+(DOUBLE)1);
    StepMel = MaxMel/(DOUBLE)(MFCC_SIZE+1);
    for (UINT16 i=1;i<= MFCC_SIZE+2; i++)
	{
		Mel = StepMel*(i-1);
        F = (pow(10,Mel/1125)-1)/0.0016;
        NoGarm = (UINT16)((F/(DOUBLE)11025*(DOUBLE)BlocksSize)+(DOUBLE)0.5);
        if (i<=MFCC_SIZE)
			FiltersSet.M[i] = NoGarm;
        if ((i-2)>0)
			FiltersSet.N[i-2] = NoGarm - FiltersSet.M[i-2];
	}
    
	//вычисление весового треугольного окна
    for (UINT16 k=1; k<=MFCC_SIZE; k++)
		for (i=FiltersSet.M[k]; i<=FiltersSet.M[k]+FiltersSet.N[k];i++)
			FiltersSet.w[k][i] =1.0-2.0*fabs(((DOUBLE)FiltersSet.M[k]+(DOUBLE)FiltersSet.N[k]/(DOUBLE)2)-i)/(DOUBLE)FiltersSet.N[k];

    for (i=0;i<Len;i++)
		Block[i].GetCeipCoeffs( &FiltersSet);
				
}

CMainVector MainVector;

EXTERN_DEFINE void GetMFCC(INT16* Buffer,UINT16 BufferLen, UINT16 BlockSize, UINT16 BlockStep, TMFCC* MFCC)
{
	
	MainVector.Init(Buffer, BufferLen, BlockSize, BlockStep);
	MainVector.FFTransform();
	MainVector.GetCeipCoeffs();
	
	MFCC->Len = MainVector.Len;
	for (UINT16 i=0; i<MFCC->Len; i++)
		for (UINT16 k=0; k<=MFCC_SIZE; k++)
			MFCC->Coefficient[i][k] = MainVector.Block[i].CeipCoeff[k];

/*	//Other information
	for (i=0; i<MFCC->Len; i++)
		for (UINT16 k=0; k<BlockSize; k++)
			MFCC->Sample[i][k] = MainVector.Block[i].Sample[k];

	for (i=0; i<MFCC->Len; i++)
		for (UINT16 k=0; k<BlockSize; k++)
			MFCC->AbsSpecter[i][k] = MainVector.Block[i].AbsSpecter[k];
*/	
}

Соседние файлы в папке MFCCExtract
  • #
    01.05.20144.84 Кб82MFCCExtract.cpp
  • #
    01.05.20144.4 Кб82MFCCExtract.dsp
  • #
    01.05.2014547 б82MFCCExtract.dsw
  • #
    01.05.201458.37 Кб82MFCCExtract.ncb
  • #
    01.05.201448.64 Кб82MFCCExtract.opt
  • #
    01.05.20141.78 Кб82MFCCExtract.plg