annotate Source/AudioReader.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 636c989477e7
children
rev   line source
d@0 1 /*
d@0 2 ==============================================================================
d@0 3
d@0 4 AudioReader.cpp
d@0 5 Created: 27 Aug 2014 3:17:10pm
d@0 6 Author: david.ronan
d@0 7
d@0 8 ==============================================================================
d@0 9 */
d@0 10
d@0 11
d@0 12
d@0 13
d@0 14 #include "AudioReader.h"
d@0 15 #include "WriteCSV.h"
d@0 16 #include <iostream>
d@0 17 #include <vector>
d@0 18
d@0 19 #define ENERGYSEARCHTIME 3
d@0 20 #define SAMPLERATE 22050.0f
d@13 21 #include "XMLWrite.h"
d@0 22
d@0 23 AudioReader::AudioReader()
d@2 24 {
d@1 25
d@0 26 };
d@0 27
d@0 28 AudioReader::~AudioReader()
d@0 29 {
d@0 30
d@0 31 };
d@0 32
d@0 33 std::vector<FeatureData> AudioReader::Read(AudioFileData audioFileData, float poolTimeSecs, int analysisWindowSize)
d@0 34 {
d@0 35 WriteCSV writeCSV = WriteCSV();
d@13 36 XMLWrite xmlWrite = XMLWrite();
d@0 37 std::vector<FeatureData> featureData = std::vector<FeatureData>();
d@0 38 std::string CSVFileName = "..\\FeatureData" + writeCSV.currentDateTime();
d@1 39
d@0 40 vector<string> audioFileNames = audioFileData.GetFileNames();
d@2 41 vector<string> labels = audioFileData.GetLabels();
d@2 42
d@1 43 AudioFormatManager m_formatManager;
d@1 44 m_formatManager.registerBasicFormats();
d@1 45 m_AudioSourceFeatureExtractor.Initialise(SAMPLERATE);
d@0 46
d@0 47 for(size_t i=0; i<audioFileNames.size(); i++)
d@0 48 {
d@3 49 float percentcomplete = static_cast<float>(i) / static_cast<float>(audioFileNames.size()) * 100.0f;
d@0 50
d@0 51 std::string outputStr = "Extracting features for " + audioFileNames[i] + "\n" + std::to_string(percentcomplete) + "% complete...";
d@0 52 cout << outputStr;
d@9 53
d@0 54 //Create file from our audio data
d@0 55 File audioFile(audioFileNames[i].c_str());
d@0 56
d@9 57 unique_ptr<AudioFormatReader> audioFileReader(m_formatManager.createReaderFor(audioFile));
d@1 58
d@3 59 if(audioFileReader != nullptr)
d@3 60 {
d@3 61 float fSampleRate = static_cast<float>(audioFileReader->sampleRate);
d@3 62 int iLengthInSamples = static_cast<int>(audioFileReader->lengthInSamples);
d@3 63 int iNumOfChannels = audioFileReader->numChannels;
d@1 64
d@3 65 if (fSampleRate != 22050.0f)
d@0 66 {
d@0 67 cout << "\n\n\nERROR: File is not the required 22050 Hz sample rate.!!!\n\n\n";
d@0 68 }
d@1 69
d@0 70 //Get loudest 30 secs. of audio
d@3 71 int numOfSamplesToCollect = static_cast<int>(analysisWindowSize * fSampleRate);
d@0 72
d@3 73 if(iLengthInSamples <= numOfSamplesToCollect)
d@0 74 {
d@3 75 numOfSamplesToCollect = iLengthInSamples;
d@0 76 }
d@0 77
d@0 78 //Length of the full track in stereo;
d@9 79 int* destSamples[2] = { nullptr };
d@9 80 unique_ptr<int> L(new int[iLengthInSamples]);
d@9 81 memset(L.get(), 0, iLengthInSamples);
d@9 82 destSamples[0] = L.get();
d@9 83 destSamples[1] = L.get();
d@1 84
d@9 85
d@0 86 //30 sec clips to check energy levels
d@9 87 std::vector<float> destSamplesFloat = std::vector<float>(static_cast<size_t>(numOfSamplesToCollect, 0));
d@0 88
d@1 89 int timesToLoop = 0;
d@0 90
d@3 91 if(iLengthInSamples == numOfSamplesToCollect)
d@0 92 {
d@0 93 timesToLoop = 1;
d@0 94 }
d@0 95 else
d@0 96 {
d@3 97 timesToLoop = static_cast<int>((iLengthInSamples - numOfSamplesToCollect) / (ENERGYSEARCHTIME * fSampleRate));
d@0 98 }
d@0 99
d@0 100 std::vector<float> thirtySecEnergy = std::vector<float>();
d@0 101
d@0 102 //float loudestEnergy = 0.0;
d@9 103 bool dave;
d@9 104 dave = audioFileReader->readSamples(destSamples, iNumOfChannels, 0, 0, iLengthInSamples);
d@0 105
d@0 106 for(int j=0; j < timesToLoop;j++)
d@1 107 {
d@0 108 float fSum=0.f;
d@0 109
d@0 110 for(int n=0; n<numOfSamplesToCollect; n++)
d@0 111 {
d@0 112 //Sum to mono if needed and workout the energy for each 30 sec. frame
d@3 113 if(iNumOfChannels > 1)
d@0 114 {
d@9 115 destSamplesFloat.push_back(static_cast<float>((destSamples[0][int(j * ENERGYSEARCHTIME * fSampleRate) + n] + destSamples[1][int( j * ENERGYSEARCHTIME * fSampleRate) + n]) / 2) / (0x7fffffff));
d@0 116 }
d@0 117 else
d@0 118 {
d@9 119 destSamplesFloat.push_back(static_cast<float>(destSamples[0][int(j * ENERGYSEARCHTIME * fSampleRate) + n]) / (0x7fffffff));
d@0 120 }
d@0 121
d@0 122 fSum+=(destSamplesFloat[n] * destSamplesFloat[n]);
d@0 123 }
d@0 124
d@0 125 //Normalise and push onto the list of 30 sec clips.
d@0 126 fSum /= numOfSamplesToCollect;
d@0 127
d@0 128 //if (fSum > loudestEnergy)
d@0 129 //{
d@0 130 // loudestEnergy = fSum;
d@0 131 // destSamplesFloatLoudest = destSamplesFloat;
d@0 132 //}
d@0 133
d@0 134 thirtySecEnergy.push_back(fSum);
d@0 135 }
d@0 136
d@1 137 //Find the index of the section with the most energy
d@0 138 int maxIdx = std::distance(thirtySecEnergy.begin(), max_element(thirtySecEnergy.begin(), thirtySecEnergy.end()));
d@0 139
d@0 140 int* thirtySecSamples[2] = {0};
d@9 141 unique_ptr<int> L30(new int[iLengthInSamples]{ 0 });
d@9 142 memset(L30.get(), 0, iLengthInSamples);
d@9 143 thirtySecSamples[0]=L30.get(); //Left channel
d@9 144 thirtySecSamples[1]=L30.get(); //Left right
d@0 145
d@0 146 //Read the 30 secs. in
d@3 147 audioFileReader->readSamples(thirtySecSamples, iNumOfChannels, 0, int(maxIdx * ENERGYSEARCHTIME * fSampleRate), numOfSamplesToCollect);
d@9 148
d@9 149 destSamplesFloat = std::vector<float>(static_cast<size_t>(numOfSamplesToCollect, 0));
d@0 150
d@0 151 for(int n=0; n<numOfSamplesToCollect; n++)
d@1 152 {
d@1 153 //Sum to mono if needed
d@3 154 if(iNumOfChannels > 1)
d@0 155 {
d@9 156 destSamplesFloat.push_back(static_cast<float>((thirtySecSamples[0][n] + thirtySecSamples[1][n]) / 2) / (0x7fffffff));
d@0 157 }
d@0 158 else
d@0 159 {
d@9 160 destSamplesFloat.push_back(static_cast<float>(thirtySecSamples[0][n]) / (0x7fffffff));
d@0 161 }
d@0 162 }
d@0 163
d@9 164 std::vector<ObservationData> newObs = m_AudioSourceFeatureExtractor.Process(destSamplesFloat);
d@1 165
d@3 166 FeatureData newFeature = FeatureData(newObs, labels[i], audioFileNames[i], fSampleRate, FFTSIZE, static_cast<float>(numOfSamplesToCollect), poolTimeSecs);
d@1 167
d@14 168 //XML from now on.
d@0 169 writeCSV.Write(CSVFileName, newFeature);
d@13 170 xmlWrite.Write(CSVFileName, newFeature);
d@1 171
d@0 172 //Update the screen information;
d@2 173
d@9 174 cout << string(outputStr.length(),'\b');
d@3 175
d@0 176 }
d@0 177 else
d@0 178 {
d@0 179 cout << "\n\n\nERROR: Could not find file!!!\n\n\n";
d@3 180 }
d@0 181 }
d@0 182
d@0 183 m_AudioSourceFeatureExtractor.Finalize();
d@1 184
d@0 185 return featureData;
d@2 186 };