From 146c797f21c7d3ede438564d3c3204b10c5a8f5d Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 10:49:54 +0100 Subject: [PATCH 01/12] Media analyzer app: add new getTotalNbSamplesToAnalyse() method to AvSoundFile class --- app/mediaAnalyser/AvSoundFile.cpp | 20 +++++++++++++------- app/mediaAnalyser/AvSoundFile.hpp | 7 +++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/app/mediaAnalyser/AvSoundFile.cpp b/app/mediaAnalyser/AvSoundFile.cpp index b720f41..954f069 100644 --- a/app/mediaAnalyser/AvSoundFile.cpp +++ b/app/mediaAnalyser/AvSoundFile.cpp @@ -98,18 +98,23 @@ AvSoundFile::~AvSoundFile() } } +size_t AvSoundFile::getTotalNbSamplesToAnalyse() +{ + size_t newTotalNbSamplesToAnalyse = 0; + for(size_t i = 0; i < _inputSampleRate.size(); i++) + { + newTotalNbSamplesToAnalyse += _forceDurationToAnalyse * _inputSampleRate.at(i) * _inputNbChannels.at(i); + } + return newTotalNbSamplesToAnalyse; +} + void AvSoundFile::analyse(Loudness::analyser::LoudnessAnalyser& analyser) { // update number of samples to analyse if(_forceDurationToAnalyse) { - size_t newTotalNbSamplesToAnalyse = 0; - for(size_t i = 0; i < _inputSampleRate.size(); i++) - { - newTotalNbSamplesToAnalyse += _forceDurationToAnalyse * _inputSampleRate.at(i) * _inputNbChannels.at(i); - } // set total number of samples to analyse - _totalNbSamplesToAnalyse = newTotalNbSamplesToAnalyse; + _totalNbSamplesToAnalyse = getTotalNbSamplesToAnalyse(); } // open file to print duration @@ -126,12 +131,13 @@ void AvSoundFile::analyse(Loudness::analyser::LoudnessAnalyser& analyser) // Create planar buffer of float data float** audioBuffer = new float*[_nbChannelsToAnalyse]; + // Analyze audio streams bool emptyFrameDecoded = false; - // Decode audio streams while(!isEndOfAnalysis()) { size_t nbSamplesRead = 0; size_t nbInputChannelAdded = 0; + // Decode audio streams for(size_t fileIndex = 0; fileIndex < _audioReader.size(); ++fileIndex) { avtranscoder::IFrame* dstFrame = _audioReader.at(fileIndex)->readNextFrame(); diff --git a/app/mediaAnalyser/AvSoundFile.hpp b/app/mediaAnalyser/AvSoundFile.hpp index accf49d..81f67b8 100644 --- a/app/mediaAnalyser/AvSoundFile.hpp +++ b/app/mediaAnalyser/AvSoundFile.hpp @@ -47,6 +47,13 @@ class AvSoundFile */ bool isEndOfAnalysis(); + /** + * @brief Compute the total number of samples to analyse from the several inputs + * sample rate, the number of channels and the expected duration. + * @return the number of samples to analyse + */ + size_t getTotalNbSamplesToAnalyse(); + private: // for loudness analyser size_t _nbChannelsToAnalyse; From 26fbec2af74ca1ce2a5df982e5802c1e380ea502 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 10:57:03 +0100 Subject: [PATCH 02/12] Media Analyzer app: add new correct() method to AvSoundFile class --- app/mediaAnalyser/AvSoundFile.cpp | 141 ++++++++++++++++++++++++++++++ app/mediaAnalyser/AvSoundFile.hpp | 1 + 2 files changed, 142 insertions(+) diff --git a/app/mediaAnalyser/AvSoundFile.cpp b/app/mediaAnalyser/AvSoundFile.cpp index 954f069..124001d 100644 --- a/app/mediaAnalyser/AvSoundFile.cpp +++ b/app/mediaAnalyser/AvSoundFile.cpp @@ -5,6 +5,10 @@ #include #include +#include +#include +#include + void AvSoundFile::printProgress() { const int p = (float)_cumulOfSamplesAnalysed / _totalNbSamplesToAnalyse * 100; @@ -179,6 +183,143 @@ void AvSoundFile::analyse(Loudness::analyser::LoudnessAnalyser& analyser) delete[] audioBuffer; } +void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const float gain) +{ + // update number of samples to analyse + if(_forceDurationToAnalyse) + { + // set total number of samples to analyse + _totalNbSamplesToAnalyse = getTotalNbSamplesToAnalyse(); + } + + // open file to print duration + std::ofstream progressOutputFile; + if(! _progressionFileName.empty()) + { + progressOutputFile.open(_progressionFileName.c_str()); + _outputStream = &progressOutputFile; + } + + // init + analyser.initAndStart(_nbChannelsToAnalyse, _inputSampleRate.at(0)); + + // Create planar buffer of float data + float** audioBuffer = new float*[_nbChannelsToAnalyse]; + + // Initialize output encoder + int totalInputNbChannels = 0; + for(size_t i = 0; i < _inputNbChannels.size(); ++i) + totalInputNbChannels += _inputNbChannels.at(i); + + avtranscoder::AudioFrameDesc outputAudioFrameDesc(48000, totalInputNbChannels, "s32"); + avtranscoder::AudioEncoder* encoder = new avtranscoder::AudioEncoder("pcm_s24le"); + encoder->setupAudioEncoder(outputAudioFrameDesc); + + avtranscoder::OutputFile* outputFile = new avtranscoder::OutputFile("output.wav"); + outputFile->addAudioStream(encoder->getAudioCodec()); + outputFile->beginWrap(); + + // reset counters + _cumulOfSamplesAnalysed = 0; + + bool emptyFrameDecoded = false; + while(!isEndOfAnalysis()) + { + // Read audio data from source streams + size_t nbSamplesRead = 0; + size_t nbInputChannelAdded = 0; + for(size_t fileIndex = 0; fileIndex < _audioReader.size(); ++fileIndex) + { + avtranscoder::IFrame* srcFrame = _audioReader.at(fileIndex)->readNextFrame(); + + // empty frame: go to the end of process + if(srcFrame == NULL) + { + emptyFrameDecoded = true; + break; + } + + size_t inputChannel = 0; + for(size_t channelToAdd = nbInputChannelAdded; + channelToAdd < nbInputChannelAdded + _inputNbChannels.at(fileIndex); ++channelToAdd) + { + audioBuffer[channelToAdd] = (float*)(srcFrame->getData()[inputChannel]); + ++inputChannel; + nbSamplesRead += srcFrame->getAVFrame().nb_samples; + } + nbInputChannelAdded += _inputNbChannels.at(fileIndex); + } + + if(emptyFrameDecoded) + break; + + // Apply gain + const size_t nbSamplesInOneFrame = nbSamplesRead / nbInputChannelAdded; + for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) + { + // float* inData = &audioBuffer[channel][0]; + for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) + { + audioBuffer[channel][sample] = audioBuffer[channel][sample] * gain; + } + } + + // Convert corrected frame + avtranscoder::AudioFrameDesc correctAudioFrameDesc(48000, totalInputNbChannels, "fltp"); + avtranscoder::AudioFrame* correctedAudioFrame = new avtranscoder::AudioFrame(correctAudioFrameDesc, false); + correctedAudioFrame->setNbSamplesPerChannel(nbSamplesInOneFrame); + correctedAudioFrame->allocateData(); + + float* inlineBuffer = new float[nbSamplesRead]; + size_t sampleCounter = 0; + for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) + { + for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) + { + inlineBuffer[sampleCounter++] = audioBuffer[channel][sample]; + } + } + + unsigned char* rawData = reinterpret_cast(&inlineBuffer[0]); + correctedAudioFrame->assignBuffer(&rawData[0]); + + avtranscoder::AudioFrame* outputFrame = new avtranscoder::AudioFrame(outputAudioFrameDesc, false); + outputFrame->setNbSamplesPerChannel(nbSamplesInOneFrame); + outputFrame->allocateData(); + + avtranscoder::AudioTransform audioTransform; + audioTransform.convert(*correctedAudioFrame, *outputFrame); + + // Write corrected frame + avtranscoder::CodedData data; + encoder->encodeFrame(*outputFrame, data); + outputFile->wrap(data, 0); + + // Analyse loudness + analyser.processSamples(audioBuffer, nbSamplesInOneFrame); + + // Progress + _cumulOfSamplesAnalysed += nbSamplesRead; + printProgress(); + + delete rawData; + delete outputFrame; + delete correctedAudioFrame; + } + + outputFile->endWrap(); + + delete encoder; + delete outputFile; + + // Close progression file + if(! _progressionFileName.empty()) + progressOutputFile.close(); + + // free audio buffer + delete[] audioBuffer; +} + void AvSoundFile::setDurationToAnalyse(const float durationToAnalyse) { if(durationToAnalyse > 0) diff --git a/app/mediaAnalyser/AvSoundFile.hpp b/app/mediaAnalyser/AvSoundFile.hpp index 81f67b8..e661dfd 100644 --- a/app/mediaAnalyser/AvSoundFile.hpp +++ b/app/mediaAnalyser/AvSoundFile.hpp @@ -19,6 +19,7 @@ class AvSoundFile ~AvSoundFile(); void analyse(Loudness::analyser::LoudnessAnalyser& analyser); + void correct(Loudness::analyser::LoudnessAnalyser& analyser, const float gain); /** * @brief Set the output filename of the progress file. From 6d4df65d3061f546090e1224bb78f5fa6700842b Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 14:39:34 +0100 Subject: [PATCH 03/12] Media Analyzer app: factorize audio buffer filling and fix planar samples ordering --- app/mediaAnalyser/AvSoundFile.cpp | 86 ++++++++++++------------------- app/mediaAnalyser/AvSoundFile.hpp | 7 +++ 2 files changed, 39 insertions(+), 54 deletions(-) diff --git a/app/mediaAnalyser/AvSoundFile.cpp b/app/mediaAnalyser/AvSoundFile.cpp index 124001d..201f85a 100644 --- a/app/mediaAnalyser/AvSoundFile.cpp +++ b/app/mediaAnalyser/AvSoundFile.cpp @@ -112,6 +112,31 @@ size_t AvSoundFile::getTotalNbSamplesToAnalyse() return newTotalNbSamplesToAnalyse; } +bool AvSoundFile::fillAudioBuffer(float** audioBuffer, size_t& nbSamplesRead, size_t& nbInputChannelAdded) +{ + for(size_t fileIndex = 0; fileIndex < _audioReader.size(); ++fileIndex) + { + avtranscoder::IFrame* dstFrame = _audioReader.at(fileIndex)->readNextFrame(); + + // empty frame: go to the end of process + if(dstFrame == NULL) + { + return false; + } + + size_t inputChannel = 0; + for(size_t channelToAdd = nbInputChannelAdded; + channelToAdd < nbInputChannelAdded + _inputNbChannels.at(fileIndex); ++channelToAdd) + { + audioBuffer[channelToAdd] = (float*)(dstFrame->getData()[inputChannel]); + ++inputChannel; + nbSamplesRead += dstFrame->getAVFrame().nb_samples; + } + nbInputChannelAdded += _inputNbChannels.at(fileIndex); + } + return true; +} + void AvSoundFile::analyse(Loudness::analyser::LoudnessAnalyser& analyser) { // update number of samples to analyse @@ -136,34 +161,12 @@ void AvSoundFile::analyse(Loudness::analyser::LoudnessAnalyser& analyser) float** audioBuffer = new float*[_nbChannelsToAnalyse]; // Analyze audio streams - bool emptyFrameDecoded = false; while(!isEndOfAnalysis()) { + // Decode audio streams size_t nbSamplesRead = 0; size_t nbInputChannelAdded = 0; - // Decode audio streams - for(size_t fileIndex = 0; fileIndex < _audioReader.size(); ++fileIndex) - { - avtranscoder::IFrame* dstFrame = _audioReader.at(fileIndex)->readNextFrame(); - - // empty frame: go to the end of process - if(dstFrame == NULL) - { - emptyFrameDecoded = true; - break; - } - - size_t inputChannel = 0; - for(size_t channelToAdd = nbInputChannelAdded; - channelToAdd < nbInputChannelAdded + _inputNbChannels.at(fileIndex); ++channelToAdd) - { - audioBuffer[channelToAdd] = (float*)(dstFrame->getData()[inputChannel]); - ++inputChannel; - nbSamplesRead += dstFrame->getAVFrame().nb_samples; - } - nbInputChannelAdded += _inputNbChannels.at(fileIndex); - } - if(emptyFrameDecoded) + if(!fillAudioBuffer(audioBuffer, nbSamplesRead, nbInputChannelAdded)) break; // Analyse loudness @@ -222,42 +225,18 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const // reset counters _cumulOfSamplesAnalysed = 0; - bool emptyFrameDecoded = false; while(!isEndOfAnalysis()) { - // Read audio data from source streams + // Decode audio streams size_t nbSamplesRead = 0; size_t nbInputChannelAdded = 0; - for(size_t fileIndex = 0; fileIndex < _audioReader.size(); ++fileIndex) - { - avtranscoder::IFrame* srcFrame = _audioReader.at(fileIndex)->readNextFrame(); - - // empty frame: go to the end of process - if(srcFrame == NULL) - { - emptyFrameDecoded = true; - break; - } - - size_t inputChannel = 0; - for(size_t channelToAdd = nbInputChannelAdded; - channelToAdd < nbInputChannelAdded + _inputNbChannels.at(fileIndex); ++channelToAdd) - { - audioBuffer[channelToAdd] = (float*)(srcFrame->getData()[inputChannel]); - ++inputChannel; - nbSamplesRead += srcFrame->getAVFrame().nb_samples; - } - nbInputChannelAdded += _inputNbChannels.at(fileIndex); - } - - if(emptyFrameDecoded) + if(!fillAudioBuffer(audioBuffer, nbSamplesRead, nbInputChannelAdded)) break; // Apply gain const size_t nbSamplesInOneFrame = nbSamplesRead / nbInputChannelAdded; for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) { - // float* inData = &audioBuffer[channel][0]; for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) { audioBuffer[channel][sample] = audioBuffer[channel][sample] * gain; @@ -272,9 +251,9 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const float* inlineBuffer = new float[nbSamplesRead]; size_t sampleCounter = 0; - for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) + for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) { - for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) + for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) { inlineBuffer[sampleCounter++] = audioBuffer[channel][sample]; } @@ -302,9 +281,8 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const _cumulOfSamplesAnalysed += nbSamplesRead; printProgress(); - delete rawData; + delete inlineBuffer; delete outputFrame; - delete correctedAudioFrame; } outputFile->endWrap(); diff --git a/app/mediaAnalyser/AvSoundFile.hpp b/app/mediaAnalyser/AvSoundFile.hpp index e661dfd..812506a 100644 --- a/app/mediaAnalyser/AvSoundFile.hpp +++ b/app/mediaAnalyser/AvSoundFile.hpp @@ -55,6 +55,13 @@ class AvSoundFile */ size_t getTotalNbSamplesToAnalyse(); + /** + * @brief Fill input audio buffer with data from audio readers, and increment the + * number of read channels and the total number of samples read (every read channels). + * @return whether the audiobuffer could be filled + */ + bool fillAudioBuffer(float** audioBuffer, size_t& nbSamplesRead, size_t& nbInputChannelAdded); + private: // for loudness analyser size_t _nbChannelsToAnalyse; From f487cf435618fe5ab92cd4766ad1a35e2772ba05 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 15:36:37 +0100 Subject: [PATCH 04/12] Media Analyzer app: fix output audio encoding in loudness correction --- app/mediaAnalyser/AvSoundFile.cpp | 88 ++++++++++++++++++------------- app/mediaAnalyser/AvSoundFile.hpp | 16 ++++++ 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/app/mediaAnalyser/AvSoundFile.cpp b/app/mediaAnalyser/AvSoundFile.cpp index 201f85a..4381540 100644 --- a/app/mediaAnalyser/AvSoundFile.cpp +++ b/app/mediaAnalyser/AvSoundFile.cpp @@ -9,6 +9,11 @@ #include #include +const size_t NB_OF_BYTES_24_BITS = 3; +const float MAX_VALUE_24_BITS = 8388607.0; +const std::string CODEC_NAME_24_BITS = "pcm_s24le"; +const std::string SAMPLE_FORMAT_24_BITS = "s32"; + void AvSoundFile::printProgress() { const int p = (float)_cumulOfSamplesAnalysed / _totalNbSamplesToAnalyse * 100; @@ -214,8 +219,8 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const for(size_t i = 0; i < _inputNbChannels.size(); ++i) totalInputNbChannels += _inputNbChannels.at(i); - avtranscoder::AudioFrameDesc outputAudioFrameDesc(48000, totalInputNbChannels, "s32"); - avtranscoder::AudioEncoder* encoder = new avtranscoder::AudioEncoder("pcm_s24le"); + avtranscoder::AudioFrameDesc outputAudioFrameDesc(_audioReader.at(0)->getOutputSampleRate(), totalInputNbChannels, SAMPLE_FORMAT_24_BITS); + avtranscoder::AudioEncoder* encoder = new avtranscoder::AudioEncoder(CODEC_NAME_24_BITS); encoder->setupAudioEncoder(outputAudioFrameDesc); avtranscoder::OutputFile* outputFile = new avtranscoder::OutputFile("output.wav"); @@ -235,43 +240,16 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const // Apply gain const size_t nbSamplesInOneFrame = nbSamplesRead / nbInputChannelAdded; - for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) - { - for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) - { - audioBuffer[channel][sample] = audioBuffer[channel][sample] * gain; - } - } + applyGain(audioBuffer, nbSamplesInOneFrame, gain); // Convert corrected frame - avtranscoder::AudioFrameDesc correctAudioFrameDesc(48000, totalInputNbChannels, "fltp"); - avtranscoder::AudioFrame* correctedAudioFrame = new avtranscoder::AudioFrame(correctAudioFrameDesc, false); - correctedAudioFrame->setNbSamplesPerChannel(nbSamplesInOneFrame); - correctedAudioFrame->allocateData(); - - float* inlineBuffer = new float[nbSamplesRead]; - size_t sampleCounter = 0; - for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) - { - for(size_t sample = 0; sample < nbSamplesInOneFrame; sample++) - { - inlineBuffer[sampleCounter++] = audioBuffer[channel][sample]; - } - } - - unsigned char* rawData = reinterpret_cast(&inlineBuffer[0]); - correctedAudioFrame->assignBuffer(&rawData[0]); - - avtranscoder::AudioFrame* outputFrame = new avtranscoder::AudioFrame(outputAudioFrameDesc, false); - outputFrame->setNbSamplesPerChannel(nbSamplesInOneFrame); - outputFrame->allocateData(); - - avtranscoder::AudioTransform audioTransform; - audioTransform.convert(*correctedAudioFrame, *outputFrame); + const size_t rawDataSize = nbSamplesRead * NB_OF_BYTES_24_BITS; + unsigned char* rawData = new unsigned char[rawDataSize]; + encodePlanarSamplesToInterlacedPcm(audioBuffer, rawData, nbSamplesInOneFrame); // Write corrected frame avtranscoder::CodedData data; - encoder->encodeFrame(*outputFrame, data); + data.copyData(rawData, rawDataSize); outputFile->wrap(data, 0); // Analyse loudness @@ -281,8 +259,7 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const _cumulOfSamplesAnalysed += nbSamplesRead; printProgress(); - delete inlineBuffer; - delete outputFrame; + delete rawData; } outputFile->endWrap(); @@ -298,6 +275,45 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const delete[] audioBuffer; } +float AvSoundFile::clipSample(const float value) +{ + if (value > 1.f) { + return 1.f; + } + if (value < -1.f) { + return -1.f; + } + return value; +} + +void AvSoundFile::applyGain(float** audioBuffer, const size_t numberOfSamplesPerChannel, const float gain) +{ + for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) + { + for(size_t sample = 0; sample < numberOfSamplesPerChannel; sample++) + { + audioBuffer[channel][sample] = audioBuffer[channel][sample] * gain; + } + } +} + +void AvSoundFile::encodePlanarSamplesToInterlacedPcm(float** planarBuffer, unsigned char* interlacedBuffer, const size_t numberOfSamplesPerChannel) +{ + size_t sampleCounter = 0; + for(size_t sample = 0; sample < numberOfSamplesPerChannel; sample++) + { + for(size_t channel = 0; channel < _nbChannelsToAnalyse; channel++) + { + const size_t offset = sampleCounter++ * NB_OF_BYTES_24_BITS; + const float sampleValueClipped = clipSample(planarBuffer[channel][sample]); + const int sampleValue = (int)(sampleValueClipped * MAX_VALUE_24_BITS); + interlacedBuffer[offset] = sampleValue & 0xff; + interlacedBuffer[offset + 1] = (sampleValue >> 8) & 0xff; + interlacedBuffer[offset + 2] = (sampleValue >> 16) & 0xff; + } + } +} + void AvSoundFile::setDurationToAnalyse(const float durationToAnalyse) { if(durationToAnalyse > 0) diff --git a/app/mediaAnalyser/AvSoundFile.hpp b/app/mediaAnalyser/AvSoundFile.hpp index 812506a..b11589f 100644 --- a/app/mediaAnalyser/AvSoundFile.hpp +++ b/app/mediaAnalyser/AvSoundFile.hpp @@ -62,6 +62,22 @@ class AvSoundFile */ bool fillAudioBuffer(float** audioBuffer, size_t& nbSamplesRead, size_t& nbInputChannelAdded); + /** + * @brief Apply gain to specified planar audio buffer samples. + */ + void applyGain(float** audioBuffer, const size_t numberOfSamplesPerChannel, const float gain); + + /** + * @brief Clip audio sample value to normalized values [-1.0, 1.0]. + * @return the clipped audio sample value + */ + float clipSample(const float value); + + /** + * @brief Convert planar audio samples buffer into interlaced PCM values buffer. + */ + void encodePlanarSamplesToInterlacedPcm(float** planarBuffer, unsigned char* interlacedBuffer, const size_t numberOfSamplesPerChannel); + private: // for loudness analyser size_t _nbChannelsToAnalyse; From baf7b4aa8bffde9b48b16a08d24c998c46d7915e Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 15:46:46 +0100 Subject: [PATCH 05/12] Media Analyzer app: update main and pass loudness correction output file path as parameter --- app/mediaAnalyser/AvSoundFile.cpp | 4 ++-- app/mediaAnalyser/AvSoundFile.hpp | 2 +- app/mediaAnalyser/main.cpp | 34 +++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/app/mediaAnalyser/AvSoundFile.cpp b/app/mediaAnalyser/AvSoundFile.cpp index 4381540..66222fd 100644 --- a/app/mediaAnalyser/AvSoundFile.cpp +++ b/app/mediaAnalyser/AvSoundFile.cpp @@ -191,7 +191,7 @@ void AvSoundFile::analyse(Loudness::analyser::LoudnessAnalyser& analyser) delete[] audioBuffer; } -void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const float gain) +void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const std::string& outputFilePath, const float gain) { // update number of samples to analyse if(_forceDurationToAnalyse) @@ -223,7 +223,7 @@ void AvSoundFile::correct(Loudness::analyser::LoudnessAnalyser& analyser, const avtranscoder::AudioEncoder* encoder = new avtranscoder::AudioEncoder(CODEC_NAME_24_BITS); encoder->setupAudioEncoder(outputAudioFrameDesc); - avtranscoder::OutputFile* outputFile = new avtranscoder::OutputFile("output.wav"); + avtranscoder::OutputFile* outputFile = new avtranscoder::OutputFile(outputFilePath); outputFile->addAudioStream(encoder->getAudioCodec()); outputFile->beginWrap(); diff --git a/app/mediaAnalyser/AvSoundFile.hpp b/app/mediaAnalyser/AvSoundFile.hpp index b11589f..ccd6d51 100644 --- a/app/mediaAnalyser/AvSoundFile.hpp +++ b/app/mediaAnalyser/AvSoundFile.hpp @@ -19,7 +19,7 @@ class AvSoundFile ~AvSoundFile(); void analyse(Loudness::analyser::LoudnessAnalyser& analyser); - void correct(Loudness::analyser::LoudnessAnalyser& analyser, const float gain); + void correct(Loudness::analyser::LoudnessAnalyser& analyser, const std::string& outputFilePath, const float gain); /** * @brief Set the output filename of the progress file. diff --git a/app/mediaAnalyser/main.cpp b/app/mediaAnalyser/main.cpp index a68eb75..2690a54 100644 --- a/app/mediaAnalyser/main.cpp +++ b/app/mediaAnalyser/main.cpp @@ -58,17 +58,18 @@ void printHelp() std::string help; help += "Usage\n"; help += "\tmedia-analyser CONFIG.TXT [--output XMLReportName][--progressionInFile " - "progressionName][--forceDurationToAnalyse durationToAnalyse][--help]\n"; + "progressionName][--forceDurationToAnalyse durationToAnalyse][--correction outputFile][--help]\n"; help += "CONFIG.TXT\n"; help += "\tEach line will be one audio stream analysed by the loudness library.\n"; help += "\tPattern of each line is:\n"; help += "\t[inputFile]=STREAM_INDEX.CHANNEL_INDEX\n"; help += "Command line options\n"; help += "\t--help: display this help\n"; - help += "\t--output: filename of the XML report\n"; help += "\t--progressionInFile: to print the progression in a file instead of in console\n"; + help += "\t--output: filename of the XML report\n"; help += "\t--forceDurationToAnalyse: to force loudness analysis on a specific duration (in seconds). By default this is " "the duration of the input.\n"; + help += "\t--correction: enable loudness correction, and write the corrected streams to the specified output file\n"; std::cout << help << std::endl; } @@ -78,6 +79,9 @@ int main(int argc, char** argv) std::string outputProgressionName; float durationToAnalyse = 0; + bool correction = false; + std::string correctionOutputFile; + // Check required arguments if(argc < 2) { @@ -135,6 +139,19 @@ int main(int argc, char** argv) return 1; } } + else if(arguments.at(argument) == "--correction") + { + correction = true; + try + { + correctionOutputFile = arguments.at(++argument); + } + catch(...) + { + printHelp(); + return 1; + } + } // unknown option continue; } @@ -157,6 +174,19 @@ int main(int argc, char** argv) // Print analyse analyser.printPloudValues(); + const float gain = analyser.getCorrectionGain(); + + if(correction && std::fabs(1.0 - gain) > 0.001) + { + std::cout << "Correction with gain " << gain << std::endl; + Loudness::analyser::LoudnessLevels level = Loudness::analyser::LoudnessLevels::Loudness_EBU_R128(); + AvSoundFile correctedSoundFile(arrayToAnalyse); + correctedSoundFile.setProgressionFile(outputProgressionName); + correctedSoundFile.setDurationToAnalyse(durationToAnalyse); + correctedSoundFile.correct(analyser, correctionOutputFile, gain); + + analyser.printPloudValues(); + } // Write XML std::vector mediaFilenames; From 6d98b4c3d8ffc456beab27fecfe1f27d66c5e0ae Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 16:30:08 +0100 Subject: [PATCH 06/12] Media Analyze app: fix fabs function import --- app/mediaAnalyser/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/mediaAnalyser/main.cpp b/app/mediaAnalyser/main.cpp index 2690a54..59eea0f 100644 --- a/app/mediaAnalyser/main.cpp +++ b/app/mediaAnalyser/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include std::vector parseConfigFile(const std::string& configFilename) { @@ -179,7 +180,6 @@ int main(int argc, char** argv) if(correction && std::fabs(1.0 - gain) > 0.001) { std::cout << "Correction with gain " << gain << std::endl; - Loudness::analyser::LoudnessLevels level = Loudness::analyser::LoudnessLevels::Loudness_EBU_R128(); AvSoundFile correctedSoundFile(arrayToAnalyse); correctedSoundFile.setProgressionFile(outputProgressionName); correctedSoundFile.setDurationToAnalyse(durationToAnalyse); From e0573cc02ebbe8bea088214977541423ec6ee627 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 17:02:05 +0100 Subject: [PATCH 07/12] LoudnessTools: write correction gain into XML --- src/loudnessTools/WriteXml.cpp | 20 +++++++++++++++++--- src/loudnessTools/WriteXml.hpp | 3 ++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/loudnessTools/WriteXml.cpp b/src/loudnessTools/WriteXml.cpp index c107e4c..dc0369c 100644 --- a/src/loudnessTools/WriteXml.cpp +++ b/src/loudnessTools/WriteXml.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace Loudness { @@ -27,7 +28,7 @@ WriteXml::~WriteXml() xmlFile.close(); } -void WriteXml::writeResults(const std::string& channelType, Loudness::analyser::LoudnessAnalyser& analyser) +void WriteXml::writeResults(const std::string& channelType, Loudness::analyser::LoudnessAnalyser& analyser, const float correctionGain) { xmlFile << "\n"; + << "channelsType=\"" << channelType << "\" "; + if(std::fabs(1.0 - correctionGain) > 0.001) + { + xmlFile << "correctionGain=\"" << getGainAsDb(correctionGain) << "\" "; + } + xmlFile << "date=\"" << getDate() << "\">\n"; xmlFile << "\t" << analyser.getIntegratedLoudness() << "\n"; xmlFile << "\t" << analyser.getIntegratedRange() @@ -155,5 +160,14 @@ std::string WriteXml::getDate() date.assign(buffer); return date; } + +std::string WriteXml::getGainAsDb(const float gain) +{ + std::ostringstream ss; + ss << 20.0 * std::log10(gain); + ss << " dB"; + return ss.str(); +} + } } diff --git a/src/loudnessTools/WriteXml.hpp b/src/loudnessTools/WriteXml.hpp index 7707976..30652bb 100644 --- a/src/loudnessTools/WriteXml.hpp +++ b/src/loudnessTools/WriteXml.hpp @@ -19,7 +19,7 @@ class WriteXml ~WriteXml(); - void writeResults(const std::string& channelType, Loudness::analyser::LoudnessAnalyser& analyser); + void writeResults(const std::string& channelType, Loudness::analyser::LoudnessAnalyser& analyser, const float correctionGain = 1.0); private: void openXMLFile(const std::string& xmlFilename); @@ -28,6 +28,7 @@ class WriteXml std::string writeValues(std::vector datas); std::string replaceXmlSpecialCharacters(std::string& text); std::string getDate(); + std::string getGainAsDb(const float gain); std::ofstream xmlFile; std::vector srcAudioFilenames; From bfa8216aeb9caac644d9268faf4b6a0d8270f711 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Wed, 19 Feb 2020 17:04:13 +0100 Subject: [PATCH 08/12] Media Analyzer app: write correction gain into XML --- app/mediaAnalyser/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/mediaAnalyser/main.cpp b/app/mediaAnalyser/main.cpp index 59eea0f..dbf9218 100644 --- a/app/mediaAnalyser/main.cpp +++ b/app/mediaAnalyser/main.cpp @@ -198,7 +198,7 @@ int main(int argc, char** argv) std::stringstream ss; ss << soundFile.getNbChannelsToAnalyse(); ss << " channels"; - writerXml.writeResults(ss.str(), analyser); + writerXml.writeResults(ss.str(), analyser, (correction)? gain : 1.0); } catch(const std::exception& e) { From 03b9f562194f061582e1191d6473939a69209ca2 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Thu, 20 Feb 2020 10:00:36 +0100 Subject: [PATCH 09/12] Travis: update G++ version to compile GoogleTest --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bf5d1b1..96d2c16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,12 +29,16 @@ env: addons: apt: - sources: ['boost-latest'] + sources: [ + 'boost-latest', + 'ubuntu-toolchain-r-test' + ] packages: - scons - libboost1.58-all-dev - libsndfile1-dev - libqt4-dev + - g++-7 cache: # Caching Ubuntu packages From 2bb002d6c347898f2e88e6001695cfa816270c81 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Thu, 20 Feb 2020 10:10:41 +0100 Subject: [PATCH 10/12] Travis: export CC & CXX for GoogleTest build --- tools/travis/install_dependencies.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/travis/install_dependencies.sh b/tools/travis/install_dependencies.sh index b2c70de..9583886 100755 --- a/tools/travis/install_dependencies.sh +++ b/tools/travis/install_dependencies.sh @@ -7,6 +7,10 @@ set -x # Install GTest framework if [[ ! -d "${GTEST_INSTALL}/*" ]]; then + if [ "$TRAVIS_COMPILER" == "gcc" ]; then + export CC=/usr/bin/gcc-7 + export CXX=/usr/bin/g++-7 + fi git clone https://github.com/google/googletest.git cd googletest cmake . -DCMAKE_INSTALL_PREFIX=${GTEST_INSTALL} From 850938bc8a2246065a39a446a4acf75f097b1896 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Thu, 20 Feb 2020 10:48:10 +0100 Subject: [PATCH 11/12] Travis: force G++ version on MacOSx --- .travis.yml | 3 +++ tools/travis/install_dependencies.sh | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 96d2c16..ee8efa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,6 +50,9 @@ cache: - ${FFMPEG_INSTALL} - ${AVTRANSCODER_INSTALL} +before_install: + - if [ "$TRAVIS_OS_NAME" == "osx" ] && [ "$TRAVIS_COMPILER" == "gcc" ]; then eval "CC=gcc-7 && CXX=g++-7"; fi + install: # Install dependencies - ./tools/travis/install_dependencies.sh diff --git a/tools/travis/install_dependencies.sh b/tools/travis/install_dependencies.sh index 9583886..1900d17 100755 --- a/tools/travis/install_dependencies.sh +++ b/tools/travis/install_dependencies.sh @@ -5,9 +5,15 @@ set -e # Print commands and their arguments as they are executed. set -x +# Install additional dependencies in case of osx environment +if [ ${TRAVIS_OS_NAME} = "osx" ]; then + brew update + brew install scons lcov libsndfile qt gcc@7 +fi + # Install GTest framework if [[ ! -d "${GTEST_INSTALL}/*" ]]; then - if [ "$TRAVIS_COMPILER" == "gcc" ]; then + if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$TRAVIS_COMPILER" == "gcc" ]; then export CC=/usr/bin/gcc-7 export CXX=/usr/bin/g++-7 fi @@ -25,9 +31,3 @@ if [[ ! -d "${AVTRANSCODER_INSTALL}/*" ]]; then tar xzf ${ARCHIVE_FILE} -C ${TRAVIS_BUILD_DIR} rm ${ARCHIVE_FILE} fi - -# Install additional dependencies in case of osx environment -if [ ${TRAVIS_OS_NAME} = "osx" ]; then - brew update - brew install scons lcov libsndfile qt -fi From 75aa2c44456f19a65a6cc9b0cb7e963f9ea502a2 Mon Sep 17 00:00:00 2001 From: Valentin NOEL Date: Thu, 20 Feb 2020 12:05:17 +0100 Subject: [PATCH 12/12] Travis: revert and use the 1.10.0 release version of GoogleTest --- .travis.yml | 9 +-------- tools/travis/install_dependencies.sh | 17 +++++++---------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index ee8efa3..bf5d1b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,16 +29,12 @@ env: addons: apt: - sources: [ - 'boost-latest', - 'ubuntu-toolchain-r-test' - ] + sources: ['boost-latest'] packages: - scons - libboost1.58-all-dev - libsndfile1-dev - libqt4-dev - - g++-7 cache: # Caching Ubuntu packages @@ -50,9 +46,6 @@ cache: - ${FFMPEG_INSTALL} - ${AVTRANSCODER_INSTALL} -before_install: - - if [ "$TRAVIS_OS_NAME" == "osx" ] && [ "$TRAVIS_COMPILER" == "gcc" ]; then eval "CC=gcc-7 && CXX=g++-7"; fi - install: # Install dependencies - ./tools/travis/install_dependencies.sh diff --git a/tools/travis/install_dependencies.sh b/tools/travis/install_dependencies.sh index 1900d17..0e8e851 100755 --- a/tools/travis/install_dependencies.sh +++ b/tools/travis/install_dependencies.sh @@ -5,20 +5,11 @@ set -e # Print commands and their arguments as they are executed. set -x -# Install additional dependencies in case of osx environment -if [ ${TRAVIS_OS_NAME} = "osx" ]; then - brew update - brew install scons lcov libsndfile qt gcc@7 -fi - # Install GTest framework if [[ ! -d "${GTEST_INSTALL}/*" ]]; then - if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$TRAVIS_COMPILER" == "gcc" ]; then - export CC=/usr/bin/gcc-7 - export CXX=/usr/bin/g++-7 - fi git clone https://github.com/google/googletest.git cd googletest + git checkout release-1.10.0 cmake . -DCMAKE_INSTALL_PREFIX=${GTEST_INSTALL} make -k make install @@ -31,3 +22,9 @@ if [[ ! -d "${AVTRANSCODER_INSTALL}/*" ]]; then tar xzf ${ARCHIVE_FILE} -C ${TRAVIS_BUILD_DIR} rm ${ARCHIVE_FILE} fi + +# Install additional dependencies in case of osx environment +if [ ${TRAVIS_OS_NAME} = "osx" ]; then + brew update + brew install scons lcov libsndfile qt +fi