cannam@26: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@25: cannam@25: /* cannam@26: QM DSP Library cannam@25: cannam@26: Centre for Digital Music, Queen Mary, University of London. cannam@26: This file copyright 2005 Nicolas Chetry, copyright 2008 QMUL. cannam@26: All rights reserved. cannam@26: */ cannam@25: cannam@26: #include cannam@26: #include cannam@26: cannam@26: #include "MFCC.h" cannam@26: #include "dsp/transforms/FFT.h" cannam@26: #include "base/Window.h" cannam@26: cannam@26: MFCC::MFCC(MFCCConfig config) cannam@26: { cannam@26: int i,j; cannam@26: cannam@26: /* Calculate at startup */ cannam@26: double *freqs, *lower, *center, *upper, *triangleHeight, *fftFreqs; cannam@25: cannam@26: lowestFrequency = 66.6666666; cannam@26: linearFilters = 13; cannam@26: linearSpacing = 66.66666666; cannam@26: logFilters = 27; cannam@26: logSpacing = 1.0711703; cannam@25: cannam@26: /* FFT and analysis window sizes */ cannam@26: fftSize = config.fftsize; cannam@26: cannam@26: totalFilters = linearFilters + logFilters; cannam@25: cannam@26: samplingRate = config.FS; cannam@26: cannam@26: /* The number of cepstral componenents */ cannam@26: nceps = config.nceps; cannam@25: cannam@26: /* Set if user want C0 */ cannam@26: WANT_C0 = (config.want_c0 ? 1 : 0); cannam@25: cannam@26: /* Allocate space for feature vector */ cannam@26: if (WANT_C0 == 1) { cannam@26: ceps = (double*)calloc(nceps+1, sizeof(double)); cannam@26: } else { cannam@26: ceps = (double*)calloc(nceps, sizeof(double)); cannam@26: } cannam@26: cannam@26: /* Allocate space for local vectors */ cannam@26: mfccDCTMatrix = (double**)calloc(nceps+1, sizeof(double*)); cannam@26: for (i=0;i lower[i]) && (fftFreqs[j] <= center[i])) { cannam@26: cannam@26: mfccFilterWeights[i][j] = triangleHeight[i] * cannam@26: (fftFreqs[j]-lower[i]) / (center[i]-lower[i]); cannam@26: cannam@26: } cannam@26: else cannam@26: { cannam@26: mfccFilterWeights[i][j] = 0.0; cannam@26: } cannam@25: cannam@26: if ((fftFreqs[j]>center[i]) && (fftFreqs[j](HammingWindow, fftSize); cannam@25: cannam@26: /* Allocate memory for the FFT */ cannam@26: imagIn = (double*)calloc(fftSize,sizeof(double)); cannam@26: realOut = (double*)calloc(fftSize,sizeof(double)); cannam@26: imagOut = (double*)calloc(fftSize,sizeof(double)); cannam@25: cannam@26: free(freqs); cannam@26: free(lower); cannam@26: free(center); cannam@26: free(upper); cannam@26: free(triangleHeight); cannam@26: free(fftFreqs); cannam@25: } cannam@25: cannam@26: MFCC::~MFCC() cannam@26: { cannam@26: int i; cannam@26: cannam@26: /* Free the structure */ cannam@26: for (i=0;icut(inputData); cannam@26: cannam@26: /* Calculate the fft on the input frame */ cannam@26: FFT::process(fftSize, 0, inputData, imagIn, realOut, imagOut); cannam@25: cannam@26: for (i = 0; i < fftSize; ++i) { cannam@26: fftMag[i] = sqrt(realOut[i] * realOut[i] + cannam@26: imagOut[i] * imagOut[i]); cannam@25: } cannam@25: cannam@26: /* Multiply by mfccFilterWeights */ cannam@26: for (i=0;i0) cannam@26: earMag[i] = log10(tmp); cannam@26: else cannam@26: earMag[i] = 0.0; cannam@26: } cannam@26: cannam@26: /* cannam@26: * cannam@26: * Calculate now the cepstral coefficients cannam@26: * with or without the DC component cannam@26: * cannam@26: */ cannam@26: cannam@26: if (WANT_C0==1) { cannam@26: cannam@26: for (i=0;i