diff data/model/WaveFileModel.cpp @ 1100:5cbf71022679 simple-fft-model

Smooth signal flow through from file to fft model
author Chris Cannam
date Mon, 15 Jun 2015 16:02:58 +0100
parents 4d9816ba0ebe
children efea94b04d5a
line wrap: on
line diff
--- a/data/model/WaveFileModel.cpp	Mon Jun 15 15:35:57 2015 +0100
+++ b/data/model/WaveFileModel.cpp	Mon Jun 15 16:02:58 2015 +0100
@@ -189,35 +189,55 @@
 vector<float>
 WaveFileModel::getData(int channel, sv_frame_t start, sv_frame_t count) const
 {
-    // Always read these directly from the file. 
-    // This is used for e.g. audio playback or input to transforms.
+    // Read directly from the file.  This is used for e.g. audio
+    // playback or input to transforms.
 
 #ifdef DEBUG_WAVE_FILE_MODEL
     cout << "WaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl;
 #endif
 
+    int channels = getChannelCount();
+
+    if (channel >= channels) {
+        cerr << "ERROR: WaveFileModel::getData: channel ("
+             << channel << ") >= channel count (" << channels << ")"
+             << endl;
+        return {};
+    }
+
     if (!m_reader || !m_reader->isOK() || count == 0) {
         return {};
     }
 
+    if (start >= m_startFrame) {
+        start -= m_startFrame;
+    } else {
+        if (count <= m_startFrame - start) {
+            return {};
+        } else {
+            count -= (m_startFrame - start);
+            start = 0;
+        }
+    }
+
+    vector<float> interleaved = m_reader->getInterleavedFrames(start, count);
+    if (channels == 1) return interleaved;
+
+    sv_frame_t obtained = interleaved.size() / channels;
+    
+    vector<float> result(obtained, 0.f);
+    
     if (channel != -1) {
         // get a single channel
-        auto data = getMultiChannelData(channel, channel, start, count);
-        if (data.empty()) return {};
-        else return data[0];
-    }
-
-    // channel == -1, mix down all channels
-
-    auto all = getMultiChannelData(0, getChannelCount()-1, start, count);
-    if (all.empty()) return {};
-
-    sv_frame_t n = all[0].size();
-    vector<float> result(n, 0.f);
-
-    for (int c = 0; in_range_for(all, c); ++c) {
-        for (sv_frame_t i = 0; i < n; ++i) {
-            result[i] += all[c][i];
+        for (int i = 0; i < obtained; ++i) {
+            result[i] = interleaved[i * channels + channel];
+        }
+    } else {
+        // channel == -1, mix down all channels
+        for (int c = 0; c < channels; ++c) {
+            for (int i = 0; i < obtained; ++i) {
+                result[i] += interleaved[i * channels + c];
+            }
         }
     }
 
@@ -228,6 +248,9 @@
 WaveFileModel::getMultiChannelData(int fromchannel, int tochannel,
                                    sv_frame_t start, sv_frame_t count) const
 {
+    // Read directly from the file.  This is used for e.g. audio
+    // playback or input to transforms.
+
 #ifdef DEBUG_WAVE_FILE_MODEL
     cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl;
 #endif