d@0: /* d@9: ============================================================================== d@0: d@9: MFCC.cpp d@9: Created: 2 Sep 2014 3:30:50pm d@9: Author: david.ronan d@0: d@9: ============================================================================== d@0: */ d@0: d@0: #include "MFCC.h" d@0: #include d@0: d@0: //----------------------------------------------------------------------------- ComputeMFCC d@4: void MFCC::ComputeMFCC(std::vector magnitude, std::vector &mfccs) d@0: { d@9: //Apply the Mel Filters to the spectrum magnitude: d@9: for (int i = 0; i < m_iTotalMFCCFilters; i++) d@9: { d@9: //Multiply spectrum with spectral mask d@9: MultiplyVector(magnitude, m_ppMFCCFilters[i], m_pfTempMelFilterResult, m_pMFCCFilterLength[i]); d@0: d@9: //Sum the values of each bins d@9: m_fMelFilteredFFT[i] = SumVector(m_pfTempMelFilterResult); d@0: d@9: //Log compression d@9: float filterOut = log10(m_fMelFilteredFFT[i] * 10.f + 1.f); d@9: m_fMelFilteredFFT[i] = filterOut; d@9: } d@0: d@9: for (int j = 0; j < m_iNumMFCCCoefs; j++) d@9: { d@9: //Cosine Transform to reduce dimensionality: d@9: MultiplySumVector(m_ppMFFC_DCT, m_fMelFilteredFFT, m_pMFCC, m_iNumMFCCCoefs, m_iTotalMFCCFilters); d@9: mfccs.push_back(m_pMFCC[j]); d@9: } d@0: d@0: } d@0: d@0: d@0: //----------------------------------------------------------------------------- initMFFCvariables d@0: void MFCC::initMFFCvariables(int NCoeffs, int Nfft, float fSampleRate) d@0: { d@9: m_iNumMFCCCoefs = NCoeffs; d@0: d@9: m_pMFCC = std::vector(m_iNumMFCCCoefs, 0); d@0: d@0: d@9: //Add a value to take into account the 0 coefficient d@9: int iStartMfccCoeff = 1; d@0: d@9: //Mel FilterBank parameters d@9: float fLowestFreq = 133.3333f; d@9: int iNumLinearFilter = 13; d@9: float fLinearSpacing = 66.66666666f; d@9: int iNumLogFilters = 27; d@9: float fLogSpacing = 1.0711703f; d@9: float fFreqPerBin = fSampleRate / static_cast(Nfft); d@9: m_iTotalMFCCFilters = iNumLinearFilter + iNumLogFilters; d@0: d@9: m_fMelFilteredFFT = std::vector(m_iTotalMFCCFilters, 0); d@9: m_pMFCCFilterStart = std::vector(m_iTotalMFCCFilters, 0); d@9: m_pMFCCFilterLength = std::vector(m_iTotalMFCCFilters, 0); d@9: m_ppMFCCFilters = std::vector>(m_iTotalMFCCFilters); d@0: d@9: float FilterLimits[3]; d@9: int iFilterWidthMax = 0; d@9: for (int i = 0; i < m_iTotalMFCCFilters; i++) d@0: { d@9: for (int j = 0; j < 3; j++) d@0: { d@9: if (i + j < iNumLinearFilter) d@1: { d@9: FilterLimits[j] = (i + j) * fLinearSpacing + fLowestFreq; d@9: } d@9: else d@9: { d@9: float fLowestLogFreq = (iNumLinearFilter - 1) * fLinearSpacing + fLowestFreq; d@9: FilterLimits[j] = fLowestLogFreq * powf(fLogSpacing, static_cast((i + j) - iNumLinearFilter + 1)); d@0: } d@0: } d@0: d@9: float fTriangleHeight = 2.f / (FilterLimits[2] - FilterLimits[0]); d@9: d@9: int iStartBin = static_cast(ceil(FilterLimits[0] / fFreqPerBin)); d@9: int iStopBin = static_cast(floor(FilterLimits[2] / fFreqPerBin)); d@9: d@9: int iFilterWidth = iStopBin - iStartBin + 1; d@9: m_pMFCCFilterStart[i] = iStartBin; d@9: m_pMFCCFilterLength[i] = iFilterWidth; d@9: m_ppMFCCFilters[i] = std::vector(iFilterWidth, 0); d@9: d@9: if (iFilterWidth > iFilterWidthMax) d@9: { d@9: iFilterWidthMax = iFilterWidth; d@9: } d@9: d@9: for (int n = iStartBin; n(iFilterWidthMax, 0); d@9: d@9: //Compute the DCT reduction matrix d@9: m_ppMFFC_DCT = std::vector(NCoeffs * m_iTotalMFCCFilters, 0); d@9: d@9: float fScaleDCTMatrix = 1.f / sqrtf(m_iTotalMFCCFilters / 2.f); d@9: d@9: for (int n = iStartMfccCoeff; n < NCoeffs + iStartMfccCoeff; n++) d@9: { d@9: for (int m = 0; m < m_iTotalMFCCFilters; m++) d@9: { d@9: m_ppMFFC_DCT[(n - iStartMfccCoeff) * m_iTotalMFCCFilters + m] = fScaleDCTMatrix * cosf(n * (m + 0.5f) * 3.141592653589793f / m_iTotalMFCCFilters); d@9: } d@0: } d@0: } d@0: d@9: //----------------------------------------------------------------------------- MultiplyVector d@9: void MFCC::MultiplyVector(std::vector v1, std::vector v2, std::vector &out, int iNumSamples) d@0: { d@9: d@9: for (int i = 0; i < iNumSamples; i++) d@9: { d@9: out[i] = v1[i] * v2[i]; d@9: } d@0: } d@0: d@9: //----------------------------------------------------------------------------- SumVector d@9: float MFCC::SumVector(std::vector v) d@0: { d@9: float fSum = 0; d@0: d@9: for (size_t i = 0; i < v.size(); i++) d@9: { d@9: fSum += v[i]; d@9: } d@0: d@9: return fSum; d@0: } d@0: d@9: //----------------------------------------------------------------------------- MultiplySumVector d@9: void MFCC::MultiplySumVector(std::vector v1, std::vector v2, std::vector &vout, int M, int P) d@0: { d@9: for (int m = 0; m < M; m++) d@9: { d@9: float fProdSum = 0.f; d@0: d@9: for (int p = 0; p < P; p++) d@9: { d@9: fProdSum += v1[m * P + p] * v2[p]; d@9: } d@1: d@9: vout[m] = fProdSum; d@9: } d@4: }