changeset 1041:843f67be0ed9 cxx11

Replace the get*Frames calls in AudioFileReader with less stupid API
author Chris Cannam
date Wed, 04 Mar 2015 12:30:41 +0000
parents a1cd5abcb38b
children 16dc7307d43a
files data/fileio/AudioFileReader.cpp data/fileio/AudioFileReader.h data/fileio/CodedAudioFileReader.cpp data/fileio/CodedAudioFileReader.h data/fileio/DecodingWavFileReader.cpp data/fileio/WavFileReader.cpp data/fileio/WavFileReader.h data/fileio/test/AudioFileReaderTest.h data/model/WaveFileModel.cpp
diffstat 9 files changed, 50 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/AudioFileReader.cpp	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/AudioFileReader.cpp	Wed Mar 04 12:30:41 2015 +0000
@@ -15,26 +15,24 @@
 
 #include "AudioFileReader.h"
 
-void
-AudioFileReader::getDeInterleavedFrames(sv_frame_t start, sv_frame_t count,
-                                        std::vector<SampleBlock> &frames) const
+using std::vector;
+
+vector<SampleBlock>
+AudioFileReader::getDeInterleavedFrames(sv_frame_t start, sv_frame_t count) const
 {
-    SampleBlock interleaved;
-    getInterleavedFrames(start, count, interleaved);
+    SampleBlock interleaved = getInterleavedFrames(start, count);
     
     int channels = getChannelCount();
     sv_frame_t rc = interleaved.size() / channels;
 
-    frames.clear();
-
+    vector<SampleBlock> frames(channels, SampleBlock(rc, 0.f));
+    
     for (int c = 0; c < channels; ++c) {
-        frames.push_back(SampleBlock());
+        for (sv_frame_t i = 0; i < rc; ++i) {
+            frames[c][i] = interleaved[i * channels + c];
+        }
     }
 
-    for (sv_frame_t i = 0; i < rc; ++i) {
-        for (int c = 0; c < channels; ++c) {
-            frames[c].push_back(interleaved[i * channels + c]);
-        }
-    }
+    return frames;
 }
 
--- a/data/fileio/AudioFileReader.h	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/AudioFileReader.h	Wed Mar 04 12:30:41 2015 +0000
@@ -94,8 +94,7 @@
      * thread-safe -- that is, safe to call from multiple threads with
      * different arguments on the same object at the same time.
      */
-    virtual void getInterleavedFrames(sv_frame_t start, sv_frame_t count,
-				      SampleBlock &frames) const = 0;
+    virtual SampleBlock getInterleavedFrames(sv_frame_t start, sv_frame_t count) const = 0;
 
     /**
      * Return de-interleaved samples for count frames from index
@@ -104,8 +103,7 @@
      * will contain getChannelCount() sample blocks of count samples
      * each (or fewer if end of file is reached).
      */
-    virtual void getDeInterleavedFrames(sv_frame_t start, sv_frame_t count,
-                                        std::vector<SampleBlock> &frames) const;
+    virtual std::vector<SampleBlock> getDeInterleavedFrames(sv_frame_t start, sv_frame_t count) const;
 
     // only subclasses that do not know exactly how long the audio
     // file is until it's been completely decoded should implement this
--- a/data/fileio/CodedAudioFileReader.cpp	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/CodedAudioFileReader.cpp	Wed Mar 04 12:30:41 2015 +0000
@@ -355,7 +355,6 @@
         for (sv_frame_t s = 0; s < count; ++s) {
             m_data.push_back(buffer[s]);
         }
-	MUNLOCK_SAMPLEBLOCK(m_data);
         m_dataLock.unlock();
         break;
     }
@@ -409,9 +408,8 @@
     }
 }
 
-void
-CodedAudioFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count,
-                                           SampleBlock &frames) const
+SampleBlock
+CodedAudioFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const
 {
     // Lock is only required in CacheInMemory mode (the cache file
     // reader is expected to be thread safe and manage its own
@@ -419,31 +417,32 @@
 
     if (!m_initialised) {
         SVDEBUG << "CodedAudioFileReader::getInterleavedFrames: not initialised" << endl;
-        return;
+        return SampleBlock();
     }
 
+    SampleBlock frames;
+    
     switch (m_cacheMode) {
 
     case CacheInTemporaryFile:
         if (m_cacheFileReader) {
-            m_cacheFileReader->getInterleavedFrames(start, count, frames);
+            frames = m_cacheFileReader->getInterleavedFrames(start, count);
         }
         break;
 
     case CacheInMemory:
     {
-        frames.clear();
-        if (!isOK()) return;
-        if (count == 0) return;
-        frames.reserve(count * m_channelCount);
+        if (!isOK()) return SampleBlock();
+        if (count == 0) return SampleBlock();
 
         sv_frame_t idx = start * m_channelCount;
         sv_frame_t i = 0;
+        sv_frame_t n = count * m_channelCount;
 
         m_dataLock.lockForRead();
-        while (i < count * m_channelCount && idx < (sv_frame_t)m_data.size()) {
-            frames.push_back(m_data[idx]);
-            ++idx;
+        while (i < n && in_range_for(m_data, idx)) {
+            frames.push_back(m_data[idx++]);
+            ++i;
         }
         m_dataLock.unlock();
     }
@@ -454,5 +453,7 @@
             frames[i] *= m_gain;
         }
     }
+
+    return frames;
 }
 
--- a/data/fileio/CodedAudioFileReader.h	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/CodedAudioFileReader.h	Wed Mar 04 12:30:41 2015 +0000
@@ -38,8 +38,7 @@
         CacheInMemory
     };
 
-    virtual void getInterleavedFrames(sv_frame_t start, sv_frame_t count,
-				      SampleBlock &frames) const;
+    virtual SampleBlock getInterleavedFrames(sv_frame_t start, sv_frame_t count) const;
 
     virtual sv_samplerate_t getNativeRate() const { return m_fileRate; }
 
--- a/data/fileio/DecodingWavFileReader.cpp	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/DecodingWavFileReader.cpp	Wed Mar 04 12:30:41 2015 +0000
@@ -74,7 +74,7 @@
             sv_frame_t count = blockSize;
             if (i + count > total) count = total - i;
 
-            m_original->getInterleavedFrames(i, count, block);
+            block = m_original->getInterleavedFrames(i, count);
             addBlock(block);
 
             if (m_cancelled) break;
@@ -131,7 +131,7 @@
         sv_frame_t count = blockSize;
         if (i + count > total) count = total - i;
         
-        m_reader->m_original->getInterleavedFrames(i, count, block);
+        block = m_reader->m_original->getInterleavedFrames(i, count);
         m_reader->addBlock(block);
 
         if (m_reader->m_cancelled) break;
--- a/data/fileio/WavFileReader.cpp	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/WavFileReader.cpp	Wed Mar 04 12:30:41 2015 +0000
@@ -25,8 +25,6 @@
     m_source(source),
     m_path(source.getLocalFilename()),
     m_seekable(false),
-    m_buffer(0),
-    m_bufsiz(0),
     m_lastStart(0),
     m_lastCount(0),
     m_updating(fileUpdating)
@@ -81,7 +79,6 @@
 WavFileReader::~WavFileReader()
 {
     if (m_file) sf_close(m_file);
-    delete[] m_buffer;
 }
 
 void
@@ -122,24 +119,21 @@
     m_updating = false;
 }
 
-void
-WavFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count,
-				    SampleBlock &results) const
+SampleBlock
+WavFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const
 {
-    if (count == 0) return;
-    results.clear();
-    results.reserve(count * m_fileInfo.channels);
+    if (count == 0) return SampleBlock();
 
     QMutexLocker locker(&m_mutex);
 
     if (!m_file || !m_channelCount) {
-        return;
+        return SampleBlock();
     }
 
     if (start >= m_fileInfo.frames) {
 //        SVDEBUG << "WavFileReader::getInterleavedFrames: " << start
 //                  << " > " << m_fileInfo.frames << endl;
-	return;
+	return SampleBlock();
     }
 
     if (start + count > m_fileInfo.frames) {
@@ -151,36 +145,21 @@
     if (start != m_lastStart || count != m_lastCount) {
 
 	if (sf_seek(m_file, start, SEEK_SET) < 0) {
-//            cerr << "sf_seek failed" << endl;
-	    return;
+	    return SampleBlock();
 	}
+
+        sv_frame_t n = count * m_fileInfo.channels;
+        m_buffer.resize(n);
 	
-	if (count * m_fileInfo.channels > m_bufsiz) {
-//	    cerr << "WavFileReader: Reallocating buffer for " << count
-//		      << " frames, " << m_fileInfo.channels << " channels: "
-//		      << m_bufsiz << " floats" << endl;
-	    m_bufsiz = count * m_fileInfo.channels;
-	    delete[] m_buffer;
-	    m_buffer = new float[m_bufsiz];
-	}
-	
-	if ((readCount = sf_readf_float(m_file, m_buffer, count)) < 0) {
-//            cerr << "sf_readf_float failed" << endl;
-	    return;
+	if ((readCount = sf_readf_float(m_file, m_buffer.data(), count)) < 0) {
+	    return SampleBlock();
 	}
 
 	m_lastStart = start;
 	m_lastCount = readCount;
     }
 
-    for (sv_frame_t i = 0; i < count * m_fileInfo.channels; ++i) {
-        if (i >= m_bufsiz) {
-            cerr << "INTERNAL ERROR: WavFileReader::getInterleavedFrames: " << i << " >= " << m_bufsiz << endl;
-        }
-	results.push_back(m_buffer[i]);
-    }
-
-    return;
+    return m_buffer;
 }
 
 void
--- a/data/fileio/WavFileReader.h	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/WavFileReader.h	Wed Mar 04 12:30:41 2015 +0000
@@ -50,8 +50,7 @@
      * Must be safe to call from multiple threads with different
      * arguments on the same object at the same time.
      */
-    virtual void getInterleavedFrames(sv_frame_t start, sv_frame_t count,
-				      SampleBlock &frames) const;
+    virtual SampleBlock getInterleavedFrames(sv_frame_t start, sv_frame_t count) const;
     
     static void getSupportedExtensions(std::set<QString> &extensions);
     static bool supportsExtension(QString ext);
@@ -76,7 +75,7 @@
     bool m_seekable;
 
     mutable QMutex m_mutex;
-    mutable float *m_buffer;
+    mutable SampleBlock m_buffer;
     mutable sv_frame_t m_bufsiz;
     mutable sv_frame_t m_lastStart;
     mutable sv_frame_t m_lastCount;
--- a/data/fileio/test/AudioFileReaderTest.h	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/fileio/test/AudioFileReaderTest.h	Wed Mar 04 12:30:41 2015 +0000
@@ -95,14 +95,12 @@
 	float *reference = tdata.getInterleavedData();
         sv_frame_t refFrames = tdata.getFrameCount();
 	
-	vector<float> test;
-	
 	// The reader should give us exactly the expected number of
 	// frames, except for mp3/aac files. We ask for quite a lot
 	// more, though, so we can (a) check that we only get the
 	// expected number back (if this is not mp3/aac) or (b) take
 	// into account silence at beginning and end (if it is).
-	reader->getInterleavedFrames(0, refFrames + 5000, test);
+	vector<float> test = reader->getInterleavedFrames(0, refFrames + 5000);
 	sv_frame_t read = test.size() / channels;
 
         if (extension == "mp3" || extension == "aac" || extension == "m4a") {
--- a/data/model/WaveFileModel.cpp	Wed Mar 04 12:01:04 2015 +0000
+++ b/data/model/WaveFileModel.cpp	Wed Mar 04 12:30:41 2015 +0000
@@ -229,8 +229,7 @@
 
     int channels = getChannelCount();
 
-    SampleBlock frames(count * channels);
-    m_reader->getInterleavedFrames(start, count, frames);
+    SampleBlock frames = m_reader->getInterleavedFrames(start, count);
 
     sv_frame_t i = 0;
 
@@ -286,8 +285,7 @@
 
     int channels = getChannelCount();
 
-    SampleBlock frames(count * channels);
-    m_reader->getInterleavedFrames(start, count, frames);
+    SampleBlock frames = m_reader->getInterleavedFrames(start, count);
 
     sv_frame_t i = 0;
 
@@ -372,8 +370,7 @@
         return 0;
     }
 
-    SampleBlock frames(count * channels);
-    m_reader->getInterleavedFrames(start, count, frames);
+    SampleBlock frames = m_reader->getInterleavedFrames(start, count);
 
     sv_frame_t i = 0;
 
@@ -455,7 +452,7 @@
             m_lastDirectReadCount != count ||
             m_directRead.empty()) {
 
-            m_reader->getInterleavedFrames(start, count, m_directRead);
+            m_directRead = m_reader->getInterleavedFrames(start, count);
             m_lastDirectReadStart = start;
             m_lastDirectReadCount = count;
         }
@@ -709,7 +706,7 @@
 
             if (updating && (frame + readBlockSize > m_frameCount)) break;
 
-            m_model.m_reader->getInterleavedFrames(frame, readBlockSize, block);
+            block = m_model.m_reader->getInterleavedFrames(frame, readBlockSize);
 
 //            cerr << "block is " << block.size() << endl;