Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лекции по МРРиИ, Геппенер В.В. / Симончик_Лекции / Лекция15 / Version2 / MFCCExtract / MFCCExtract
.cpp// 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];
*/
}