Mercurial > hg > batch-feature-extraction-tool
changeset 9:262e084a15a9
Vectorised everything and made use of unique_ptr so there should be no more memory leaks. Hurrah for RAII
author | Geogaddi\David <d.m.ronan@qmul.ac.uk> |
---|---|
date | Wed, 12 Aug 2015 22:25:06 +0100 |
parents | fdc592312a96 |
children | 73852457b624 |
files | Source/AudioReader.cpp Source/AudioSourceFeatureExtractor.cpp Source/AudioSourceFeatureExtractor.h Source/FFT.cpp Source/FFT.h Source/FeatureData.cpp Source/MFCC.cpp Source/MFCC.h Source/ParseCSV.cpp Source/WriteCSV.cpp |
diffstat | 10 files changed, 182 insertions(+), 281 deletions(-) [+] |
line wrap: on
line diff
--- a/Source/AudioReader.cpp Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/AudioReader.cpp Wed Aug 12 22:25:06 2015 +0100 @@ -40,7 +40,6 @@ AudioFormatManager m_formatManager; m_formatManager.registerBasicFormats(); - //AudioSourceFeatureExtractor audioSourceFeatureExtractor = AudioSourceFeatureExtractor(); m_AudioSourceFeatureExtractor.Initialise(SAMPLERATE); for(size_t i=0; i<audioFileNames.size(); i++) @@ -49,11 +48,11 @@ std::string outputStr = "Extracting features for " + audioFileNames[i] + "\n" + std::to_string(percentcomplete) + "% complete..."; cout << outputStr; - + //Create file from our audio data File audioFile(audioFileNames[i].c_str()); - AudioFormatReader* audioFileReader = m_formatManager.createReaderFor(audioFile); + unique_ptr<AudioFormatReader> audioFileReader(m_formatManager.createReaderFor(audioFile)); if(audioFileReader != nullptr) { @@ -75,19 +74,15 @@ } //Length of the full track in stereo; - int* destSamples[2] = {0}; - int* L = new int[static_cast<size_t>(iLengthInSamples)]; - memset(L, 0, static_cast<size_t>(iLengthInSamples)*sizeof(float)); - destSamples[0]=L; - destSamples[1]=L; + int* destSamples[2] = { nullptr }; + unique_ptr<int> L(new int[iLengthInSamples]); + memset(L.get(), 0, iLengthInSamples); + destSamples[0] = L.get(); + destSamples[1] = L.get(); + //30 sec clips to check energy levels - float* destSamplesFloat = new float[static_cast<size_t>(numOfSamplesToCollect)]; - memset(destSamplesFloat, 0, static_cast<size_t>(numOfSamplesToCollect)*sizeof(float)); - - ////30 sec clips to check energy levels - //float* destSamplesFloatLoudest = new float[(size_t)numOfSamplesToCollect]; - //memset(destSamplesFloatLoudest, 0, (size_t)numOfSamplesToCollect*sizeof(float)); + std::vector<float> destSamplesFloat = std::vector<float>(static_cast<size_t>(numOfSamplesToCollect, 0)); int timesToLoop = 0; @@ -103,8 +98,8 @@ std::vector<float> thirtySecEnergy = std::vector<float>(); //float loudestEnergy = 0.0; - - audioFileReader->readSamples(destSamples, iNumOfChannels, 0, 0, iLengthInSamples); + bool dave; + dave = audioFileReader->readSamples(destSamples, iNumOfChannels, 0, 0, iLengthInSamples); for(int j=0; j < timesToLoop;j++) { @@ -115,11 +110,11 @@ //Sum to mono if needed and workout the energy for each 30 sec. frame if(iNumOfChannels > 1) { - destSamplesFloat[n] = (static_cast<float>((destSamples[0][int(j * ENERGYSEARCHTIME * fSampleRate) + n] + destSamples[1][int( j * ENERGYSEARCHTIME * fSampleRate) + n]) / 2) / (0x7fffffff)); + destSamplesFloat.push_back(static_cast<float>((destSamples[0][int(j * ENERGYSEARCHTIME * fSampleRate) + n] + destSamples[1][int( j * ENERGYSEARCHTIME * fSampleRate) + n]) / 2) / (0x7fffffff)); } else { - destSamplesFloat[n] = (static_cast<float>(destSamples[0][int(j * ENERGYSEARCHTIME * fSampleRate) + n]) / (0x7fffffff)); + destSamplesFloat.push_back(static_cast<float>(destSamples[0][int(j * ENERGYSEARCHTIME * fSampleRate) + n]) / (0x7fffffff)); } fSum+=(destSamplesFloat[n] * destSamplesFloat[n]); @@ -141,29 +136,30 @@ int maxIdx = std::distance(thirtySecEnergy.begin(), max_element(thirtySecEnergy.begin(), thirtySecEnergy.end())); int* thirtySecSamples[2] = {0}; - int* L30 = new int[static_cast<size_t>(numOfSamplesToCollect)]; - memset(L30, 0, static_cast<size_t>(numOfSamplesToCollect)*sizeof(float)); - thirtySecSamples[0]=L30; //Left channel - thirtySecSamples[1]=L30; //Left right + unique_ptr<int> L30(new int[iLengthInSamples]{ 0 }); + memset(L30.get(), 0, iLengthInSamples); + thirtySecSamples[0]=L30.get(); //Left channel + thirtySecSamples[1]=L30.get(); //Left right //Read the 30 secs. in audioFileReader->readSamples(thirtySecSamples, iNumOfChannels, 0, int(maxIdx * ENERGYSEARCHTIME * fSampleRate), numOfSamplesToCollect); - memset(destSamplesFloat, 0, static_cast<size_t>(numOfSamplesToCollect)*sizeof(float)); + + destSamplesFloat = std::vector<float>(static_cast<size_t>(numOfSamplesToCollect, 0)); for(int n=0; n<numOfSamplesToCollect; n++) { //Sum to mono if needed if(iNumOfChannels > 1) { - destSamplesFloat[n] = (static_cast<float>((thirtySecSamples[0][n] + thirtySecSamples[1][n]) / 2) / (0x7fffffff)); + destSamplesFloat.push_back(static_cast<float>((thirtySecSamples[0][n] + thirtySecSamples[1][n]) / 2) / (0x7fffffff)); } else { - destSamplesFloat[n] = (static_cast<float>(thirtySecSamples[0][n]) / (0x7fffffff)); + destSamplesFloat.push_back(static_cast<float>(thirtySecSamples[0][n]) / (0x7fffffff)); } } - std::vector<ObservationData> newObs = m_AudioSourceFeatureExtractor.Process(destSamplesFloat, numOfSamplesToCollect); + std::vector<ObservationData> newObs = m_AudioSourceFeatureExtractor.Process(destSamplesFloat); FeatureData newFeature = FeatureData(newObs, labels[i], audioFileNames[i], fSampleRate, FFTSIZE, static_cast<float>(numOfSamplesToCollect), poolTimeSecs); @@ -171,29 +167,7 @@ //Update the screen information; - cout << string(outputStr.length(),'\b'); - - //Cleanup - if(L != nullptr) - { - delete[] L; - L = nullptr; - } - - if (L30 != nullptr) - { - delete[] L30; - L30 = nullptr; - } - - if(destSamplesFloat != nullptr) - { - delete[] destSamplesFloat; - destSamplesFloat = nullptr; - } - - delete[] audioFileReader; - audioFileReader = nullptr; + cout << string(outputStr.length(),'\b'); } else
--- a/Source/AudioSourceFeatureExtractor.cpp Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/AudioSourceFeatureExtractor.cpp Wed Aug 12 22:25:06 2015 +0100 @@ -52,7 +52,7 @@ } //============================================================================== process -std::vector<ObservationData> AudioSourceFeatureExtractor::Process(const float* data, size_t numSamples) +std::vector<ObservationData> AudioSourceFeatureExtractor::Process(const std::vector<float> data) { std::vector<ObservationData> observations = std::vector<ObservationData>(); @@ -61,11 +61,11 @@ m_fPreviousMagnitudeSpectrum = std::vector<float>(MAGNITUDESIZE, 0); m_iWriteIdx = 0; - float perdiodicity = EstimatePerdiodicity(const_cast<float*>(data), numSamples); + float perdiodicity = EstimatePerdiodicity(data); - float entropyofenergy = EntropyOfEnergy(const_cast<float*>(data), numSamples); + float entropyofenergy = EntropyOfEnergy(data); - for (size_t n = 0; n < numSamples; n++) + for (size_t n = 0; n < data.size(); n++) { m_fInputBuffer[m_iWriteIdx] = data[n]; m_iWriteIdx++; @@ -166,7 +166,6 @@ void AudioSourceFeatureExtractor::Finalize() { - m_MFCC.freeMFCCmemory(); } void AudioSourceFeatureExtractor::VectorDistance(std::vector<float> vIn1, int stride1, std::vector<float> vIn2, int stride2, std::vector<float> &vOut, int strideOut, size_t nElements) @@ -443,15 +442,15 @@ fftwf_free(product); } -float AudioSourceFeatureExtractor::EstimatePerdiodicity(float* data, size_t numSamples) +float AudioSourceFeatureExtractor::EstimatePerdiodicity(std::vector<float> data) { float periodicity = 0.0; - std::vector<float> downsampleddata = std::vector<float>(numSamples, 0); + std::vector<float> downsampleddata = std::vector<float>(data.size(), 0); std::vector<float> xcorr; - for (size_t k = 0; k < numSamples; k++) + for (size_t k = 0; k < data.size(); k++) { downsampleddata[k] = data[k]; } @@ -495,7 +494,7 @@ float minValInRange = std::numeric_limits<float>::max(); - for (size_t j = static_cast<size_t>(from); j < to; j++) + for (size_t j = static_cast<size_t>(from); j < static_cast<size_t>(to); j++) { if (temp2[j] < minValInRange) { @@ -536,19 +535,19 @@ } } -float AudioSourceFeatureExtractor::EntropyOfEnergy(float* data, size_t len) +float AudioSourceFeatureExtractor::EntropyOfEnergy(std::vector<float> data) { float totalEnergy = 0.0; float totalentropy = 0.0; const int numSubFrames = 30; //Calculate Total Energy and normalise it - for (size_t i = 0; i < len; i++) + for (size_t i = 0; i < data.size(); i++) { totalEnergy += (data[i] * data[i]); } - int subFrameSize = len / numSubFrames; + int subFrameSize = data.size() / numSubFrames; for (size_t i = 0; i < numSubFrames; i++) {
--- a/Source/AudioSourceFeatureExtractor.h Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/AudioSourceFeatureExtractor.h Wed Aug 12 22:25:06 2015 +0100 @@ -31,7 +31,7 @@ ~AudioSourceFeatureExtractor(); void Initialise ( float fSampleRate); - std::vector<ObservationData> Process (const float* data, size_t numSamples); + std::vector<ObservationData> Process (const std::vector<float> data); void Finalize(); private: @@ -40,15 +40,13 @@ void SpectralFeatures(std::vector<float> &magnitude, std::vector<float> &previousmagnitude, size_t windowSize, float ¢roid, float &spread, float &skew, float &kurtosis, float &brightness, float &rolloff95, float &rolloff85, float &spectralentropy, float &flatness, float &spectralcf, float &spectralflux); - void MFCCs(std::vector<float> &magnitude, size_t windowSize, float sampleRate); - - float EstimatePerdiodicity(float* data, size_t numSamples); + float EstimatePerdiodicity(std::vector<float> data); void EnvelopeCurve(std::vector<float> data, std::vector<float> &out, float sampleRate); void XCorr(std::vector<float> &output, std::vector<float> input1, std::vector<float> input2, size_t maxLag); - float EntropyOfEnergy(float* data, size_t numSamples); + float EntropyOfEnergy(std::vector<float> data); float Log2(float n);
--- a/Source/FFT.cpp Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/FFT.cpp Wed Aug 12 22:25:06 2015 +0100 @@ -12,4 +12,4 @@ //FFT::FastFourierTransform() //{ // -//} +//}
--- a/Source/FFT.h Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/FFT.h Wed Aug 12 22:25:06 2015 +0100 @@ -19,33 +19,20 @@ { public: - FastFourierTransform(); + FastFourierTransform(){}; FastFourierTransform( unsigned fftLength ) : m_fft_impl( fftLength ) { - m_realPart = new float[fftLength]; - m_imagPart = new float[fftLength]; - - memset(m_realPart, 0, (fftLength)*sizeof(float)); - memset(m_imagPart, 0, (fftLength)*sizeof(float)); + std::vector<float> m_realPart = std::vector<float>(fftLength, 0); + std::vector<float> m_imagPart = std::vector<float>(fftLength, 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ~FastFourierTransform() { - if(m_realPart != NULL) - { - delete[] m_realPart; - m_realPart = nullptr; - } - if(m_imagPart != NULL) - { - delete[] m_imagPart; - m_imagPart = nullptr; - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -54,13 +41,13 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const float * realPart() { return m_realPart; } - const float * imagPart() { return m_imagPart; } + std::vector<float> realPart() { return m_realPart; } + std::vector<float> imagPart() { return m_imagPart; } private: - float* m_realPart; - float* m_imagPart; + std::vector<float> m_realPart; + std::vector<float> m_imagPart; FFTImpl m_fft_impl;
--- a/Source/FeatureData.cpp Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/FeatureData.cpp Wed Aug 12 22:25:06 2015 +0100 @@ -17,7 +17,7 @@ void FeatureData::PoolData(float timefactor) { //TODO: Remove hardcoded value - int modval = (int)(timefactor / 0.05); //50 millisecs + int modval = static_cast<int>(timefactor / 0.05); //50 millisecs int index = 0; int remainderindex = 0; @@ -519,7 +519,7 @@ avgdeltamfcc.push_back(Average(m_deltamfccs[10])); avgdeltamfcc.push_back(Average(m_deltamfccs[11])); - for(size_t i =0; i < m_PooledObservationDataAverage.size(); i++) + //for(size_t i =0; i < m_PooledObservationDataAverage.size(); i++) { obs = ObservationData(avgrms, avgpeak, avgcrestFactor, avgzcr, avgcentroid, avgspread, avgskewness, avgkurtosis, avgbrightness, avgrolloff85, avgrolloff95, avgspectralentropy, avgflatness, avgspectralcf, avgspectralflux, avgmfcc, avgdeltamfcc, m_ObservationData[0].GetPeriodicity(), m_ObservationData[0].GetEntropyOfEnergy()); obs.SetLowEnergy(m_ObservationData[0].GetLowEnergy()); @@ -776,7 +776,7 @@ sum += v[i]; } - return sum / (float)v.size(); + return sum / static_cast<float>(v.size()); } float FeatureData::Deviation(std::vector<float> v, float ave) @@ -788,7 +788,7 @@ E += (v[i] - ave) * (v[i] - ave); } - return sqrt((1 / (float)v.size()) * E); + return sqrt((1 / static_cast<float>(v.size())) * E); } float FeatureData::Max(std::vector<float> v)
--- a/Source/MFCC.cpp Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/MFCC.cpp Wed Aug 12 22:25:06 2015 +0100 @@ -1,40 +1,39 @@ /* - ============================================================================== +============================================================================== - MFCC.cpp - Created: 2 Sep 2014 3:30:50pm - Author: david.ronan +MFCC.cpp +Created: 2 Sep 2014 3:30:50pm +Author: david.ronan - ============================================================================== +============================================================================== */ #include "MFCC.h" #include <math.h> -//#include <windows.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 - vDSP_vmul(magnitude.data(), 1, m_ppMFCCFilters[i], 1, m_pfTempMelFilterResult, 1, m_pMFCCFilterLength[i]); + //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] = vDSP_sve(m_pfTempMelFilterResult, 1, 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; - } + //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: - vDSP_mmul(m_ppMFFC_DCT, 1, m_fMelFilteredFFT, 1, m_pMFCC, 1, m_iNumMFCCCoefs, 1, m_iTotalMFCCFilters); - mfccs.push_back(m_pMFCC[j]); - } + 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]); + } } @@ -42,182 +41,129 @@ //----------------------------------------------------------------------------- initMFFCvariables void MFCC::initMFFCvariables(int NCoeffs, int Nfft, float fSampleRate) { - m_iNumMFCCCoefs = NCoeffs; + m_iNumMFCCCoefs = NCoeffs; - m_pMFCC = new float[m_iNumMFCCCoefs]; + 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 / (float)(Nfft); - m_iTotalMFCCFilters = iNumLinearFilter + iNumLogFilters; + //Add a value to take into account the 0 coefficient + int iStartMfccCoeff = 1; - m_fMelFilteredFFT = new float[m_iTotalMFCCFilters]; - m_pMFCCFilterStart = new int[m_iTotalMFCCFilters]; - m_pMFCCFilterLength = new int[m_iTotalMFCCFilters]; - m_ppMFCCFilters = new float*[m_iTotalMFCCFilters]; + //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; - 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, (float)((i + j) - iNumLinearFilter + 1)); - } - } + 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 fTriangleHeight = 2.f / (FilterLimits[2] - FilterLimits[0]); - - int iStartBin = (int)(ceil(FilterLimits[0] / fFreqPerBin)); - int iStopBin = (int)(floor(FilterLimits[2] / fFreqPerBin)); - - int iFilterWidth = iStopBin-iStartBin+1; - m_pMFCCFilterStart[i] = iStartBin; - m_pMFCCFilterLength[i] = iFilterWidth; - m_ppMFCCFilters[i] = new float[iFilterWidth]; - - if(iFilterWidth > iFilterWidthMax) + float FilterLimits[3]; + int iFilterWidthMax = 0; + for (int i = 0; i < m_iTotalMFCCFilters; i++) { - 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 = new float[iFilterWidthMax]; - - //Compute the DCT reduction matrix - m_ppMFFC_DCT = new float[NCoeffs * m_iTotalMFCCFilters]; - - 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); - } - } -} - -//----------------------------------------------------------------------------- freeMFCCmemory -void MFCC::freeMFCCmemory() -{ - if(m_pMFCC != nullptr) - { - delete(m_pMFCC); - m_pMFCC=nullptr; - } - - if(m_ppMFFC_DCT != nullptr) - { - delete(m_ppMFFC_DCT); - m_ppMFFC_DCT=nullptr; - } - - if(m_fMelFilteredFFT != nullptr) - { - delete(m_fMelFilteredFFT); - m_fMelFilteredFFT=nullptr; - } - - if(m_pMFCCFilterStart != nullptr) - { - delete(m_pMFCCFilterStart); - m_pMFCCFilterStart=nullptr; - } - - if(m_pMFCCFilterLength != nullptr) - { - delete(m_pMFCCFilterLength); - m_pMFCCFilterLength=nullptr; - } - - if(m_pfTempMelFilterResult != nullptr) - { - delete(m_pfTempMelFilterResult); - m_pfTempMelFilterResult=nullptr; - } - - if(m_ppMFCCFilters != nullptr) - { - for(int i=0; i<m_iTotalMFCCFilters; i++) + for (int j = 0; j < 3; j++) { - if(m_ppMFCCFilters[i] != nullptr) + if (i + j < iNumLinearFilter) { - delete(m_ppMFCCFilters[i]); - m_ppMFCCFilters[i]=nullptr; + 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)); } } - delete (m_ppMFCCFilters); - m_ppMFCCFilters=nullptr; + 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); + } } } -//----------------------------------------------------------------------------- vDSP_vmul -inline void MFCC::vDSP_vmul(float* v1,int stride1, float* v2, int stride2, float* out, int outstride, int iNumSamples) +//----------------------------------------------------------------------------- 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*outstride] = v1[i*stride1] * v2[i*stride2]; - } + + for (int i = 0; i < iNumSamples; i++) + { + out[i] = v1[i] * v2[i]; + } } -//----------------------------------------------------------------------------- vDSP_sve -inline float MFCC::vDSP_sve(float* v, int , int iNumSamples) +//----------------------------------------------------------------------------- SumVector +float MFCC::SumVector(std::vector<float> v) { - float fSum = 0; + float fSum = 0; - for(int i=0; i < iNumSamples; i++) - { - fSum += v[i]; - } + for (size_t i = 0; i < v.size(); i++) + { + fSum += v[i]; + } - return fSum; + return fSum; } -//----------------------------------------------------------------------------- vDSP_mmul -inline void MFCC::vDSP_mmul(float* v1, int , float* v2, int , float* &vout, int , int M, int , int P) +//----------------------------------------------------------------------------- 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 m = 0; m < M; m++) + { + float fProdSum = 0.f; - for(int p = 0; p < P; p++) - { - fProdSum+=v1[m * P + p] * v2[p]; - } + for (int p = 0; p < P; p++) + { + fProdSum += v1[m * P + p] * v2[p]; + } - vout[m]=fProdSum; - } + vout[m] = fProdSum; + } }
--- a/Source/MFCC.h Wed Jul 22 15:28:00 2015 +0100 +++ b/Source/MFCC.h Wed Aug 12 22:25:06 2015 +0100 @@ -18,26 +18,23 @@ public: void initMFFCvariables(int NCoeffs, int Nfft, float fSampleRate); void ComputeMFCC(std::vector<float> magnitude, std::vector<float> &mfccs); - void freeMFCCmemory(); private: // -------- MFFC computation int m_iNumMFCCCoefs; int m_iTotalMFCCFilters; - int* m_pMFCCFilterStart; - int* m_pMFCCFilterLength; - float** m_ppMFCCFilters; - float* m_ppMFFC_DCT; - float* m_fMelFilteredFFT; - float* m_pMFCC; - float* m_pfTempMelFilterResult; + std::vector<int> m_pMFCCFilterStart; + std::vector<int> m_pMFCCFilterLength; + std::vector<std::vector<float>> m_ppMFCCFilters; + std::vector<float> m_ppMFFC_DCT; + std::vector<float> m_fMelFilteredFFT; + std::vector<float> m_pMFCC; + std::vector<float> m_pfTempMelFilterResult; - -// -------- tools -inline void vDSP_vmul(float* v1,int stride1, float* v2, int stride2, float* out, int outstride, int iNumSamples); + void MultiplyVector(std::vector<float> v1, std::vector<float> v2, std::vector<float> &out, int iNumSamples); -inline float vDSP_sve(float* v, int stride, int iNumSamples); + float SumVector(std::vector<float> v); -inline void vDSP_mmul(float* v1, int stride1, float* v2, int stride2, float* &vout, int strideOut, int M, int N, int P); + void MultiplySumVector(std::vector<float> v1, std::vector<float> v2, std::vector<float> &vout, int M, int P); };