changeset 221:9e739f92c0b8

* Add fuzzy interpolation option as an alternative to zero padding in spectrogram (looks terrible though) * Make spectrogram appear more quickly by having the FFT server notify of updates more often near the start of its run
author Chris Cannam
date Mon, 05 Mar 2007 15:32:55 +0000
parents 8dc50f57d480
children cd81066ac7ad
files layer/SpectrogramLayer.cpp
diffstat 1 files changed, 75 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp	Mon Mar 05 13:04:52 2007 +0000
+++ b/layer/SpectrogramLayer.cpp	Mon Mar 05 15:32:55 2007 +0000
@@ -576,7 +576,7 @@
         setWindowType(Preferences::getInstance()->getWindowType());
         return;
     }
-    if (name == "Smooth Spectrogram") {
+    if (name == "Spectrogram Smoothing") {
         invalidatePixmapCaches();
         invalidateMagnitudes();
         emit layerParametersChanged();
@@ -1494,7 +1494,13 @@
     //!!! tidy all this stuff
 
     if (m_binDisplay != AllBins) return 0;
-    if (!Preferences::getInstance()->getSmoothSpectrogram()) return 0;
+
+    Preferences::SpectrogramSmoothing smoothing = 
+        Preferences::getInstance()->getSpectrogramSmoothing();
+    
+    if (smoothing == Preferences::NoSpectrogramSmoothing ||
+        smoothing == Preferences::SpectrogramInterpolated) return 0;
+
     if (m_frequencyScale == LogFrequencyScale) return 3;
 
     int sr = m_model->getSampleRate();
@@ -2016,6 +2022,15 @@
 
     bool fftSuspended = false;
 
+    bool interpolate = false;
+    Preferences::SpectrogramSmoothing smoothing = 
+        Preferences::getInstance()->getSpectrogramSmoothing();
+    if (smoothing == Preferences::SpectrogramInterpolated ||
+        smoothing == Preferences::SpectrogramZeroPaddedAndInterpolated) {
+        interpolate = true;
+    }
+
+
 #ifdef DEBUG_SPECTROGRAM_REPAINT
     std::cerr << (float(v->getFrameForX(1) - v->getFrameForX(0)) / increment) << " bins per pixel" << std::endl;
 #endif
@@ -2108,21 +2123,69 @@
                     value *= m_gain;
                 }
 
-		for (int y = y0i; y <= y1i; ++y) {
+                if (interpolate) {
+                    
+                    int ypi = y0i;
+                    if (q < maxbin - 1) ypi = int(yval[q + 2]);
+
+                    for (int y = ypi; y <= y1i; ++y) {
+                    
+                        if (y < 0 || y >= h) continue;
+                    
+                        float yprop = sprop;
+                        float iprop = yprop;
+
+                        if (ypi < y0i && y <= y0i) {
+
+                            float half = float(y0i - ypi) / 2;
+                            float dist = y - (ypi + half);
+
+                            if (dist >= 0) {
+                                iprop = (iprop * dist) / half;
+                                ymag[y] += iprop * value;
+                            }
+                        } else {
+                            if (y1i > y0i) {
+
+                                float half = float(y1i - y0i) / 2;
+                                float dist = y - (y0i + half);
+                                
+                                if (dist >= 0) {
+                                    iprop = (iprop * (half - dist)) / half;
+                                }
+                            }
+
+                            ymag[y] += iprop * value;
+                            ydiv[y] += yprop;
+                        }
+                    }
+
+                } else {
+
+                    for (int y = y0i; y <= y1i; ++y) {
+                    
+                        if (y < 0 || y >= h) continue;
+                    
+                        float yprop = sprop;
+                        if (y == y0i) yprop *= (y + 1) - y0;
+                        if (y == y1i) yprop *= y1 - y;
+
+                        for (int y = y0i; y <= y1i; ++y) {
 		    
-		    if (y < 0 || y >= h) continue;
-
-		    float yprop = sprop;
-		    if (y == y0i) yprop *= (y + 1) - y0;
-		    if (y == y1i) yprop *= y1 - y;
-		    ymag[y] += yprop * value;
-		    ydiv[y] += yprop;
-		}
+                            if (y < 0 || y >= h) continue;
+
+                            float yprop = sprop;
+                            if (y == y0i) yprop *= (y + 1) - y0;
+                            if (y == y1i) yprop *= y1 - y;
+                            ymag[y] += yprop * value;
+                            ydiv[y] += yprop;
+                        }
+                    }
+                }
 	    }
 
             if (mag.isSet()) {
 
-
                 if (s >= m_columnMags.size()) {
                     std::cerr << "INTERNAL ERROR: " << s << " >= "
                               << m_columnMags.size() << " at SpectrogramLayer.cpp:2087" << std::endl;