Chromagram SpectrumAnalyser::chromagramOfFirstFrame( const AudioData& audio ) const { if (audio.getChannels() != 1) throw Exception("Audio must be monophonic to be analysed"); Chromagram c(1, octaves, bandsPerSemitone); unsigned int fftFrameSize = fft->getFrameSize(); for (unsigned int sample = 0; sample < fftFrameSize; sample++) { fft->setInput(sample, audio.getSample(sample) * temporalWindow[sample]); } fft->execute(); std::vector<float> cv = ct->chromaVector(fft); for (unsigned int band = 0; band < c.getBands(); band++) { c.setMagnitude(0, band, cv[band]); } return c; }
void LowPassFilterPrivate::filter(AudioData& audio, Workspace& workspace, unsigned int shortcutFactor) const { if (audio.getChannels() > 1) { throw Exception("Monophonic audio only"); } std::vector<double>* buffer = workspace.lpfBuffer; if (buffer == NULL) { workspace.lpfBuffer = new std::vector<double>(impulseLength, 0.0); buffer = workspace.lpfBuffer; } else { // clear delay buffer std::vector<double>::iterator bufferIterator = buffer->begin(); while (bufferIterator < buffer->end()) { *bufferIterator = 0.0; std::advance(bufferIterator, 1); } } std::vector<double>::iterator bufferFront = buffer->begin(); std::vector<double>::iterator bufferBack; std::vector<double>::iterator bufferTemp; unsigned int sampleCount = audio.getSampleCount(); audio.resetIterators(); double sum; // for each frame (running off the end of the sample stream by delay) for (unsigned int inSample = 0; inSample < sampleCount + delay; inSample++) { // shuffle old samples along delay buffer bufferBack = bufferFront; std::advance(bufferFront, 1); if (bufferFront == buffer->end()) { bufferFront = buffer->begin(); } // load new sample into back of delay buffer if (audio.readIteratorWithinUpperBound()) { *bufferBack = audio.getSampleAtReadIterator() / gain; audio.advanceReadIterator(); } else { *bufferBack = 0.0; // zero pad once we're past the end of the file } // start doing the maths once the delay has passed int outSample = (signed)inSample - (signed)delay; if (outSample < 0) { continue; } // and, if shortcut != 1, only do the maths for the useful samples (this is mathematically dodgy, but it's faster and it usually works) if (outSample % shortcutFactor > 0) { continue; } sum = 0.0; bufferTemp = bufferFront; std::vector<double>::const_iterator coefficientIterator = coefficients.begin(); while (coefficientIterator < coefficients.end()) { sum += *coefficientIterator * *bufferTemp; std::advance(coefficientIterator, 1); std::advance(bufferTemp, 1); if (bufferTemp == buffer->end()) { bufferTemp = buffer->begin(); } } audio.setSampleAtWriteIterator(sum); audio.advanceWriteIterator(shortcutFactor); } }
//Decodes the data in a WAV file and saves it into an AudioData class AudioData * coder::decode(string filename){ fstream audioFile; audioFile.open(filename, ios_base::in | ios_base::binary); //File does not exist if(audioFile.fail()){ return NULL; } AudioData * data = NULL; if(audioFile.is_open()){ data = new AudioData; //Read RIFF int smallBuffer; audioFile.read((char *)&smallBuffer, 4); data->setRIFF((char *)&smallBuffer); //Read file size audioFile.read((char *)&smallBuffer, 4); data->setFileSize(smallBuffer); //Read file type audioFile.read((char *)&smallBuffer, 4); data->setFileType((char *)&smallBuffer); //Read format audioFile.read((char *)&smallBuffer, 4); data->setFormat((char *)&smallBuffer); //Read format info size unsigned int infoSize = 0; audioFile.read((char *)&infoSize, 4); data->setFormatInfoSize(infoSize); //Read format info char * largeBuffer = (char *)malloc(sizeof(char) * infoSize); //remember to free on close memset(largeBuffer, 0x00, infoSize); audioFile.read(largeBuffer, infoSize); data->setFormatInfo(largeBuffer); //Read data chunk audioFile.read((char *)&smallBuffer, 4); data->setDataChunk((char *)&smallBuffer); //Read data size unsigned int dataSize = 0; audioFile.read((char *)&dataSize, 4); data->setDataSize(dataSize); //Read audio data largeBuffer = (char *)malloc(sizeof(char) * dataSize); memset(largeBuffer, 0x00, dataSize); audioFile.read(largeBuffer, dataSize); //Seperate audio data into multiple channels short ** channelData = seperateChannels((short *)largeBuffer, data->getChannels(), data->getNumberOfSamples()); data->setChannelData(channelData); free(largeBuffer); audioFile.close(); } return data; }