# HG changeset patch # User Chris Cannam # Date 1402671828 -3600 # Node ID f3cda3280398ebdad832a2537ed823ece76da3fe # Parent 4c7b4040bd2daac3883a9def0279fae7104ad9a2 Add normalised option to CodedAudioFileReader diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/AudioFileReaderFactory.cpp --- a/data/fileio/AudioFileReaderFactory.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/AudioFileReaderFactory.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -58,21 +58,28 @@ } AudioFileReader * -AudioFileReaderFactory::createReader(FileSource source, size_t targetRate, +AudioFileReaderFactory::createReader(FileSource source, + size_t targetRate, + bool normalised, ProgressReporter *reporter) { - return create(source, targetRate, false, reporter); + return create(source, targetRate, normalised, false, reporter); } AudioFileReader * -AudioFileReaderFactory::createThreadingReader(FileSource source, size_t targetRate, +AudioFileReaderFactory::createThreadingReader(FileSource source, + size_t targetRate, + bool normalised, ProgressReporter *reporter) { - return create(source, targetRate, true, reporter); + return create(source, targetRate, normalised, true, reporter); } AudioFileReader * -AudioFileReaderFactory::create(FileSource source, size_t targetRate, bool threading, +AudioFileReaderFactory::create(FileSource source, + size_t targetRate, + bool normalised, + bool threading, ProgressReporter *reporter) { QString err; @@ -102,9 +109,10 @@ if (reader->isOK() && (!reader->isQuicklySeekable() || + normalised || (targetRate != 0 && fileRate != targetRate))) { - SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; + SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; delete reader; reader = new DecodingWavFileReader @@ -114,6 +122,7 @@ DecodingWavFileReader::ResampleAtOnce, DecodingWavFileReader::CacheInTemporaryFile, targetRate ? targetRate : fileRate, + normalised, reporter); if (!reader->isOK()) { delete reader; @@ -133,6 +142,7 @@ OggVorbisFileReader::DecodeAtOnce, OggVorbisFileReader::CacheInTemporaryFile, targetRate, + normalised, reporter); if (!reader->isOK()) { delete reader; @@ -153,6 +163,7 @@ MP3FileReader::DecodeAtOnce, MP3FileReader::CacheInTemporaryFile, targetRate, + normalised, reporter); if (!reader->isOK()) { delete reader; @@ -172,6 +183,7 @@ QuickTimeFileReader::DecodeAtOnce, QuickTimeFileReader::CacheInTemporaryFile, targetRate, + normalised, reporter); if (!reader->isOK()) { delete reader; @@ -191,6 +203,7 @@ CoreAudioFileReader::DecodeAtOnce, CoreAudioFileReader::CacheInTemporaryFile, targetRate, + normalised, reporter); if (!reader->isOK()) { delete reader; @@ -215,9 +228,10 @@ if (reader->isOK() && (!reader->isQuicklySeekable() || + normalised || (targetRate != 0 && fileRate != targetRate))) { - SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; + SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; delete reader; reader = new DecodingWavFileReader @@ -227,6 +241,7 @@ DecodingWavFileReader::ResampleAtOnce, DecodingWavFileReader::CacheInTemporaryFile, targetRate ? targetRate : fileRate, + normalised, reporter); } diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/AudioFileReaderFactory.h --- a/data/fileio/AudioFileReaderFactory.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/AudioFileReaderFactory.h Fri Jun 13 16:03:48 2014 +0100 @@ -43,6 +43,9 @@ * if you want to find out whether the file is being resampled * or not. * + * If normalised is true, the file data will be normalised to + * abs(max) == 1.0. Otherwise the file will not be normalised. + * * If a ProgressReporter is provided, it will be updated with * progress status. Caller retains ownership of the reporter * object. @@ -51,6 +54,7 @@ */ static AudioFileReader *createReader(FileSource source, size_t targetRate = 0, + bool normalised = false, ProgressReporter *reporter = 0); /** @@ -65,6 +69,9 @@ * if you want to find out whether the file is being resampled * or not. * + * If normalised is true, the file data will be normalised to + * abs(max) == 1.0. Otherwise the file will not be normalised. + * * If a ProgressReporter is provided, it will be updated with * progress status. This will only be meaningful if threading * mode is not used because the file reader in use does not @@ -76,11 +83,13 @@ */ static AudioFileReader *createThreadingReader(FileSource source, size_t targetRate = 0, + bool normalised = false, ProgressReporter *reporter = 0); protected: static AudioFileReader *create(FileSource source, size_t targetRate, + bool normalised, bool threading, ProgressReporter *reporter); }; diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/CodedAudioFileReader.cpp --- a/data/fileio/CodedAudioFileReader.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/CodedAudioFileReader.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -28,7 +28,8 @@ #include CodedAudioFileReader::CodedAudioFileReader(CacheMode cacheMode, - size_t targetRate) : + size_t targetRate, + bool normalised) : m_cacheMode(cacheMode), m_initialised(false), m_serialiser(0), @@ -40,9 +41,12 @@ m_cacheWriteBufferSize(16384), m_resampler(0), m_resampleBuffer(0), - m_fileFrameCount(0) + m_fileFrameCount(0), + m_normalised(normalised), + m_max(0.f), + m_gain(1.f) { - SVDEBUG << "CodedAudioFileReader::CodedAudioFileReader: rate " << targetRate << endl; + SVDEBUG << "CodedAudioFileReader::CodedAudioFileReader: rate " << targetRate << ", normalised = " << normalised << endl; m_frameCount = 0; m_sampleRate = targetRate; @@ -270,11 +274,9 @@ return; } -// if (m_cacheWriteBufferIndex > 0) { - pushBuffer(m_cacheWriteBuffer, - m_cacheWriteBufferIndex / m_channelCount, - true); -// } + pushBuffer(m_cacheWriteBuffer, + m_cacheWriteBufferIndex / m_channelCount, + true); delete[] m_cacheWriteBuffer; m_cacheWriteBuffer = 0; @@ -312,14 +314,24 @@ void CodedAudioFileReader::pushBufferNonResampling(float *buffer, size_t sz) { - float max = 1.0; + float clip = 1.0; size_t count = sz * m_channelCount; - for (size_t i = 0; i < count; ++i) { - if (buffer[i] > max) buffer[i] = max; - } - for (size_t i = 0; i < count; ++i) { - if (buffer[i] < -max) buffer[i] = -max; + if (m_normalised) { + for (size_t i = 0; i < count; ++i) { + float v = fabsf(buffer[i]); + if (v > m_max) { + m_max = v; + m_gain = 1.f / m_max; + } + } + } else { + for (size_t i = 0; i < count; ++i) { + if (buffer[i] > clip) buffer[i] = clip; + } + for (size_t i = 0; i < count; ++i) { + if (buffer[i] < -clip) buffer[i] = -clip; + } } m_frameCount += sz; @@ -432,5 +444,11 @@ m_dataLock.unlock(); } } + + if (m_normalised) { + for (int i = 0; i < (int)(count * m_channelCount); ++i) { + frames[i] *= m_gain; + } + } } diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/CodedAudioFileReader.h --- a/data/fileio/CodedAudioFileReader.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/CodedAudioFileReader.h Fri Jun 13 16:03:48 2014 +0100 @@ -50,7 +50,9 @@ void progress(int); protected: - CodedAudioFileReader(CacheMode cacheMode, size_t targetRate); + CodedAudioFileReader(CacheMode cacheMode, + size_t targetRate, + bool normalised); void initialiseDecodeCache(); // samplerate, channels must have been set @@ -91,6 +93,10 @@ Resampler *m_resampler; float *m_resampleBuffer; size_t m_fileFrameCount; + + bool m_normalised; + float m_max; + float m_gain; }; #endif diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/CoreAudioFileReader.cpp --- a/data/fileio/CoreAudioFileReader.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/CoreAudioFileReader.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -60,8 +60,9 @@ DecodeMode decodeMode, CacheMode mode, size_t targetRate, + bool normalised, ProgressReporter *reporter) : - CodedAudioFileReader(mode, targetRate), + CodedAudioFileReader(mode, targetRate, normalised), m_source(source), m_path(source.getLocalFilename()), m_d(new D), diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/CoreAudioFileReader.h --- a/data/fileio/CoreAudioFileReader.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/CoreAudioFileReader.h Fri Jun 13 16:03:48 2014 +0100 @@ -40,6 +40,7 @@ DecodeMode decodeMode, CacheMode cacheMode, size_t targetRate = 0, + bool normalised = false, ProgressReporter *reporter = 0); virtual ~CoreAudioFileReader(); diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/DecodingWavFileReader.cpp --- a/data/fileio/DecodingWavFileReader.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/DecodingWavFileReader.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -22,11 +22,12 @@ #include DecodingWavFileReader::DecodingWavFileReader(FileSource source, - ResampleMode resampleMode, - CacheMode mode, - size_t targetRate, - ProgressReporter *reporter) : - CodedAudioFileReader(mode, targetRate), + ResampleMode resampleMode, + CacheMode mode, + size_t targetRate, + bool normalised, + ProgressReporter *reporter) : + CodedAudioFileReader(mode, targetRate, normalised), m_source(source), m_path(source.getLocalFilename()), m_cancelled(false), diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/DecodingWavFileReader.h --- a/data/fileio/DecodingWavFileReader.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/DecodingWavFileReader.h Fri Jun 13 16:03:48 2014 +0100 @@ -35,10 +35,11 @@ }; DecodingWavFileReader(FileSource source, - ResampleMode resampleMode, - CacheMode cacheMode, - size_t targetRate = 0, - ProgressReporter *reporter = 0); + ResampleMode resampleMode, + CacheMode cacheMode, + size_t targetRate = 0, + bool normalised = false, + ProgressReporter *reporter = 0); virtual ~DecodingWavFileReader(); virtual QString getError() const { return m_error; } diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/MP3FileReader.cpp --- a/data/fileio/MP3FileReader.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/MP3FileReader.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -38,8 +38,9 @@ MP3FileReader::MP3FileReader(FileSource source, DecodeMode decodeMode, CacheMode mode, size_t targetRate, + bool normalised, ProgressReporter *reporter) : - CodedAudioFileReader(mode, targetRate), + CodedAudioFileReader(mode, targetRate, normalised), m_source(source), m_path(source.getLocalFilename()), m_decodeThread(0) diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/MP3FileReader.h --- a/data/fileio/MP3FileReader.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/MP3FileReader.h Fri Jun 13 16:03:48 2014 +0100 @@ -41,6 +41,7 @@ DecodeMode decodeMode, CacheMode cacheMode, size_t targetRate = 0, + bool normalised = false, ProgressReporter *reporter = 0); virtual ~MP3FileReader(); diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/OggVorbisFileReader.cpp --- a/data/fileio/OggVorbisFileReader.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/OggVorbisFileReader.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -35,8 +35,9 @@ DecodeMode decodeMode, CacheMode mode, size_t targetRate, + bool normalised, ProgressReporter *reporter) : - CodedAudioFileReader(mode, targetRate), + CodedAudioFileReader(mode, targetRate, normalised), m_source(source), m_path(source.getLocalFilename()), m_reporter(reporter), diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/OggVorbisFileReader.h --- a/data/fileio/OggVorbisFileReader.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/OggVorbisFileReader.h Fri Jun 13 16:03:48 2014 +0100 @@ -43,6 +43,7 @@ DecodeMode decodeMode, CacheMode cacheMode, size_t targetRate = 0, + bool normalised = false, ProgressReporter *reporter = 0); virtual ~OggVorbisFileReader(); diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/QuickTimeFileReader.cpp --- a/data/fileio/QuickTimeFileReader.cpp Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/QuickTimeFileReader.cpp Fri Jun 13 16:03:48 2014 +0100 @@ -51,8 +51,9 @@ DecodeMode decodeMode, CacheMode mode, size_t targetRate, + bool normalised, ProgressReporter *reporter) : - CodedAudioFileReader(mode, targetRate), + CodedAudioFileReader(mode, targetRate, normalised), m_source(source), m_path(source.getLocalFilename()), m_d(new D), diff -r 4c7b4040bd2d -r f3cda3280398 data/fileio/QuickTimeFileReader.h --- a/data/fileio/QuickTimeFileReader.h Fri Jun 13 12:56:31 2014 +0100 +++ b/data/fileio/QuickTimeFileReader.h Fri Jun 13 16:03:48 2014 +0100 @@ -43,6 +43,7 @@ DecodeMode decodeMode, CacheMode cacheMode, size_t targetRate = 0, + bool normalised = false, ProgressReporter *reporter = 0); virtual ~QuickTimeFileReader();