changeset 1125:50324fca1328 spectrogram-minor-refactor

Scale range matching
author Chris Cannam
date Mon, 01 Aug 2016 15:06:16 +0100
parents b71a0491d287
children 5c3333fb70b3
files layer/Colour3DPlotRenderer.cpp layer/Colour3DPlotRenderer.h layer/SpectrogramLayer.cpp
diffstat 3 files changed, 69 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Colour3DPlotRenderer.cpp	Mon Aug 01 11:31:53 2016 +0100
+++ b/layer/Colour3DPlotRenderer.cpp	Mon Aug 01 15:06:16 2016 +0100
@@ -359,6 +359,8 @@
                 vector<float>(fullColumn.data() + minbin,
                               fullColumn.data() + maxbin + 1);
 
+            column = ColumnOp::applyGain(column, m_params.scaleFactor);
+            
             magRange.sample(column);
 
 //!!! fft scale                if (m_colourScale != ColourScaleType::Phase) {
@@ -788,6 +790,8 @@
                     vector<float>(fullColumn.data() + minbin,
                                   fullColumn.data() + maxbin + 1);
 
+                column = ColumnOp::applyGain(column, m_params.scaleFactor);
+
 //!!! fft scale                if (m_colourScale != ColourScaleType::Phase) {
 //                    column = ColumnOp::fftScale(column, m_fftSize);
 //                }
@@ -935,6 +939,8 @@
                     vector<float>(fullColumn.data() + minbin,
                                   fullColumn.data() + maxbin + 1);
 
+                column = ColumnOp::applyGain(column, m_params.scaleFactor);
+
                 magRange.sample(column);
                 
 //!!! fft scale                if (m_colourScale != ColourScaleType::Phase) {
--- a/layer/Colour3DPlotRenderer.h	Mon Aug 01 11:31:53 2016 +0100
+++ b/layer/Colour3DPlotRenderer.h	Mon Aug 01 15:06:16 2016 +0100
@@ -64,17 +64,48 @@
 	    binDisplay(BinDisplay::AllBins),
             binScale(BinScale::Linear),
 	    alwaysOpaque(false),
-            interpolate(false), //!!! separate out x-interpolate and y-interpolate? the spectrogram actually does (or used to)
+            interpolate(false),
             invertVertical(false),
+            scaleFactor(1.0),
             colourRotation(0) { }
 
-	ColourScale colourScale;       // complete ColourScale object by value
+        /** A complete ColourScale object by value, used for colour
+         *  map conversion. Note that the final display gain setting is
+         *  also encapsulated here. */
+	ColourScale colourScale;
+
+        /** Type of column normalization. */
 	ColumnNormalization normalization;
+
+        /** Selection of bins to display. */
 	BinDisplay binDisplay;
+
+        /** Scale for vertical bin spacing (linear or logarithmic). */
 	BinScale binScale;
+
+        /** Whether cells should always be opaque. If false, then
+         *  large cells (when zoomed in a long way) will be rendered
+         *  translucent in order not to obscure anything in a layer
+         *  beneath. */
 	bool alwaysOpaque;
+
+        /** Whether to apply smoothing when rendering cells at more
+         *  than one pixel per cell.  !!! todo: decide about separating
+         *  out x-interpolate and y-interpolate as the spectrogram
+         *  actually does (or used to)
+         */
 	bool interpolate;
+
+        /** Whether to render the whole caboodle upside-down. */
 	bool invertVertical;
+
+        /** Initial scale factor (e.g. for FFT scaling). This factor
+         *  is applied to all values read from the underlying model
+         *  *before* magnitude ranges are calculated, in contrast to
+         *  the display gain found in the ColourScale parameter. */
+        double scaleFactor;
+
+        /** Colourmap rotation, in the range 0-255. */
         int colourRotation;
     };
     
@@ -121,7 +152,8 @@
      * that the LayerGeometryProvider returns valid results; it is the
      * caller's responsibility to ensure these.
      */
-    RenderResult render(const LayerGeometryProvider *v, QPainter &paint, QRect rect);
+    RenderResult render(const LayerGeometryProvider *v,
+                        QPainter &paint, QRect rect);
     
     /**
      * Render the requested area using the given painter, obtaining
@@ -182,6 +214,15 @@
         return decideRenderType(v) != DirectTranslucent;
     }
     
+    /**
+     * Return the colour corresponding to the given value.
+     * \see ColourScale::getPixel
+     * \see ColourScale::getColour
+     */
+    QColor getColour(double value) const {
+        return m_params.colourScale.getColour(value, m_params.colourRotation);
+    }
+    
 private:
     Sources m_sources;
     Parameters m_params;
--- a/layer/SpectrogramLayer.cpp	Mon Aug 01 11:31:53 2016 +0100
+++ b/layer/SpectrogramLayer.cpp	Mon Aug 01 15:06:16 2016 +0100
@@ -1459,9 +1459,10 @@
         cparams.threshold = m_threshold;
         cparams.gain = m_gain;
 
-        if (m_colourScale != ColourScaleType::Phase &&
+        if (m_colourScale == ColourScaleType::Linear &&
             m_normalization == ColumnNormalization::None) {
-            cparams.gain *= 2.f / float(getFFTSize());
+            //!!! This should not be necessary -- what is the actual range
+            cparams.maxValue = 0.1;
         }
         
         Colour3DPlotRenderer::Parameters params;
@@ -1469,10 +1470,16 @@
         params.normalization = m_normalization;
         params.binDisplay = m_binDisplay;
         params.binScale = m_binScale;
-        params.alwaysOpaque = false;
+        params.alwaysOpaque = false; //!!! should be true though
         params.invertVertical = false;
+        params.scaleFactor = 1.0;
         params.colourRotation = m_colourRotation;
 
+        if (m_colourScale != ColourScaleType::Phase &&
+            m_normalization == ColumnNormalization::None) {
+            params.scaleFactor *= 2.f / float(getFFTSize());
+        }
+
         Preferences::SpectrogramSmoothing smoothing = 
             Preferences::getInstance()->getSpectrogramSmoothing();
         params.interpolate = 
@@ -2063,6 +2070,11 @@
         if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f;
         bottom = QString("%1").arg(lrint(dBmin));
 
+#ifdef DEBUG_SPECTROGRAM_REPAINT
+        cerr << "adjusted dB range to min = " << dBmin << ", max = " << dBmax
+             << endl;
+#endif
+        
         //!!! & phase etc
 
         if (m_colourScale != ColourScaleType::Phase) {
@@ -2088,10 +2100,10 @@
             double dBval = dBmin + (((dBmax - dBmin) * i) / (ch - 1));
             int idb = int(dBval);
 
-//!!! replace this
-            // double value = AudioLevel::dB_to_multiplier(dBval);
-            // int colour = getDisplayValue(v, value * m_gain);
-	    // paint.setPen(m_palette.getColour((unsigned char)colour));
+            //!!!
+            double value = AudioLevel::dB_to_multiplier(dBval);
+            cerr << "dBval = " << dBval << ", value = " << value << endl;
+            paint.setPen(getRenderer(v)->getColour(value));
 
             int y = textHeight * topLines + 4 + ch - i;