changeset 1561:d6f9fac336b3 spectrogram-export

Handle scale factor, needed for all spectrogram export; handle thresholding (using gain/normalisation for threshold calculation) in peak frequency export
author Chris Cannam
date Thu, 09 Jan 2020 14:34:51 +0000
parents 27f3e64489e1
children 3b45788b7804
files layer/Colour3DPlotExporter.cpp layer/Colour3DPlotExporter.h
diffstat 2 files changed, 49 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Colour3DPlotExporter.cpp	Thu Jan 09 14:29:21 2020 +0000
+++ b/layer/Colour3DPlotExporter.cpp	Thu Jan 09 14:34:51 2020 +0000
@@ -115,19 +115,15 @@
         if (fr < startFrame || fr >= startFrame + duration) {
             continue;
         }
-
-        // Unlike Colour3DPlotRenderer, we don't want to scale or
-        // normalise
-
-        //!!! (but might we want to threshold? we get a lot of
-        //!!! spurious output [i.e. elements not readily visible on
-        //!!! screen] for peak freqs)
         
-        //!!! (+ should we be handling phase layer type?)
+        //!!! (+ phase layer type)
 
         auto column = model->getColumn(i);
         column = ColumnOp::Column(column.data() + minbin,
                                   column.data() + minbin + nbins);
+
+        // The scale factor is always applied
+        column = ColumnOp::applyGain(column, m_params.scaleFactor);
         
         QStringList list;
 
@@ -136,13 +132,28 @@
             FFTModel::PeakSet peaks = fftModel->getPeakFrequencies
                 (FFTModel::AllPeaks, i, minbin, minbin + nbins - 1);
 
+            // We don't apply normalisation or gain to the output, but
+            // we *do* perform thresholding when exporting the
+            // peak-frequency spectrogram, to give the user an
+            // opportunity to cut irrelevant peaks. And to make that
+            // match the display, we have to apply both normalisation
+            // and gain locally for thresholding
+
+            auto toTest = ColumnOp::normalize(column, m_params.normalization);
+            toTest = ColumnOp::applyGain(toTest, m_params.gain);
+            
             for (const auto &p: peaks) {
 
                 int bin = p.first;
+
+                if (toTest[bin - minbin] < m_params.threshold) {
+                    continue;
+                }
+
                 double freq = p.second;
-                float mag = column[bin - minbin];
-
-                list << QString("%1").arg(freq) << QString("%1").arg(mag);
+                double value = column[bin - minbin];
+                
+                list << QString("%1").arg(freq) << QString("%1").arg(value);
             }
 
         } else {
@@ -160,23 +171,5 @@
     }
 
     return s;
-    
-
-    //!!! For reference, this is the body of
-    //!!! EditableDenseThreeDimensionalModel::toDelimitedDataString
-    /*
-    QString s;
-    for (int i = 0; in_range_for(m_data, i); ++i) {
-        sv_frame_t fr = m_startFrame + i * m_resolution;
-        if (fr >= startFrame && fr < startFrame + duration) {
-            QStringList list;
-            for (int j = 0; in_range_for(m_data.at(i), j); ++j) {
-                list << QString("%1").arg(m_data.at(i).at(j));
-            }
-            s += list.join(delimiter) + "\n";
-        }
-    }
-    return s;
-    */    
 }
 
--- a/layer/Colour3DPlotExporter.h	Thu Jan 09 14:29:21 2020 +0000
+++ b/layer/Colour3DPlotExporter.h	Thu Jan 09 14:34:51 2020 +0000
@@ -33,10 +33,36 @@
 
     struct Parameters {
         Parameters() :
-            binDisplay(BinDisplay::AllBins) { }
+            binDisplay(BinDisplay::AllBins),
+            scaleFactor(1.0),
+            threshold(0.0),
+            gain(1.0),
+            normalization(ColumnNormalization::None) { }
 
         /** Selection of bins to include in the export. */
         BinDisplay binDisplay;
+
+        /** Initial scale factor (e.g. for FFT scaling). This factor
+         *  is actually applied to exported values, in contrast to the
+         *  gain value below based on the ColourScale parameter. */
+        double scaleFactor;
+
+        /** Threshold below which every value is mapped to background
+         *  pixel 0 in the display, matching the ColourScale object
+         *  parameters. This is used for thresholding in
+         *  peak-frequency output only. */
+        double threshold;
+
+        /** Gain that is applied before thresholding, in the display,
+         *  matching the ColourScale object parameters. This is used
+         *  only to determined the thresholding level. The exported
+         *  values have the scaleFactor applied, but not this gain. */
+        double gain;
+
+        /** Type of column normalization. Again, this is only used to
+         *  calculate thresholding level. The exported values are
+         *  un-normalized. */
+        ColumnNormalization normalization;
     };
     
     Colour3DPlotExporter(Sources sources, Parameters parameters);