annotate Source/MFCC.cpp @ 15:585caf503ef5 tip

Tidy up for ROLI
author Geogaddi\David <d.m.ronan@qmul.ac.uk>
date Tue, 17 May 2016 18:50:19 +0100
parents 262e084a15a9
children
rev   line source
d@0 1 /*
d@9 2 ==============================================================================
d@0 3
d@9 4 MFCC.cpp
d@9 5 Created: 2 Sep 2014 3:30:50pm
d@9 6 Author: david.ronan
d@0 7
d@9 8 ==============================================================================
d@0 9 */
d@0 10
d@0 11 #include "MFCC.h"
d@0 12 #include <math.h>
d@0 13
d@0 14 //----------------------------------------------------------------------------- ComputeMFCC
d@4 15 void MFCC::ComputeMFCC(std::vector<float> magnitude, std::vector<float> &mfccs)
d@0 16 {
d@9 17 //Apply the Mel Filters to the spectrum magnitude:
d@9 18 for (int i = 0; i < m_iTotalMFCCFilters; i++)
d@9 19 {
d@9 20 //Multiply spectrum with spectral mask
d@9 21 MultiplyVector(magnitude, m_ppMFCCFilters[i], m_pfTempMelFilterResult, m_pMFCCFilterLength[i]);
d@0 22
d@9 23 //Sum the values of each bins
d@9 24 m_fMelFilteredFFT[i] = SumVector(m_pfTempMelFilterResult);
d@0 25
d@9 26 //Log compression
d@9 27 float filterOut = log10(m_fMelFilteredFFT[i] * 10.f + 1.f);
d@9 28 m_fMelFilteredFFT[i] = filterOut;
d@9 29 }
d@0 30
d@9 31 for (int j = 0; j < m_iNumMFCCCoefs; j++)
d@9 32 {
d@9 33 //Cosine Transform to reduce dimensionality:
d@9 34 MultiplySumVector(m_ppMFFC_DCT, m_fMelFilteredFFT, m_pMFCC, m_iNumMFCCCoefs, m_iTotalMFCCFilters);
d@9 35 mfccs.push_back(m_pMFCC[j]);
d@9 36 }
d@0 37
d@0 38 }
d@0 39
d@0 40
d@0 41 //----------------------------------------------------------------------------- initMFFCvariables
d@0 42 void MFCC::initMFFCvariables(int NCoeffs, int Nfft, float fSampleRate)
d@0 43 {
d@9 44 m_iNumMFCCCoefs = NCoeffs;
d@0 45
d@9 46 m_pMFCC = std::vector<float>(m_iNumMFCCCoefs, 0);
d@0 47
d@0 48
d@9 49 //Add a value to take into account the 0 coefficient
d@9 50 int iStartMfccCoeff = 1;
d@0 51
d@9 52 //Mel FilterBank parameters
d@9 53 float fLowestFreq = 133.3333f;
d@9 54 int iNumLinearFilter = 13;
d@9 55 float fLinearSpacing = 66.66666666f;
d@9 56 int iNumLogFilters = 27;
d@9 57 float fLogSpacing = 1.0711703f;
d@9 58 float fFreqPerBin = fSampleRate / static_cast<float>(Nfft);
d@9 59 m_iTotalMFCCFilters = iNumLinearFilter + iNumLogFilters;
d@0 60
d@9 61 m_fMelFilteredFFT = std::vector<float>(m_iTotalMFCCFilters, 0);
d@9 62 m_pMFCCFilterStart = std::vector<int>(m_iTotalMFCCFilters, 0);
d@9 63 m_pMFCCFilterLength = std::vector<int>(m_iTotalMFCCFilters, 0);
d@9 64 m_ppMFCCFilters = std::vector<std::vector<float>>(m_iTotalMFCCFilters);
d@0 65
d@9 66 float FilterLimits[3];
d@9 67 int iFilterWidthMax = 0;
d@9 68 for (int i = 0; i < m_iTotalMFCCFilters; i++)
d@0 69 {
d@9 70 for (int j = 0; j < 3; j++)
d@0 71 {
d@9 72 if (i + j < iNumLinearFilter)
d@1 73 {
d@9 74 FilterLimits[j] = (i + j) * fLinearSpacing + fLowestFreq;
d@9 75 }
d@9 76 else
d@9 77 {
d@9 78 float fLowestLogFreq = (iNumLinearFilter - 1) * fLinearSpacing + fLowestFreq;
d@9 79 FilterLimits[j] = fLowestLogFreq * powf(fLogSpacing, static_cast<float>((i + j) - iNumLinearFilter + 1));
d@0 80 }
d@0 81 }
d@0 82
d@9 83 float fTriangleHeight = 2.f / (FilterLimits[2] - FilterLimits[0]);
d@9 84
d@9 85 int iStartBin = static_cast<int>(ceil(FilterLimits[0] / fFreqPerBin));
d@9 86 int iStopBin = static_cast<int>(floor(FilterLimits[2] / fFreqPerBin));
d@9 87
d@9 88 int iFilterWidth = iStopBin - iStartBin + 1;
d@9 89 m_pMFCCFilterStart[i] = iStartBin;
d@9 90 m_pMFCCFilterLength[i] = iFilterWidth;
d@9 91 m_ppMFCCFilters[i] = std::vector<float>(iFilterWidth, 0);
d@9 92
d@9 93 if (iFilterWidth > iFilterWidthMax)
d@9 94 {
d@9 95 iFilterWidthMax = iFilterWidth;
d@9 96 }
d@9 97
d@9 98 for (int n = iStartBin; n<iStopBin + 1; n++)
d@9 99 {
d@9 100 float fFreq = n * fFreqPerBin;
d@9 101 if (fFreq <= FilterLimits[1])
d@9 102 {
d@9 103 float factor = (fFreq - FilterLimits[0]) / (FilterLimits[1] - FilterLimits[0]);
d@9 104 float filterVal = fTriangleHeight * factor;
d@9 105 m_ppMFCCFilters[i][n - iStartBin] = filterVal;
d@9 106 }
d@9 107 else
d@9 108 {
d@9 109 float factor = (FilterLimits[2] - fFreq) / (FilterLimits[2] - FilterLimits[1]);
d@9 110 float filterVal = fTriangleHeight * factor;
d@9 111 m_ppMFCCFilters[i][n - iStartBin] = filterVal;
d@9 112 }
d@9 113 }
d@9 114 }
d@9 115
d@9 116 m_pfTempMelFilterResult = std::vector<float>(iFilterWidthMax, 0);
d@9 117
d@9 118 //Compute the DCT reduction matrix
d@9 119 m_ppMFFC_DCT = std::vector<float>(NCoeffs * m_iTotalMFCCFilters, 0);
d@9 120
d@9 121 float fScaleDCTMatrix = 1.f / sqrtf(m_iTotalMFCCFilters / 2.f);
d@9 122
d@9 123 for (int n = iStartMfccCoeff; n < NCoeffs + iStartMfccCoeff; n++)
d@9 124 {
d@9 125 for (int m = 0; m < m_iTotalMFCCFilters; m++)
d@9 126 {
d@9 127 m_ppMFFC_DCT[(n - iStartMfccCoeff) * m_iTotalMFCCFilters + m] = fScaleDCTMatrix * cosf(n * (m + 0.5f) * 3.141592653589793f / m_iTotalMFCCFilters);
d@9 128 }
d@0 129 }
d@0 130 }
d@0 131
d@9 132 //----------------------------------------------------------------------------- MultiplyVector
d@9 133 void MFCC::MultiplyVector(std::vector<float> v1, std::vector<float> v2, std::vector<float> &out, int iNumSamples)
d@0 134 {
d@9 135
d@9 136 for (int i = 0; i < iNumSamples; i++)
d@9 137 {
d@9 138 out[i] = v1[i] * v2[i];
d@9 139 }
d@0 140 }
d@0 141
d@9 142 //----------------------------------------------------------------------------- SumVector
d@9 143 float MFCC::SumVector(std::vector<float> v)
d@0 144 {
d@9 145 float fSum = 0;
d@0 146
d@9 147 for (size_t i = 0; i < v.size(); i++)
d@9 148 {
d@9 149 fSum += v[i];
d@9 150 }
d@0 151
d@9 152 return fSum;
d@0 153 }
d@0 154
d@9 155 //----------------------------------------------------------------------------- MultiplySumVector
d@9 156 void MFCC::MultiplySumVector(std::vector<float> v1, std::vector<float> v2, std::vector<float> &vout, int M, int P)
d@0 157 {
d@9 158 for (int m = 0; m < M; m++)
d@9 159 {
d@9 160 float fProdSum = 0.f;
d@0 161
d@9 162 for (int p = 0; p < P; p++)
d@9 163 {
d@9 164 fProdSum += v1[m * P + p] * v2[p];
d@9 165 }
d@1 166
d@9 167 vout[m] = fProdSum;
d@9 168 }
d@4 169 }