Mercurial > hg > batch-feature-extraction-tool
view Source/MFCC.cpp @ 14:636c989477e7
XML changes for Public.
author | Geogaddi\David <d.m.ronan@qmul.ac.uk> |
---|---|
date | Wed, 04 May 2016 11:02:59 +0100 |
parents | 262e084a15a9 |
children |
line wrap: on
line source
/* ============================================================================== MFCC.cpp Created: 2 Sep 2014 3:30:50pm Author: david.ronan ============================================================================== */ #include "MFCC.h" #include <math.h> //----------------------------------------------------------------------------- ComputeMFCC void MFCC::ComputeMFCC(std::vector<float> magnitude, std::vector<float> &mfccs) { //Apply the Mel Filters to the spectrum magnitude: for (int i = 0; i < m_iTotalMFCCFilters; i++) { //Multiply spectrum with spectral mask MultiplyVector(magnitude, m_ppMFCCFilters[i], m_pfTempMelFilterResult, m_pMFCCFilterLength[i]); //Sum the values of each bins m_fMelFilteredFFT[i] = SumVector(m_pfTempMelFilterResult); //Log compression float filterOut = log10(m_fMelFilteredFFT[i] * 10.f + 1.f); m_fMelFilteredFFT[i] = filterOut; } for (int j = 0; j < m_iNumMFCCCoefs; j++) { //Cosine Transform to reduce dimensionality: MultiplySumVector(m_ppMFFC_DCT, m_fMelFilteredFFT, m_pMFCC, m_iNumMFCCCoefs, m_iTotalMFCCFilters); mfccs.push_back(m_pMFCC[j]); } } //----------------------------------------------------------------------------- initMFFCvariables void MFCC::initMFFCvariables(int NCoeffs, int Nfft, float fSampleRate) { m_iNumMFCCCoefs = NCoeffs; m_pMFCC = std::vector<float>(m_iNumMFCCCoefs, 0); //Add a value to take into account the 0 coefficient int iStartMfccCoeff = 1; //Mel FilterBank parameters float fLowestFreq = 133.3333f; int iNumLinearFilter = 13; float fLinearSpacing = 66.66666666f; int iNumLogFilters = 27; float fLogSpacing = 1.0711703f; float fFreqPerBin = fSampleRate / static_cast<float>(Nfft); m_iTotalMFCCFilters = iNumLinearFilter + iNumLogFilters; m_fMelFilteredFFT = std::vector<float>(m_iTotalMFCCFilters, 0); m_pMFCCFilterStart = std::vector<int>(m_iTotalMFCCFilters, 0); m_pMFCCFilterLength = std::vector<int>(m_iTotalMFCCFilters, 0); m_ppMFCCFilters = std::vector<std::vector<float>>(m_iTotalMFCCFilters); float FilterLimits[3]; int iFilterWidthMax = 0; for (int i = 0; i < m_iTotalMFCCFilters; i++) { for (int j = 0; j < 3; j++) { if (i + j < iNumLinearFilter) { FilterLimits[j] = (i + j) * fLinearSpacing + fLowestFreq; } else { float fLowestLogFreq = (iNumLinearFilter - 1) * fLinearSpacing + fLowestFreq; FilterLimits[j] = fLowestLogFreq * powf(fLogSpacing, static_cast<float>((i + j) - iNumLinearFilter + 1)); } } float fTriangleHeight = 2.f / (FilterLimits[2] - FilterLimits[0]); int iStartBin = static_cast<int>(ceil(FilterLimits[0] / fFreqPerBin)); int iStopBin = static_cast<int>(floor(FilterLimits[2] / fFreqPerBin)); int iFilterWidth = iStopBin - iStartBin + 1; m_pMFCCFilterStart[i] = iStartBin; m_pMFCCFilterLength[i] = iFilterWidth; m_ppMFCCFilters[i] = std::vector<float>(iFilterWidth, 0); if (iFilterWidth > iFilterWidthMax) { iFilterWidthMax = iFilterWidth; } for (int n = iStartBin; n<iStopBin + 1; n++) { float fFreq = n * fFreqPerBin; if (fFreq <= FilterLimits[1]) { float factor = (fFreq - FilterLimits[0]) / (FilterLimits[1] - FilterLimits[0]); float filterVal = fTriangleHeight * factor; m_ppMFCCFilters[i][n - iStartBin] = filterVal; } else { float factor = (FilterLimits[2] - fFreq) / (FilterLimits[2] - FilterLimits[1]); float filterVal = fTriangleHeight * factor; m_ppMFCCFilters[i][n - iStartBin] = filterVal; } } } m_pfTempMelFilterResult = std::vector<float>(iFilterWidthMax, 0); //Compute the DCT reduction matrix m_ppMFFC_DCT = std::vector<float>(NCoeffs * m_iTotalMFCCFilters, 0); float fScaleDCTMatrix = 1.f / sqrtf(m_iTotalMFCCFilters / 2.f); for (int n = iStartMfccCoeff; n < NCoeffs + iStartMfccCoeff; n++) { for (int m = 0; m < m_iTotalMFCCFilters; m++) { m_ppMFFC_DCT[(n - iStartMfccCoeff) * m_iTotalMFCCFilters + m] = fScaleDCTMatrix * cosf(n * (m + 0.5f) * 3.141592653589793f / m_iTotalMFCCFilters); } } } //----------------------------------------------------------------------------- MultiplyVector void MFCC::MultiplyVector(std::vector<float> v1, std::vector<float> v2, std::vector<float> &out, int iNumSamples) { for (int i = 0; i < iNumSamples; i++) { out[i] = v1[i] * v2[i]; } } //----------------------------------------------------------------------------- SumVector float MFCC::SumVector(std::vector<float> v) { float fSum = 0; for (size_t i = 0; i < v.size(); i++) { fSum += v[i]; } return fSum; } //----------------------------------------------------------------------------- MultiplySumVector void MFCC::MultiplySumVector(std::vector<float> v1, std::vector<float> v2, std::vector<float> &vout, int M, int P) { for (int m = 0; m < M; m++) { float fProdSum = 0.f; for (int p = 0; p < P; p++) { fProdSum += v1[m * P + p] * v2[p]; } vout[m] = fProdSum; } }