changeset 1094:b386363ff6c8 simple-fft-model

A small cache for source samples
author Chris Cannam
date Fri, 12 Jun 2015 19:18:56 +0100
parents 44b079427b36
children b66734b5f806
files data/model/FFTModel.cpp data/model/FFTModel.h
diffstat 2 files changed, 61 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/data/model/FFTModel.cpp	Fri Jun 12 18:50:52 2015 +0100
+++ b/data/model/FFTModel.cpp	Fri Jun 12 19:18:56 2015 +0100
@@ -196,27 +196,76 @@
 vector<float>
 FFTModel::getSourceSamples(int column) const
 {
+    // m_fftSize may be greater than m_windowSize, but not the reverse
+
+//    cerr << "getSourceSamples(" << column << ")" << endl;
+    
     auto range = getSourceSampleRange(column);
-    vector<float> samples(m_fftSize, 0.f);
+    auto data = getSourceData(range);
+
     int off = (m_fftSize - m_windowSize) / 2;
+
+    if (off == 0) {
+        return data;
+    } else {
+        vector<float> pad(off, 0.f);
+        vector<float> padded;
+        padded.reserve(m_fftSize);
+        padded.insert(padded.end(), pad.begin(), pad.end());
+        padded.insert(padded.end(), data.begin(), data.end());
+        padded.insert(padded.end(), pad.begin(), pad.end());
+        return padded;
+    }
+}
+
+vector<float>
+FFTModel::getSourceData(pair<sv_frame_t, sv_frame_t> range) const
+{
+//    cerr << "getSourceData(" << range.first << "," << range.second
+//         << "): saved range is (" << m_savedData.range.first
+//         << "," << m_savedData.range.second << ")" << endl;
+
+    if (m_savedData.range == range) return m_savedData.data;
+
+    if (range.first < m_savedData.range.second &&
+        range.first >= m_savedData.range.first &&
+        range.second > m_savedData.range.second) {
+
+        //!!! Need FFTModel overlap tests to exercise this
+        
+        sv_frame_t off = range.first - m_savedData.range.first;
+                
+        vector<float> partial(m_savedData.data.begin() + off, m_savedData.data.end());
+
+        vector<float> rest = getSourceData({ m_savedData.range.second, range.second });
+        
+        partial.insert(partial.end(), rest.begin(), rest.end());
+        return partial;
+    }
+
+    vector<float> data(range.second - range.first, 0.f);
     decltype(range.first) pfx = 0;
     if (range.first < 0) {
         pfx = -range.first;
         range = { 0, range.second };
     }
+//    cerr << "requesting " << range.second - range.first << " from file" << endl;
     (void) m_model->getData(m_channel,
                             range.first,
                             range.second - range.first,
-                            &samples[off + pfx]);
+                            &data[pfx]);
     if (m_channel == -1) {
 	int channels = m_model->getChannelCount();
 	if (channels > 1) {
-	    for (int i = 0; i < range.second - range.first; ++i) {
-		samples[off + pfx + i] /= float(channels);
+	    for (int i = 0; in_range_for(data, i); ++i) {
+		data[i] /= float(channels);
 	    }
 	}
     }
-    return samples;
+
+    m_savedData = { range, data };
+    
+    return data;
 }
 
 vector<complex<float>>
--- a/data/model/FFTModel.h	Fri Jun 12 18:50:52 2015 +0100
+++ b/data/model/FFTModel.h	Fri Jun 12 19:18:56 2015 +0100
@@ -168,12 +168,18 @@
 
     std::vector<std::complex<float> > getFFTColumn(int column) const;
     std::vector<float> getSourceSamples(int column) const;
+    std::vector<float> getSourceData(std::pair<sv_frame_t, sv_frame_t>) const;
 
+    struct SavedSourceData {
+        std::pair<sv_frame_t, sv_frame_t> range;
+        std::vector<float> data;
+    };
+    mutable SavedSourceData m_savedData;
+    
     struct SavedColumn {
         int n;
         std::vector<std::complex<float> > col;
     };
-    
     mutable std::deque<SavedColumn> m_cached;
     size_t m_cacheSize;