Mercurial > hg > svgui
diff layer/SpectrogramLayer.cpp @ 382:06b5f110c5d2
* Speed up spectrogram painting by releasing mutex in FFTDataServer
while calculating data prior to writing it, and by adding whole-column
value query methods to FFT objects
* Add paint cache to Thumbwheel -- repaints of this widget were slowing
down the whole spectrogram repaint
* More uses of MutexLocker (named and with debug) and more profile
points
* Make startup much quicker some of the time, with OSC server in place
author | Chris Cannam |
---|---|
date | Thu, 08 May 2008 14:46:22 +0000 |
parents | e1a9e478b7f2 |
children | b35184d0dfe5 |
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp Tue Apr 29 11:07:14 2008 +0000 +++ b/layer/SpectrogramLayer.cpp Thu May 08 14:46:22 2008 +0000 @@ -1239,6 +1239,8 @@ bool SpectrogramLayer::getYBinRange(View *v, int y, float &q0, float &q1) const { + Profiler profiler("SpectrogramLayer::getYBinRange"); + int h = v->height(); if (y < 0 || y >= h) return false; @@ -1555,7 +1557,7 @@ m_windowSize, getWindowIncrement(), fftSize, - true, + true, // polar StorageAdviser::SpeedCritical, m_candidateFillStartFrame); @@ -2036,7 +2038,9 @@ float ymag[h]; float ydiv[h]; - float yval[maxbin + 1]; //!!! cache this? + + float yval[maxbin - minbin + 1]; + float values[maxbin - minbin + 1]; size_t increment = getWindowIncrement(); @@ -2044,9 +2048,9 @@ for (size_t q = minbin; q <= maxbin; ++q) { float f0 = (float(q) * sr) / fftSize; - yval[q] = v->getYForFrequency(f0, displayMinFreq, displayMaxFreq, - logarithmic); -// std::cerr << "min: " << minFreq << ", max: " << maxFreq << ", yval[" << q << "]: " << yval[q] << std::endl; + yval[q - minbin] = + v->getYForFrequency(f0, displayMinFreq, displayMaxFreq, + logarithmic); } MagnitudeRange overallMag = m_viewMags[v]; @@ -2079,8 +2083,13 @@ size_t pixels = 0; #endif + Profiler outerprof("SpectrogramLayer::paint: all cols"); + FFTModel::PeakSet peaks; + for (int x = 0; x < w; ++x) { + Profiler innerprof("SpectrogramLayer::paint: 1 pixel column"); + if (runOutOfData) { #ifdef DEBUG_SPECTROGRAM_REPAINT std::cerr << "Run out of data -- dropping out of loop" << std::endl; @@ -2133,20 +2142,34 @@ fftSuspended = true; } + Profiler innerprof2("SpectrogramLayer::paint: 1 data column"); + MagnitudeRange mag; - FFTModel::PeakSet peaks; - if (m_binDisplay == PeakFrequencies && - s < int(fft->getWidth()) - 1) { - peaks = fft->getPeakFrequencies(FFTModel::AllPeaks, - s, - minbin, maxbin - 1); + if (m_binDisplay == PeakFrequencies) { + if (s < int(fft->getWidth()) - 1) { + peaks = fft->getPeakFrequencies(FFTModel::AllPeaks, + s, + minbin, maxbin - 1); + } else { + peaks.clear(); + } } + + if (m_colourScale == PhaseColourScale) { + fft->getPhasesAt(s, values, minbin, maxbin - minbin + 1); + } else if (m_normalizeColumns) { + fft->getNormalizedMagnitudesAt(s, values, minbin, maxbin - minbin + 1); + } else { + fft->getMagnitudesAt(s, values, minbin, maxbin - minbin + 1); + } for (size_t q = minbin; q < maxbin; ++q) { - float y0 = yval[q + 1]; - float y1 = yval[q]; + Profiler innerprof3("SpectrogramLayer::paint: 1 bin"); + + float y0 = yval[q + 1 - minbin]; + float y1 = yval[q - minbin]; if (m_binDisplay == PeakBins) { if (!fft->isLocalPeak(s, q)) continue; @@ -2160,7 +2183,7 @@ continue; } - float sprop = 1.0; + float sprop = 1.f; if (s == s0i) sprop *= (s + 1) - s0; if (s == s1i) sprop *= s1 - s; @@ -2169,11 +2192,24 @@ (peaks[q], displayMinFreq, displayMaxFreq, logarithmic); } - int y0i = int(y0 + 0.001); + int y0i = int(y0 + 0.001f); int y1i = int(y1); - float value; + float value = values[q - minbin]; + + if (m_colourScale != PhaseColourScale) { + if (!m_normalizeColumns) { + value /= (m_fftSize/2.f); + } + mag.sample(value); + value *= m_gain; + } + + float v2 = value; + +//!!! + value = 0.f; if (m_colourScale == PhaseColourScale) { value = fft->getPhaseAt(s, q); } else if (m_normalizeColumns) { @@ -2186,10 +2222,14 @@ value *= m_gain; } + if (value != v2) { + std::cout << "old = " << value << " new = " << v2 << " at y = " << q << std::endl; + } + if (interpolate) { int ypi = y0i; - if (q < maxbin - 1) ypi = int(yval[q + 2]); + if (q < maxbin - 1) ypi = int(yval[q + 2 - minbin]); for (int y = ypi; y <= y1i; ++y) { @@ -2200,7 +2240,7 @@ if (ypi < y0i && y <= y0i) { - float half = float(y0i - ypi) / 2; + float half = float(y0i - ypi) / 2.f; float dist = y - (ypi + half); if (dist >= 0) { @@ -2210,7 +2250,7 @@ } else { if (y1i > y0i) { - float half = float(y1i - y0i) / 2; + float half = float(y1i - y0i) / 2.f; float dist = y - (y0i + half); if (dist >= 0) { @@ -2238,7 +2278,7 @@ if (y < 0 || y >= h) continue; float yprop = sprop; - if (y == y0i) yprop *= (y + 1) - y0; + if (y == y0i) yprop *= (y + 1.f) - y0; if (y == y1i) yprop *= y1 - y; ymag[y] += yprop * value; ydiv[y] += yprop; @@ -2266,6 +2306,8 @@ } } + Profiler drawbufferprof("SpectrogramLayer::paint: set buffer pixels"); + for (int y = 0; y < h; ++y) { if (ydiv[y] > 0.0) { @@ -2301,7 +2343,9 @@ #endif } - Profiler profiler2("SpectrogramLayer::paint: draw image", true); + outerprof.end(); + + Profiler profiler2("SpectrogramLayer::paint: draw image"); if (recreateWholePixmapCache) { std::cerr << "Recreating pixmap cache: width = " << v->width() @@ -2384,6 +2428,8 @@ void SpectrogramLayer::illuminateLocalFeatures(View *v, QPainter &paint) const { + Profiler profiler("SpectrogramLayer::illuminateLocalFeatures"); + QPoint localPos; if (!v->shouldIlluminateLocalFeatures(this, localPos) || !m_model) { return; @@ -2823,7 +2869,7 @@ return; } - Profiler profiler("SpectrogramLayer::paintVerticalScale", true); + Profiler profiler("SpectrogramLayer::paintVerticalScale"); //!!! cache this?