changeset 1161:5b463c7727e5

Use float format for cached files in CodedAudioFileReader, to preserve internal representation (see comment)
author Chris Cannam
date Wed, 24 Feb 2016 10:28:47 +0000
parents d9c766274c8b
children 1dd98a5432cf
files data/fileio/AudioFileReaderFactory.cpp data/fileio/CodedAudioFileReader.cpp data/fileio/WavFileReader.cpp
diffstat 3 files changed, 38 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/AudioFileReaderFactory.cpp	Sat Jan 30 12:08:50 2016 +0000
+++ b/data/fileio/AudioFileReaderFactory.cpp	Wed Feb 24 10:28:47 2016 +0000
@@ -26,6 +26,8 @@
 #include <QFileInfo>
 #include <iostream>
 
+//#define DEBUG_AUDIO_FILE_READER_FACTORY 1
+
 QString
 AudioFileReaderFactory::getKnownExtensions()
 {
@@ -84,7 +86,9 @@
 {
     QString err;
 
-    SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl;
+#ifdef DEBUG_AUDIO_FILE_READER_FACTORY
+    cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl;
+#endif
 
     if (!source.isOK()) {
         cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Failed to retrieve source (transmission error?): " << source.getErrorString() << endl;
@@ -92,7 +96,7 @@
     }
 
     if (!source.isAvailable()) {
-        SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl;
+        cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl;
         return 0;
     }
 
@@ -112,8 +116,10 @@
              normalised ||
              (targetRate != 0 && fileRate != targetRate))) {
 
-            SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl;
-
+#ifdef DEBUG_AUDIO_FILE_READER_FACTORY
+            cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl;
+#endif
+            
             delete reader;
             reader = new DecodingWavFileReader
                 (source,
@@ -231,7 +237,9 @@
              normalised ||
              (targetRate != 0 && fileRate != targetRate))) {
 
-            SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl;
+#ifdef DEBUG_AUDIO_FILE_READER_FACTORY
+            cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl;
+#endif
 
             delete reader;
             reader = new DecodingWavFileReader
@@ -327,7 +335,9 @@
 
     if (reader) {
         if (reader->isOK()) {
-            SVDEBUG << "AudioFileReaderFactory: Reader is OK" << endl;
+#ifdef DEBUG_AUDIO_FILE_READER_FACTORY
+            cerr << "AudioFileReaderFactory: Reader is OK" << endl;
+#endif
             return reader;
         }
         cerr << "AudioFileReaderFactory: Preferred reader for "
--- a/data/fileio/CodedAudioFileReader.cpp	Sat Jan 30 12:08:50 2016 +0000
+++ b/data/fileio/CodedAudioFileReader.cpp	Wed Feb 24 10:28:47 2016 +0000
@@ -137,11 +137,27 @@
             }
             fileInfo.samplerate = fileRate;
             fileInfo.channels = m_channelCount;
-            
-            // No point in writing 24-bit or float; generally this
-            // class is used for decoding files that have come from a
-            // 16 bit source or that decode to only 16 bits anyway.
-            fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+
+            // Previously we were writing SF_FORMAT_PCM_16 and in a
+            // comment I wrote: "No point in writing 24-bit or float;
+            // generally this class is used for decoding files that
+            // have come from a 16 bit source or that decode to only
+            // 16 bits anyway." That was naive -- we want to preserve
+            // the original values to the same float precision that we
+            // use internally. Saving PCM_16 obviously doesn't
+            // preserve values for sources at bit depths greater than
+            // 16, but it also doesn't always do so for sources at bit
+            // depths less than 16.
+            //
+            // (This came to light with a bug in libsndfile 1.0.26,
+            // which always reports every file as non-seekable, so
+            // that coded readers were being used even for WAV
+            // files. This changed the values that came from PCM_8 WAV
+            // sources, breaking Sonic Annotator's output comparison
+            // tests.)
+            //
+            // So: now we write floats.
+            fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
     
             m_cacheFileWritePtr = sf_open(m_cacheFileName.toLocal8Bit(),
                                           SFM_WRITE, &fileInfo);
--- a/data/fileio/WavFileReader.cpp	Sat Jan 30 12:08:50 2016 +0000
+++ b/data/fileio/WavFileReader.cpp	Wed Feb 24 10:28:47 2016 +0000
@@ -72,7 +72,7 @@
         }
     }
 
-//    cerr << "WavFileReader: Frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", seekable " << m_seekable << endl;
+//    cerr << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_seekable << endl;
 
 }