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 &centroid, 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);
 
 };
 
--- a/Source/ParseCSV.cpp	Wed Jul 22 15:28:00 2015 +0100
+++ b/Source/ParseCSV.cpp	Wed Aug 12 22:25:06 2015 +0100
@@ -89,4 +89,4 @@
 	}
 
 	return lines;
-}
+}
--- a/Source/WriteCSV.cpp	Wed Jul 22 15:28:00 2015 +0100
+++ b/Source/WriteCSV.cpp	Wed Aug 12 22:25:06 2015 +0100
@@ -410,4 +410,4 @@
     strftime(buf, sizeof(buf), "%Y-%m-%d.%H-%M-%S", &tstruct);
 
     return buf;
-}
+}