changeset 284:1284955856ab

* threshold, show-peaks properties in spectrum
author Chris Cannam
date Fri, 06 Jul 2007 15:17:35 +0000
parents 86a112b5b319
children 9dd432665059
files layer/SliceLayer.cpp layer/SliceLayer.h layer/SpectrogramLayer.cpp layer/SpectrumLayer.cpp layer/SpectrumLayer.h
diffstat 5 files changed, 98 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/layer/SliceLayer.cpp	Thu Jul 05 15:36:37 2007 +0000
+++ b/layer/SliceLayer.cpp	Fri Jul 06 15:17:35 2007 +0000
@@ -36,6 +36,8 @@
     m_plotStyle(PlotSteps),
     m_binScale(LinearBins),
     m_normalize(false),
+    m_threshold(0.0),
+    m_initialThreshold(0.0),
     m_gain(1.0),
     m_currentf0(0),
     m_currentf1(0)
@@ -240,7 +242,7 @@
 
     int yorigin = m_yorigins[v];
     int h = m_heights[v];
-    float thresh = -80.f;
+    float thresh = getThresholdDb();
 
     float y = 0.f;
 
@@ -265,8 +267,10 @@
         break;
         
     default:
-        norm = value;
-        y = yorigin - (float(h) * value);
+        std::cerr << "thresh = " << m_threshold << std::endl;
+        norm = (fabsf(value) - m_threshold);
+        if (norm < 0) norm = 0;
+        y = yorigin - (float(h) * norm);
         break;
     }
     
@@ -282,7 +286,7 @@
 
     int yorigin = m_yorigins[v];
     int h = m_heights[v];
-    float thresh = -80.f;
+    float thresh = getThresholdDb();
 
     if (h <= 0) return value;
 
@@ -302,7 +306,7 @@
         break;
 
     default:
-        value = y / h;
+        value = y / h + m_threshold;
     }
 
     return value / m_gain;
@@ -358,7 +362,7 @@
     size_t f1 = v->getFrameForX(f0x + 1);
     if (f1 > f0) --f1;
 
-    std::cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << std::endl;
+//    std::cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << std::endl;
 
     size_t res = m_sliceableModel->getResolution();
     size_t col0 = f0 / res;
@@ -367,7 +371,7 @@
     f0 = col0 * res;
     f1 = (col1 + 1) * res - 1;
 
-    std::cerr << "resolution " << res << ", col0 " << col0 << ", col1 " << col1 << ", f0 " << f0 << ", f1 " << f1 << std::endl;
+//    std::cerr << "resolution " << res << ", col0 " << col0 << ", col1 " << col1 << ", f0 " << f0 << ", f1 " << f1 << std::endl;
 
     m_currentf0 = f0;
     m_currentf1 = f1;
@@ -510,9 +514,9 @@
 void
 SliceLayer::paintVerticalScale(View *v, QPainter &paint, QRect rect) const
 {
-    float thresh = 0;
+    float thresh = m_threshold;
     if (m_energyScale != LinearScale) {
-        thresh = AudioLevel::dB_to_multiplier(-80); //!!! thresh
+        thresh = AudioLevel::dB_to_multiplier(getThresholdDb());
     }
     
 //    int h = (rect.height() * 3) / 4;
@@ -551,6 +555,7 @@
 //    list.push_back("Sampling Mode");
     list.push_back("Scale");
     list.push_back("Normalize");
+    list.push_back("Threshold");
     list.push_back("Gain");
     list.push_back("Bin Scale");
 
@@ -564,6 +569,7 @@
     if (name == "Plot Type") return tr("Plot Type");
     if (name == "Energy Scale") return tr("Scale");
     if (name == "Normalize") return tr("Normalize");
+    if (name == "Threshold") return tr("Threshold");
     if (name == "Gain") return tr("Gain");
     if (name == "Sampling Mode") return tr("Sampling Mode");
     if (name == "Bin Scale") return tr("Plot X Scale");
@@ -575,6 +581,7 @@
 {
     if (name == "Gain") return RangeProperty;
     if (name == "Normalize") return ToggleProperty;
+    if (name == "Threshold") return RangeProperty;
     return ValueProperty;
 }
 
@@ -584,6 +591,7 @@
     if (name == "Scale" ||
         name == "Normalize" ||
         name == "Sampling Mode" ||
+        name == "Threshold" ||
         name == "Gain") return tr("Scale");
     if (name == "Plot Type" ||
         name == "Bin Scale") return tr("Plot Type");
@@ -613,6 +621,19 @@
 	if (val < *min) val = *min;
 	if (val > *max) val = *max;
 
+    } else if (name == "Threshold") {
+        
+	*min = -80;
+	*max = 0;
+
+        *deflt = lrintf(AudioLevel::multiplier_to_dB(m_initialThreshold));
+	if (*deflt < *min) *deflt = *min;
+	if (*deflt > *max) *deflt = *max;
+
+	val = lrintf(AudioLevel::multiplier_to_dB(m_threshold));
+	if (val < *min) val = *min;
+	if (val > *max) val = *max;
+
     } else if (name == "Normalize") {
 	
 	val = (m_normalize ? 1 : 0);
@@ -743,6 +764,9 @@
     if (name == "Gain") {
         return new LinearRangeMapper(-50, 50, -25, 25, tr("dB"));
     }
+    if (name == "Threshold") {
+        return new LinearRangeMapper(-80, 0, -80, 0, tr("dB"));
+    }
     return 0;
 }
 
@@ -751,6 +775,9 @@
 {
     if (name == "Gain") {
 	setGain(pow(10, float(value)/20.0));
+    } else if (name == "Threshold") {
+	if (value == -80) setThreshold(0.0);
+	else setThreshold(AudioLevel::dB_to_multiplier(value));
     } else if (name == "Colour") {
         if (m_plotStyle == PlotFilledBlocks) {
             setFillColourMap(value);
@@ -855,6 +882,14 @@
 }
 
 void
+SliceLayer::setThreshold(float thresh)
+{
+    if (m_threshold == thresh) return;
+    m_threshold = thresh;
+    emit layerParametersChanged();
+}
+
+void
 SliceLayer::setGain(float gain)
 {
     if (m_gain == gain) return;
@@ -862,6 +897,14 @@
     emit layerParametersChanged();
 }
 
+float
+SliceLayer::getThresholdDb() const
+{
+    if (m_threshold == 0.0) return -80.f;
+    float db = AudioLevel::multiplier_to_dB(m_threshold);
+    return db;
+}
+
 QString
 SliceLayer::toXmlString(QString indent, QString extraAttributes) const
 {
--- a/layer/SliceLayer.h	Thu Jul 05 15:36:37 2007 +0000
+++ b/layer/SliceLayer.h	Fri Jul 06 15:17:35 2007 +0000
@@ -91,6 +91,9 @@
     void setBinScale(BinScale scale);
     BinScale getBinScale() const { return m_binScale; }
 
+    void setThreshold(float);
+    int getThreshold() const { return m_threshold; }
+
     void setGain(float gain);
     float getGain() const;
 
@@ -122,6 +125,8 @@
     typedef std::vector<float> BiasCurve;
     virtual void getBiasCurve(BiasCurve &) const { return; }
 
+    virtual float getThresholdDb() const;
+
     const DenseThreeDimensionalModel *m_sliceableModel;
     QColor                            m_colour;
     int                               m_colourMap;
@@ -130,6 +135,8 @@
     PlotStyle                         m_plotStyle;
     BinScale                          m_binScale;
     bool                              m_normalize;
+    float                             m_threshold;
+    float                             m_initialThreshold;
     float                             m_gain;
     mutable std::vector<int>          m_scalePoints;
     mutable std::map<const View *, int> m_xorigins;
--- a/layer/SpectrogramLayer.cpp	Thu Jul 05 15:36:37 2007 +0000
+++ b/layer/SpectrogramLayer.cpp	Fri Jul 06 15:17:35 2007 +0000
@@ -2914,12 +2914,17 @@
 
             if (n == 1) {
                 // C# -- fill the C from here
+                QColor col = Qt::gray;
+                if (i == 61) { // filling middle C
+                    col = Qt::blue;
+                    col = col.light(150);
+                }
                 if (ppy - y > 2) {
                     paint.fillRect(w - pkw,
                                    y,
                                    pkw,
                                    (py + ppy) / 2 - y,
-                                   Qt::gray);
+                                   col);
                 }
             }
 
--- a/layer/SpectrumLayer.cpp	Thu Jul 05 15:36:37 2007 +0000
+++ b/layer/SpectrumLayer.cpp	Fri Jul 06 15:17:35 2007 +0000
@@ -32,6 +32,7 @@
     m_windowSize(1024),
     m_windowType(HanningWindow),
     m_windowHopLevel(2),
+    m_showPeaks(false),
     m_newFFTNeeded(true)
 {
     Preferences *prefs = Preferences::getInstance();
@@ -108,8 +109,6 @@
 
     m_channel = channel;
 
-//!!!    if (!fft) setupFFT();
-
     emit layerParametersChanged();
 }
 
@@ -119,6 +118,7 @@
     PropertyList list = SliceLayer::getProperties();
     list.push_back("Window Size");
     list.push_back("Window Increment");
+    list.push_back("Show Peak Frequencies");
     return list;
 }
 
@@ -127,6 +127,7 @@
 {
     if (name == "Window Size") return tr("Window Size");
     if (name == "Window Increment") return tr("Window Overlap");
+    if (name == "Show Peak Frequencies") return tr("Show Peak Frequencies");
     return SliceLayer::getPropertyLabel(name);
 }
 
@@ -135,6 +136,7 @@
 {
     if (name == "Window Size") return ValueProperty;
     if (name == "Window Increment") return ValueProperty;
+    if (name == "Show Peak Frequencies") return ToggleProperty;
     return SliceLayer::getPropertyType(name);
 }
 
@@ -143,6 +145,7 @@
 {
     if (name == "Window Size" ||
 	name == "Window Increment") return tr("Window");
+    if (name == "Show Peak Frequencies") return tr("Plot Type");
     return SliceLayer::getPropertyGroupName(name);
 }
 
@@ -175,6 +178,10 @@
 	
         val = m_windowHopLevel;
     
+    } else if (name == "Show Peak Frequencies") {
+
+        return m_showPeaks ? 1 : 0;
+
     } else {
 
         val = SliceLayer::getPropertyRangeAndValue(name, min, max, deflt);
@@ -217,6 +224,8 @@
 	setWindowSize(32 << value);
     } else if (name == "Window Increment") {
         setWindowHopLevel(value);
+    } else if (name == "Show Peak Frequencies") {
+        setShowPeaks(value ? true : false);
     } else {
         SliceLayer::setProperty(name, value);
     }
@@ -227,7 +236,6 @@
 {
     if (m_windowSize == ws) return;
     m_windowSize = ws;
-//!!!    setupFFT();
     m_newFFTNeeded = true;
     emit layerParametersChanged();
 }
@@ -237,7 +245,6 @@
 {
     if (m_windowHopLevel == v) return;
     m_windowHopLevel = v;
-//!!!    setupFFT();
     m_newFFTNeeded = true;
     emit layerParametersChanged();
 }
@@ -247,12 +254,19 @@
 {
     if (m_windowType == w) return;
     m_windowType = w;
-//!!!    setupFFT();
     m_newFFTNeeded = true;
     emit layerParametersChanged();
 }
 
 void
+SpectrumLayer::setShowPeaks(bool show)
+{
+    if (m_showPeaks == show) return;
+    m_showPeaks = show;
+    emit layerParametersChanged();
+}
+
+void
 SpectrumLayer::preferenceChanged(PropertyContainer::PropertyName name)
 {
     if (name == "Window Type") {
@@ -365,12 +379,10 @@
 
     if (m_energyScale == dBScale || m_energyScale == MeterScale) {
 
-        float thresh = -80.f;
-
         if (value > 0.f) {
             value = 10.f * log10f(value);
-            if (value < thresh) value = thresh;
-        } else value = thresh;
+            if (value < m_threshold) value = m_threshold;
+        } else value = m_threshold;
 
         unit = "dBV";
 
@@ -476,7 +488,7 @@
     }
 
     float value = getValueForY(cursorPos.y(), v);
-    float thresh = -80.f;
+    float thresh = m_threshold;
     float db = thresh;
     if (value > 0.f) db = 10.f * log10f(value);
     if (db < thresh) db = thresh;
@@ -634,10 +646,9 @@
     int pkh = 0;
     if (m_binScale == LogBins) pkh = 10;
 
-    if (fft) {
+    if (fft && m_showPeaks) {
 
         // draw peak lines
-        //!!! should be optional
 
         size_t col = v->getCentreFrame() / fft->getResolution();
 
@@ -738,12 +749,17 @@
 
             if (n == 1) {
                 // C# -- fill the C from here
+                QColor col = Qt::gray;
+                if (i == 61) { // filling middle C
+                    col = Qt::blue;
+                    col = col.light(150);
+                }
                 if (x - ppx > 2) {
                     paint.fillRect((px + ppx) / 2 + 1,
                                    h - pkh,
                                    x - (px + ppx) / 2 - 1,
                                    pkh,
-                                   Qt::gray);
+                                   col);
                 }
             }
 
--- a/layer/SpectrumLayer.h	Thu Jul 05 15:36:37 2007 +0000
+++ b/layer/SpectrumLayer.h	Fri Jul 06 15:17:35 2007 +0000
@@ -88,6 +88,9 @@
     void setWindowType(WindowType type);
     WindowType getWindowType() const { return m_windowType; }
 
+    void setShowPeaks(bool);
+    bool getShowPeaks() const { return m_showPeaks; }
+
     virtual QString toXmlString(QString indent = "",
 				QString extraAttributes = "") const;
 
@@ -106,6 +109,7 @@
     size_t                  m_windowSize;
     WindowType              m_windowType;
     size_t                  m_windowHopLevel;
+    bool                    m_showPeaks;
     mutable bool            m_newFFTNeeded;
 
     void setupFFT();