changeset 920:f3cda3280398 tonioni

Add normalised option to CodedAudioFileReader
author Chris Cannam
date Fri, 13 Jun 2014 16:03:48 +0100
parents 4c7b4040bd2d
children 2896b8872834
files data/fileio/AudioFileReaderFactory.cpp data/fileio/AudioFileReaderFactory.h data/fileio/CodedAudioFileReader.cpp data/fileio/CodedAudioFileReader.h data/fileio/CoreAudioFileReader.cpp data/fileio/CoreAudioFileReader.h data/fileio/DecodingWavFileReader.cpp data/fileio/DecodingWavFileReader.h data/fileio/MP3FileReader.cpp data/fileio/MP3FileReader.h data/fileio/OggVorbisFileReader.cpp data/fileio/OggVorbisFileReader.h data/fileio/QuickTimeFileReader.cpp data/fileio/QuickTimeFileReader.h
diffstat 14 files changed, 93 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- 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);
         }
 
--- 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);
 };
--- 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 <QMutexLocker>
 
 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;
+        }
+    }
 }
 
--- 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
--- 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),
--- 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();
 
--- 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 <QFileInfo>
 
 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),
--- 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; }
--- 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)
--- 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();
 
--- 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),
--- 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();
 
--- 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),
--- 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();