changeset 1085:179ea8a2f650 spectrogram-minor-refactor

Add VerticalBinLayer to SpectrogramLayer
author Chris Cannam
date Fri, 01 Jul 2016 17:54:31 +0100
parents db976e9f385a
children 163cb9b98104
files layer/Colour3DPlotLayer.cpp layer/Colour3DPlotLayer.h layer/LayerGeometryProvider.h layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h layer/VerticalBinLayer.h view/View.cpp view/View.h view/ViewProxy.h
diffstat 9 files changed, 60 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp	Fri Jul 01 11:37:46 2016 +0100
+++ b/layer/Colour3DPlotLayer.cpp	Fri Jul 01 17:54:31 2016 +0100
@@ -670,12 +670,6 @@
     return y;
 }
 
-int
-Colour3DPlotLayer::getIYForBin(LayerGeometryProvider *v, int bin) const
-{
-    return int(round(getYForBin(v, bin)));
-}
-
 double
 Colour3DPlotLayer::getBinForY(LayerGeometryProvider *v, double y) const
 {
@@ -694,12 +688,6 @@
     return bin;
 }
 
-int
-Colour3DPlotLayer::getIBinForY(LayerGeometryProvider *v, int y) const
-{
-    return int(floor(getBinForY(v, y)));
-}
-
 QString
 Colour3DPlotLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
 {
--- a/layer/Colour3DPlotLayer.h	Fri Jul 01 11:37:46 2016 +0100
+++ b/layer/Colour3DPlotLayer.h	Fri Jul 01 17:54:31 2016 +0100
@@ -202,11 +202,6 @@
      * fractional, to obtain a position part-way through a bin.
      */
     double getYForBin(LayerGeometryProvider *, double bin) const;
-
-    /**
-     * As getYForBin, but rounding to integer values.
-     */
-    int getIYForBin(LayerGeometryProvider *, int bin) const;
     
     /**
      * Return the bin number, possibly fractional, at the given y
@@ -215,11 +210,6 @@
      * if the vertical scale is the usual way up).
      */
     double getBinForY(LayerGeometryProvider *, double y) const;
-
-    /**
-     * As getBinForY, but rounding to integer values.
-     */
-    int getIBinForY(LayerGeometryProvider *, int y) const;
     
     DenseThreeDimensionalModel::Column getColumn(int col) const;
 
--- a/layer/LayerGeometryProvider.h	Fri Jul 01 11:37:46 2016 +0100
+++ b/layer/LayerGeometryProvider.h	Fri Jul 01 17:54:31 2016 +0100
@@ -103,23 +103,26 @@
     virtual int getViewXForX(int x) const = 0;
     
     /**
-     * Return the pixel y-coordinate corresponding to a given
-     * frequency, if the frequency range is as specified.  This does
-     * not imply any policy about layer frequency ranges, but it might
-     * be useful for layers to match theirs up if desired.
+     * Return the (maybe fractional) pixel y-coordinate corresponding
+     * to a given frequency, if the frequency range is as specified.
+     * This does not imply any policy about layer frequency ranges,
+     * but it might be useful for layers to match theirs up if
+     * desired.
      *
      * Not thread-safe in logarithmic mode.  Call only from GUI thread.
      */
-    virtual double getYForFrequency(double frequency, double minFreq, double maxFreq, 
+    virtual double getYForFrequency(double frequency,
+                                    double minFreq, double maxFreq, 
                                     bool logarithmic) const = 0;
 
     /**
-     * Return the closest frequency to the given pixel y-coordinate,
-     * if the frequency range is as specified.
+     * Return the closest frequency to the given (maybe fractional)
+     * pixel y-coordinate, if the frequency range is as specified.
      *
      * Not thread-safe in logarithmic mode.  Call only from GUI thread.
      */
-    virtual double getFrequencyForY(int y, double minFreq, double maxFreq,
+    virtual double getFrequencyForY(double y,
+                                    double minFreq, double maxFreq,
                                     bool logarithmic) const = 0;
 
     virtual int getTextLabelHeight(const Layer *layer, QPainter &) const = 0;
--- a/layer/SpectrogramLayer.cpp	Fri Jul 01 11:37:46 2016 +0100
+++ b/layer/SpectrogramLayer.cpp	Fri Jul 01 17:54:31 2016 +0100
@@ -1209,7 +1209,38 @@
 
     return true;
 }
+
+double
+SpectrogramLayer::getYForBin(LayerGeometryProvider *, double bin) const {
+    //!!! not implemented
+    throw std::logic_error("not implemented");
+}
+
+double
+SpectrogramLayer::getBinForY(LayerGeometryProvider *v, double y) const
+{
+    //!!! overlap with range methods above (but using double arg)
+    //!!! tidy this
     
+    int h = v->getPaintHeight();
+    if (y < 0 || y >= h) return false;
+
+    sv_samplerate_t sr = m_model->getSampleRate();
+    double minf = getEffectiveMinFrequency();
+    double maxf = getEffectiveMaxFrequency();
+
+    bool logarithmic = (m_frequencyScale == LogFrequencyScale);
+
+    double q = v->getFrequencyForY(y, minf, maxf, logarithmic);
+
+    // Now map on to ("proportions of") actual bins, using raw FFT
+    // size (unsmoothed)
+
+    q = (q * getFFTSize(v)) / sr;
+
+    return q;
+}
+
 bool
 SpectrogramLayer::getXBinRange(LayerGeometryProvider *v, int x, double &s0, double &s1) const
 {
--- a/layer/SpectrogramLayer.h	Fri Jul 01 11:37:46 2016 +0100
+++ b/layer/SpectrogramLayer.h	Fri Jul 01 17:54:31 2016 +0100
@@ -27,6 +27,7 @@
 #include "data/model/FFTModel.h"
 
 #include "ScrollableImageCache.h"
+#include "VerticalBinLayer.h"
 
 #include <QMutex>
 #include <QWaitCondition>
@@ -48,6 +49,7 @@
  */
 
 class SpectrogramLayer : public SliceableLayer,
+                         public VerticalBinLayer,
 			 public PowerOfSqrtTwoZoomConstraint
 {
     Q_OBJECT
@@ -208,6 +210,10 @@
     double getYForFrequency(const LayerGeometryProvider *v, double frequency) const;
     double getFrequencyForY(const LayerGeometryProvider *v, int y) const;
 
+    //!!! VerticalBinLayer methods. Note overlap with get*BinRange()
+    double getYForBin(LayerGeometryProvider *, double bin) const;
+    double getBinForY(LayerGeometryProvider *, double y) const;
+    
     virtual int getCompletion(LayerGeometryProvider *v) const;
     virtual QString getError(LayerGeometryProvider *v) const;
 
--- a/layer/VerticalBinLayer.h	Fri Jul 01 11:37:46 2016 +0100
+++ b/layer/VerticalBinLayer.h	Fri Jul 01 17:54:31 2016 +0100
@@ -36,7 +36,9 @@
     /**
      * As getYForBin, but rounding to integer values.
      */
-    virtual int getIYForBin(LayerGeometryProvider *, int bin) const = 0;
+    virtual int getIYForBin(LayerGeometryProvider *v, int bin) const {
+        return int(round(getYForBin(v, bin)));
+    }
     
     /**
      * Return the bin number, possibly fractional, at the given y
@@ -49,7 +51,9 @@
     /**
      * As getBinForY, but rounding to integer values.
      */
-    virtual int getIBinForY(LayerGeometryProvider *, int y) const = 0;
+    virtual int getIBinForY(LayerGeometryProvider *v, int y) const {
+        return int(floor(getBinForY(v, y)));
+    }
 };
 
 #endif
--- a/view/View.cpp	Fri Jul 01 11:37:46 2016 +0100
+++ b/view/View.cpp	Fri Jul 01 17:54:31 2016 +0100
@@ -415,12 +415,12 @@
 }
 
 double
-View::getFrequencyForY(int y,
+View::getFrequencyForY(double y,
 		       double minf,
 		       double maxf,
 		       bool logarithmic) const
 {
-    int h = height();
+    double h = height();
 
     if (logarithmic) {
 
--- a/view/View.h	Fri Jul 01 11:37:46 2016 +0100
+++ b/view/View.h	Fri Jul 01 17:54:31 2016 +0100
@@ -144,8 +144,8 @@
      *
      * Not thread-safe in logarithmic mode.  Call only from GUI thread.
      */
-    double getFrequencyForY(int y, double minFreq, double maxFreq,
-			   bool logarithmic) const;
+    double getFrequencyForY(double y, double minFreq, double maxFreq,
+                            bool logarithmic) const;
 
     /**
      * Return the zoom level, i.e. the number of frames per pixel
--- a/view/ViewProxy.h	Fri Jul 01 11:37:46 2016 +0100
+++ b/view/ViewProxy.h	Fri Jul 01 17:54:31 2016 +0100
@@ -63,14 +63,10 @@
 	return m_scaleFactor *
 	    m_view->getYForFrequency(frequency, minFreq, maxFreq, logarithmic);
     }
-    virtual double getFrequencyForY(int y, double minFreq, double maxFreq,
+    virtual double getFrequencyForY(double y, double minFreq, double maxFreq,
 				    bool logarithmic) const {
-        double f0 = m_view->getFrequencyForY
+        return m_view->getFrequencyForY
             (y / m_scaleFactor, minFreq, maxFreq, logarithmic);
-        if (m_scaleFactor == 1) return f0;
-        double f1 = m_view->getFrequencyForY
-            ((y / m_scaleFactor) + 1, minFreq, maxFreq, logarithmic);
-        return f0 + ((f1 - f0) * (y % m_scaleFactor)) / m_scaleFactor;
     }
     virtual int getTextLabelHeight(const Layer *layer, QPainter &paint) const {
 	return m_scaleFactor * m_view->getTextLabelHeight(layer, paint);