diff data/model/FFTModel.h @ 1090:420fc961c0c4 simple-fft-model

Gut the old code, but don't replace it yet (so nothing will link yet)
author Chris Cannam
date Fri, 12 Jun 2015 14:51:46 +0100
parents 9f4505ac9072
children bdebff3265ae
line wrap: on
line diff
--- a/data/model/FFTModel.h	Fri Jun 12 13:46:44 2015 +0100
+++ b/data/model/FFTModel.h	Fri Jun 12 14:51:46 2015 +0100
@@ -16,8 +16,10 @@
 #ifndef FFT_MODEL_H
 #define FFT_MODEL_H
 
-#include "data/fft/FFTDataServer.h"
 #include "DenseThreeDimensionalModel.h"
+#include "DenseTimeValueModel.h"
+
+#include "base/Window.h"
 
 #include <set>
 #include <map>
@@ -25,11 +27,8 @@
 /**
  * An implementation of DenseThreeDimensionalModel that makes FFT data
  * derived from a DenseTimeValueModel available as a generic data
- * grid.  The FFT data is acquired using FFTDataServer.  Note that any
- * of the accessor functions may throw AllocationFailed if a cache
- * resize fails.
+ * grid.
  */
-
 class FFTModel : public DenseThreeDimensionalModel
 {
     Q_OBJECT
@@ -43,111 +42,61 @@
      * If the model has multiple channels use only the given channel,
      * unless the channel is -1 in which case merge all available
      * channels.
-     * 
-     * If polar is true, the data will normally be retrieved from the
-     * FFT model in magnitude/phase form; otherwise it will normally
-     * be retrieved in "cartesian" real/imaginary form.  The results
-     * should be the same either way, but a "polar" model addressed in
-     * "cartesian" form or vice versa may suffer a performance
-     * penalty.
-     *
-     * The fillFromColumn argument gives a hint that the FFT data
-     * server should aim to start calculating FFT data at that column
-     * number if possible, as that is likely to be requested first.
      */
     FFTModel(const DenseTimeValueModel *model,
              int channel,
              WindowType windowType,
              int windowSize,
              int windowIncrement,
-             int fftSize,
-             bool polar,
-             StorageAdviser::Criteria criteria = StorageAdviser::NoCriteria,
-             sv_frame_t fillFromFrame = 0);
+             int fftSize);
     ~FFTModel();
 
-    inline float getMagnitudeAt(int x, int y) {
-        return m_server->getMagnitudeAt(x << m_xshift, y << m_yshift);
-    }
-    inline float getNormalizedMagnitudeAt(int x, int y) {
-        return m_server->getNormalizedMagnitudeAt(x << m_xshift, y << m_yshift);
-    }
-    inline float getMaximumMagnitudeAt(int x) {
-        return m_server->getMaximumMagnitudeAt(x << m_xshift);
-    }
-    inline float getPhaseAt(int x, int y) {
-        return m_server->getPhaseAt(x << m_xshift, y << m_yshift);
-    }
-    inline void getValuesAt(int x, int y, float &real, float &imaginary) {
-        m_server->getValuesAt(x << m_xshift, y << m_yshift, real, imaginary);
-    }
-    inline bool isColumnAvailable(int x) const {
-        return m_server->isColumnReady(x << m_xshift);
-    }
-
-    inline bool getMagnitudesAt(int x, float *values, int minbin = 0, int count = 0) {
-        return m_server->getMagnitudesAt(x << m_xshift, values, minbin << m_yshift, count, getYRatio());
-    }
-    inline bool getNormalizedMagnitudesAt(int x, float *values, int minbin = 0, int count = 0) {
-        return m_server->getNormalizedMagnitudesAt(x << m_xshift, values, minbin << m_yshift, count, getYRatio());
-    }
-    inline bool getPhasesAt(int x, float *values, int minbin = 0, int count = 0) {
-        return m_server->getPhasesAt(x << m_xshift, values, minbin << m_yshift, count, getYRatio());
-    }
-    inline bool getValuesAt(int x, float *reals, float *imaginaries, int minbin = 0, int count = 0) {
-        return m_server->getValuesAt(x << m_xshift, reals, imaginaries, minbin << m_yshift, count, getYRatio());
-    }
-
-    inline sv_frame_t getFillExtent() const { return m_server->getFillExtent(); }
-
     // DenseThreeDimensionalModel and Model methods:
     //
-    inline virtual int getWidth() const {
-        return m_server->getWidth() >> m_xshift;
-    }
-    inline virtual int getHeight() const {
-        // If there is no y-shift, the server's height (based on its
-        // fftsize/2 + 1) is correct.  If there is a shift, then the
-        // server is using a larger fft size than we want, so we shift
-        // it right as many times as necessary, but then we need to
-        // re-add the "+1" part (because ((fftsize*2)/2 + 1) / 2 !=
-        // fftsize/2 + 1).
-        return (m_server->getHeight() >> m_yshift) + (m_yshift > 0 ? 1 : 0);
-    }
-    virtual float getValueAt(int x, int y) const {
-        return const_cast<FFTModel *>(this)->getMagnitudeAt(x, y);
-    }
-    virtual bool isOK() const {
-        // Return true if the model was constructed successfully (not
-        // necessarily whether an error has occurred since
-        // construction, use getError for that)
-        return m_server && m_server->getModel();
-    }
-    virtual sv_frame_t getStartFrame() const {
-        return 0;
-    }
+    virtual int getWidth() const;
+    virtual int getHeight() const;
+    virtual float getValueAt(int x, int y) const { return getMagnitudeAt(x, y); }
+    virtual bool isOK() const { return m_model && m_model->isOK(); }
+    virtual sv_frame_t getStartFrame() const { return 0; }
     virtual sv_frame_t getEndFrame() const {
         return sv_frame_t(getWidth()) * getResolution() + getResolution();
     }
-    virtual sv_samplerate_t getSampleRate() const;
-    virtual int getResolution() const {
-        return m_server->getWindowIncrement() << m_xshift;
+    virtual sv_samplerate_t getSampleRate() const {
+        return isOK() ? m_model->getSampleRate() : 0;
     }
-    virtual int getYBinCount() const {
-        return getHeight();
+    virtual int getResolution() const { return m_windowIncrement; }
+    virtual int getYBinCount() const { return getHeight(); }
+    virtual float getMinimumLevel() const { return 0.f; } // Can't provide
+    virtual float getMaximumLevel() const { return 1.f; } // Can't provide
+    virtual Column getColumn(int x) const; // magnitudes
+    virtual QString getBinName(int n) const;
+    virtual bool shouldUseLogValueScale() const { return true; }
+    virtual int getCompletion() const {
+        int c = 100;
+        if (m_model) (void)m_model->isReady(&c);
+        return c;
     }
-    virtual float getMinimumLevel() const {
-        return 0.f; // Can't provide
-    }
-    virtual float getMaximumLevel() const {
-        return 1.f; // Can't provide
-    }
-    virtual Column getColumn(int x) const;
-    virtual QString getBinName(int n) const;
+    virtual QString getError() const { return ""; } //!!!???
+    virtual sv_frame_t getFillExtent() const { return getEndFrame(); }
 
-    virtual bool shouldUseLogValueScale() const {
-        return true; // Although obviously it's up to the user...
-    }
+    // FFTModel methods:
+    //
+    int getChannel() const { return m_channel; }
+    WindowType getWindowType() const { return m_windowType; }
+    int getWindowSize() const { return m_windowSize; }
+    int getWindowIncrement() const { return m_windowIncrement; }
+    int getFFTSize() const { return m_fftSize; }
+    
+    float getMagnitudeAt(int x, int y) const;
+    float getNormalizedMagnitudeAt(int x, int y) const;
+    float getMaximumMagnitudeAt(int x) const;
+    float getPhaseAt(int x, int y) const;
+    void getValuesAt(int x, int y, float &real, float &imaginary) const;
+    bool isColumnAvailable(int x) const;
+    bool getMagnitudesAt(int x, float *values, int minbin = 0, int count = 0) const;
+    bool getNormalizedMagnitudesAt(int x, float *values, int minbin = 0, int count = 0) const;
+    bool getPhasesAt(int x, float *values, int minbin = 0, int count = 0) const;
+    bool getValuesAt(int x, float *reals, float *imaginaries, int minbin = 0, int count = 0) const;
 
     /**
      * Calculate an estimated frequency for a stable signal in this
@@ -179,13 +128,6 @@
     virtual PeakSet getPeakFrequencies(PeakPickType type, int x,
                                        int ymin = 0, int ymax = 0);
 
-    virtual int getCompletion() const { return m_server->getFillCompletion(); }
-    virtual QString getError() const { return m_server->getError(); }
-
-    virtual void suspend() { m_server->suspend(); }
-    virtual void suspendWrites() { m_server->suspendWrites(); }
-    virtual void resume() { m_server->resume(); }
-
     QString getTypeName() const { return tr("FFT"); }
 
 public slots:
@@ -195,23 +137,16 @@
     FFTModel(const FFTModel &); // not implemented
     FFTModel &operator=(const FFTModel &); // not implemented
 
-    FFTDataServer *m_server;
-    int m_xshift;
-    int m_yshift;
-
-    FFTDataServer *getServer(const DenseTimeValueModel *,
-                             int, WindowType, int, int, int,
-                             bool, StorageAdviser::Criteria, sv_frame_t);
-
+    const DenseTimeValueModel *m_model;
+    int m_channel;
+    WindowType m_windowType;
+    int m_windowSize;
+    int m_windowIncrement;
+    int m_fftSize;
+    Window<float> m_windower;
+    
     int getPeakPickWindowSize(PeakPickType type, sv_samplerate_t sampleRate,
                               int bin, float &percentile) const;
-
-    int getYRatio() {
-        int ys = m_yshift;
-        int r = 1;
-        while (ys) { --ys; r <<= 1; }
-        return r;
-    }
 };
 
 #endif