/* * maxiMFCC.h * mfccs * * Created by Chris on 08/03/2011. * Copyright 2011 Goldsmiths Creative Computing. All rights reserved. * Based on Matthew Yee-King's MFCCMYK java class */ #pragma once #pragma pack(16) #include "maxiFFT.h" #include #include #include #ifdef __APPLE_CC__ #include #endif using namespace std; // implements this formula: // mel = 2595 log10(Hz/700 + 1) inline double hzToMel(double hz){ return 2595.0 * (log10(hz/700.0 + 1.0)); } // implements this formula // Hz = 700 (10^(mel/2595) - 1) inline double melToHz(double mel){ return 700.0 * (pow(10, mel/2595.0) - 1.0); } template class maxiMFCCAnalyser { public: T *melBands; maxiMFCCAnalyser():melFilters(NULL),dctMatrix(NULL), melBands(NULL){}; ~maxiMFCCAnalyser() { if (melFilters) { delete[] melFilters; delete[] melBands; delete[] dctMatrix; #ifdef __APPLE_CC__ delete doubleSpec; #endif } } void setup(unsigned int numBins, unsigned int numFilters, unsigned int numCoeffs, double minFreq, double maxFreq, unsigned int sampleRate) { this->numFilters = numFilters; this->numCoeffs = numCoeffs; this->minFreq = minFreq; this->maxFreq = maxFreq; this->sampleRate = sampleRate; this->numBins = numBins; melFilters = NULL; melBands = (T*) malloc(sizeof(T) * numFilters); #ifdef __APPLE_CC__ doubleSpec = (T*)malloc(sizeof(T) * numBins); #endif //create new matrix dctMatrix = (T*)malloc(sizeof(T) * numCoeffs * numFilters); calcMelFilterBank(sampleRate, numBins); createDCTCoeffs(); } void mfcc(float* powerSpectrum, T *mfccs) { melFilterAndLogSquare(powerSpectrum); dct(mfccs); } private: unsigned int numFilters, numCoeffs; double minFreq, maxFreq; unsigned int sampleRate; T *melFilters; unsigned int numBins; T *dctMatrix; #ifdef __APPLE_CC__ T *doubleSpec; #endif #ifdef __APPLE_CC__ void dct(T *mfccs); //define later #else void dct(T *mfccs) { for(int i=0; i < numCoeffs; i++) { mfccs[i] = 0.0; } for(int i=0; i < numCoeffs; i++ ) { for(int j=0; j < numFilters; j++) { int idx = i + (j * numCoeffs); mfccs[i] += (dctMatrix[idx] * melBands[j]); } } for(int i=0; i < numCoeffs; i++) { mfccs[i] /= numCoeffs; } } #endif void melFilterAndLogSquare(float* powerSpectrum); void melFilterAndLogSq_Part2(float *powerSpectrum); void calcMelFilterBank(double sampleRate, int numBins) { double mel, dMel, maxMel, minMel, nyquist, binFreq, start, end, thisF, nextF, prevF; int numValidBins; // ignore bins over nyquist numValidBins = numBins; nyquist = sampleRate/2; if (maxFreq > nyquist) { maxFreq = nyquist; } maxMel = hzToMel(maxFreq); minMel = hzToMel(minFreq); dMel = (maxMel - minMel) / (numFilters + 2 - 1); T *filtPos = (T*) malloc(sizeof(double) * (numFilters + 2)); // first generate an array of start and end freqs for each triangle mel = minMel; for (int i=0;i nextF || binFreq < prevF) { // outside this filter melFilters[idx] = 0; //cout << "MFCCMYK: filter at " < maxiMFCC; //typedef maxiMFCCAnalyser maxiFloatMFCC;