diff layer/SpectrogramLayer.cpp @ 215:d2334a77db73

* Update to use new vamp-hostsdk instead of vamp-sdk * Make spectrogram adapt its paint block size depending on how long it actually takes to draw * Some thread debugging infrastructure
author Chris Cannam
date Fri, 02 Mar 2007 13:01:41 +0000
parents 748985c7e2c1
children 34bbbcb3c01f
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp	Thu Mar 01 17:12:50 2007 +0000
+++ b/layer/SpectrogramLayer.cpp	Fri Mar 02 13:01:41 2007 +0000
@@ -48,8 +48,11 @@
     m_zeroPadLevel(0),
     m_fftSize(1024),
     m_gain(1.0),
+    m_initialGain(1.0),
     m_threshold(0.0),
+    m_initialThreshold(0.0),
     m_colourRotation(0),
+    m_initialRotation(0),
     m_minFrequency(10),
     m_maxFrequency(8000),
     m_initialMaxFrequency(8000),
@@ -60,27 +63,34 @@
     m_normalizeColumns(false),
     m_normalizeVisibleArea(false),
     m_lastEmittedZoomStep(-1),
+    m_lastPaintBlockWidth(0),
     m_updateTimer(0),
     m_candidateFillStartFrame(0),
     m_exiting(false),
     m_sliceableModel(0)
 {
-    if (config == MelodicRange) {
+    if (config == FullRangeDb) {
+        m_initialMaxFrequency = 0;
+        setMaxFrequency(0);
+    } else if (config == MelodicRange) {
 	setWindowSize(8192);
 	setWindowHopLevel(4);
-//	setWindowType(ParzenWindow);
-        m_initialMaxFrequency = 1000;
-	setMaxFrequency(1000);
+        m_initialMaxFrequency = 1500;
+	setMaxFrequency(1500);
+        setMinFrequency(40);
 	setColourScale(LinearColourScale);
+        setColourMap(ColourMapper::Sunset);
+        setFrequencyScale(LogFrequencyScale);
+        m_initialGain = 20;
+        setGain(20);
     } else if (config == MelodicPeaks) {
 	setWindowSize(4096);
 	setWindowHopLevel(5);
-//	setWindowType(BlackmanWindow);
         m_initialMaxFrequency = 2000;
 	setMaxFrequency(2000);
 	setMinFrequency(40);
 	setFrequencyScale(LogFrequencyScale);
-	setColourScale(MeterColourScale);
+	setColourScale(LinearColourScale);
 	setBinDisplay(PeakFrequencies);
 	setNormalizeColumns(true);
     }
@@ -213,7 +223,7 @@
 	*min = -50;
 	*max = 50;
 
-	deft = lrint(log10(m_gain) * 20.0);
+	deft = lrintf(log10(m_initialGain) * 20.0);
 	if (deft < *min) deft = *min;
 	if (deft > *max) deft = *max;
 
@@ -222,7 +232,7 @@
 	*min = -50;
 	*max = 0;
 
-	deft = lrintf(AudioLevel::multiplier_to_dB(m_threshold));
+	deft = lrintf(AudioLevel::multiplier_to_dB(m_initialThreshold));
 	if (deft < *min) deft = *min;
 	if (deft > *max) deft = *max;
 
@@ -231,7 +241,7 @@
 	*min = 0;
 	*max = 256;
 
-	deft = m_colourRotation;
+	deft = m_initialRotation;
 
     } else if (name == "Colour Scale") {
 
@@ -345,8 +355,8 @@
 	default:
 	case 0: return tr("Linear");
 	case 1: return tr("Meter");
-	case 2: return tr("dB");
-	case 3: return tr("dB^2");
+	case 2: return tr("dBV^2");
+	case 3: return tr("dBV");
 	case 4: return tr("Phase");
 	}
     }
@@ -489,8 +499,8 @@
 	default:
 	case 0: setColourScale(LinearColourScale); break;
 	case 1: setColourScale(MeterColourScale); break;
-	case 2: setColourScale(dBColourScale); break;
-	case 3: setColourScale(dBSquaredColourScale); break;
+	case 2: setColourScale(dBSquaredColourScale); break;
+	case 3: setColourScale(dBColourScale); break;
 	case 4: setColourScale(PhaseColourScale); break;
 	}
     } else if (name == "Frequency Scale") {
@@ -1084,7 +1094,7 @@
     } else if (!m_normalizeColumns) {
         if (m_colourScale == LinearColourScale ||
             m_colourScale == MeterColourScale) {
-            max = 0.1f;
+//            max = 0.1f;
         }
     }
 
@@ -1104,29 +1114,9 @@
         value = AudioLevel::multiplier_to_preview
             ((input - min) / (max - min), 254) + 1;
 	break;
-	
-    case dBColourScale:
-        //!!! experiment with normalizing the visible area this way.
-        //In any case, we need to have some indication of what the dB
-        //scale is relative to.
-        input = input / max;
-        if (input > 0.f) {
-            input = 10.f * log10f(input);
-        } else {
-            input = thresh;
-        }
-        if (min > 0.f) {
-            thresh = 10.f * log10f(min);
-            if (thresh < -80.f) thresh = -80.f;
-        }
-	input = (input - thresh) / (-thresh);
-	if (input < 0.f) input = 0.f;
-	if (input > 1.f) input = 1.f;
-	value = int(input * 255.f) + 1;
-	break;
 
     case dBSquaredColourScale:
-        input = (input * input) / (max * max);
+        input = ((input - min) * (input - min)) / ((max - min) * (max - min));
         if (input > 0.f) {
             input = 10.f * log10f(input);
         } else {
@@ -1142,6 +1132,26 @@
 	value = int(input * 255.f) + 1;
 	break;
 	
+    case dBColourScale:
+        //!!! experiment with normalizing the visible area this way.
+        //In any case, we need to have some indication of what the dB
+        //scale is relative to.
+        input = (input - min) / (max - min);
+        if (input > 0.f) {
+            input = 10.f * log10f(input);
+        } else {
+            input = thresh;
+        }
+        if (min > 0.f) {
+            thresh = 10.f * log10f(min);
+            if (thresh < -80.f) thresh = -80.f;
+        }
+	input = (input - thresh) / (-thresh);
+	if (input < 0.f) input = 0.f;
+	if (input > 1.f) input = 1.f;
+	value = int(input * 255.f) + 1;
+	break;
+	
     case PhaseColourScale:
 	value = int((input * 127.0 / M_PI) + 128);
 	break;
@@ -1174,14 +1184,14 @@
 	    / (m_normalizeColumns ? 1.0 : 50.0);
 	break;
 
-    case dBColourScale:
+    case dBSquaredColourScale:
 	input = float(value - 1) / 255.0;
 	input = (input * 80.0) - 80.0;
 	input = powf(10.0, input) / 20.0;
 	value = int(input);
 	break;
 
-    case dBSquaredColourScale:
+    case dBColourScale:
 	input = float(value - 1) / 255.0;
 	input = (input * 80.0) - 80.0;
 	input = powf(10.0, input) / 20.0;
@@ -1846,13 +1856,32 @@
         x1 = v->width();
     }
 
-    //!!! This width should really depend on how fast the machine is
-    //at redrawing the spectrogram.  We could fairly easily time that,
-    //in this function, and adjust accordingly.  The following is
-    //probably about as small as the block width should go.
-    int paintBlockWidth = (300000 / zoomLevel);
+    struct timeval tv;
+    (void)gettimeofday(&tv, 0);
+    RealTime mainPaintStart = RealTime::fromTimeval(tv);
+
+    int paintBlockWidth = m_lastPaintBlockWidth;
+
+    if (paintBlockWidth == 0) {
+        paintBlockWidth = (300000 / zoomLevel);
+    } else {
+        RealTime lastTime = m_lastPaintTime;
+        while (lastTime > RealTime::fromMilliseconds(200) &&
+               paintBlockWidth > 50) {
+            paintBlockWidth /= 2;
+            lastTime = lastTime / 2;
+        }
+        while (lastTime < RealTime::fromMilliseconds(90) &&
+               paintBlockWidth < 1500) {
+            paintBlockWidth *= 2;
+            lastTime = lastTime * 2;
+        }
+    }
+
     if (paintBlockWidth < 20) paintBlockWidth = 20;
 
+    std::cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << std::endl;
+
     if (cache.validArea.width() > 0) {
 
         int vx0 = 0, vx1 = 0;
@@ -2172,6 +2201,10 @@
     std::cerr << "SpectrogramLayer::paint() returning" << std::endl;
 #endif
 
+    m_lastPaintBlockWidth = paintBlockWidth;
+    (void)gettimeofday(&tv, 0);
+    m_lastPaintTime = RealTime::fromTimeval(tv) - mainPaintStart;
+
     if (fftSuspended) fft->resume();
 }