Mercurial > hg > svgui
changeset 113:7a23edd831cb
* Various fft server improvements, including the ability to pick out data from
an existing fft cache at a smaller increment or larger fft size rather than
recalculating it (if appropriate)
author | Chris Cannam |
---|---|
date | Thu, 29 Jun 2006 16:16:49 +0000 |
parents | 43b1ca9647e1 |
children | 991de8783cf5 |
files | layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h |
diffstat | 2 files changed, 65 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp Wed Jun 28 15:42:04 2006 +0000 +++ b/layer/SpectrogramLayer.cpp Thu Jun 29 16:16:49 2006 +0000 @@ -122,22 +122,20 @@ void SpectrogramLayer::getFFTServer() { - //!!! really want to check that params differ from previous ones - if (m_fftServer) { FFTDataServer::releaseInstance(m_fftServer); m_fftServer = 0; } if (m_model) { - m_fftServer = FFTDataServer::getInstance(m_model, - m_channel, - m_windowType, - m_windowSize, - getWindowIncrement(), - m_fftSize, - true, - m_candidateFillStartFrame); + m_fftServer = FFTDataServer::getFuzzyInstance(m_model, + m_channel, + m_windowType, + m_windowSize, + getWindowIncrement(), + m_fftSize, + true, + m_candidateFillStartFrame); m_lastFillExtent = 0; @@ -1290,21 +1288,21 @@ if (q == q0i) freqMin = binfreq; if (q == q1i) freqMax = binfreq; - if (peaksOnly && !m_fftServer->isLocalPeak(s, q)) continue; + if (peaksOnly && !isFFTLocalPeak(s, q)) continue; - if (!m_fftServer->isOverThreshold(s, q, m_threshold)) continue; + if (!isFFTOverThreshold(s, q, m_threshold)) continue; float freq = binfreq; bool steady = false; - if (s < int(m_fftServer->getWidth()) - 1) { + if (s < int(getFFTWidth()) - 1) { freq = calculateFrequency(q, windowSize, windowIncrement, sr, - m_fftServer->getPhaseAt(s, q), - m_fftServer->getPhaseAt(s+1, q), + getFFTPhaseAt(s, q), + getFFTPhaseAt(s+1, q), steady); if (!haveAdj || freq < adjFreqMin) adjFreqMin = freq; @@ -1343,8 +1341,8 @@ if (m_fftServer) { - int cw = m_fftServer->getWidth(); - int ch = m_fftServer->getHeight(); + int cw = getFFTWidth(); + int ch = getFFTHeight(); min = 0.0; max = 0.0; @@ -1358,11 +1356,11 @@ float value; - value = m_fftServer->getPhaseAt(s, q); + value = getFFTPhaseAt(s, q); if (!have || value < phaseMin) { phaseMin = value; } if (!have || value > phaseMax) { phaseMax = value; } - value = m_fftServer->getMagnitudeAt(s, q); + value = getFFTMagnitudeAt(s, q); if (!have || value < min) { min = value; } if (!have || value > max) { max = value; } @@ -1639,8 +1637,9 @@ } //!!! quite wrong and won't work for layers that may be in more than one view - if (v->height() > (bins - minbin) / (m_zeroPadLevel + 1)) { + if (v->height() / 1.5 > (bins - minbin) / (m_zeroPadLevel + 1)) { if (m_zeroPadLevel != 3) { + std::cerr << v->height()/1.5 << " > " << ((bins - minbin) / (m_zeroPadLevel + 1)) << ": switching to smoothed display" << std::endl; ((SpectrogramLayer *)this)->setZeroPadLevel(3); return; } @@ -1684,8 +1683,8 @@ int s0i = int(s0 + 0.001); int s1i = int(s1); - if (s1i >= m_fftServer->getWidth()) { - if (s0i >= m_fftServer->getWidth()) { + if (s1i >= getFFTWidth()) { + if (s0i >= getFFTWidth()) { continue; } else { s1i = s0i; @@ -1694,7 +1693,7 @@ for (int s = s0i; s <= s1i; ++s) { -// if (!m_fftServer->haveSetColumnAt(s)) continue; + if (!isFFTColumnReady(s)) continue; for (size_t q = minbin; q < bins; ++q) { @@ -1703,25 +1702,25 @@ if (m_binDisplay == PeakBins || m_binDisplay == PeakFrequencies) { - if (!m_fftServer->isLocalPeak(s, q)) continue; + if (!isFFTLocalPeak(s, q)) continue; } - if (!m_fftServer->isOverThreshold(s, q, m_threshold)) continue; + if (!isFFTOverThreshold(s, q, m_threshold)) continue; float sprop = 1.0; if (s == s0i) sprop *= (s + 1) - s0; if (s == s1i) sprop *= s1 - s; if (m_binDisplay == PeakFrequencies && - s < int(m_fftServer->getWidth()) - 1) { + s < int(getFFTWidth()) - 1) { bool steady = false; float f = calculateFrequency(q, m_windowSize, increment, sr, - m_fftServer->getPhaseAt(s, q), - m_fftServer->getPhaseAt(s+1, q), + getFFTPhaseAt(s, q), + getFFTPhaseAt(s+1, q), steady); y0 = y1 = v->getYForFrequency @@ -1734,11 +1733,11 @@ float value; if (m_colourScale == PhaseColourScale) { - value = m_fftServer->getPhaseAt(s, q); + value = getFFTPhaseAt(s, q); } else if (m_normalizeColumns) { - value = m_fftServer->getNormalizedMagnitudeAt(s, q) * m_gain; + value = getFFTNormalizedMagnitudeAt(s, q) * m_gain; } else { - value = m_fftServer->getMagnitudeAt(s, q) * m_gain; + value = getFFTMagnitudeAt(s, q) * m_gain; } for (int y = y0i; y <= y1i; ++y) {
--- a/layer/SpectrogramLayer.h Wed Jun 28 15:42:04 2006 +0000 +++ b/layer/SpectrogramLayer.h Thu Jun 29 16:16:49 2006 +0000 @@ -22,6 +22,7 @@ #include "base/Thread.h" #include "model/PowerOfSqrtTwoZoomConstraint.h" #include "model/DenseTimeValueModel.h" +#include "fileio/FFTDataServer.h" #include <QMutex> #include <QWaitCondition> @@ -33,7 +34,6 @@ class QImage; class QPixmap; class QTimer; -class FFTDataServer; /** * SpectrogramLayer represents waveform data (obtained from a @@ -308,6 +308,40 @@ else if (m_windowHopLevel == 1) return (m_windowSize * 3) / 4; else return m_windowSize / (1 << (m_windowHopLevel - 1)); } + + size_t getFFTWidth() const { + return m_fftServer->getWidth(getWindowIncrement(), m_fftSize); + } + size_t getFFTHeight() const { + return m_fftServer->getHeight(getWindowIncrement(), m_fftSize); + } + float getFFTMagnitudeAt(size_t x, size_t y) const { + return m_fftServer->getMagnitudeAt(getWindowIncrement(), m_fftSize, + x, y); + } + float getFFTNormalizedMagnitudeAt(size_t x, size_t y) const { + return m_fftServer->getNormalizedMagnitudeAt(getWindowIncrement(), m_fftSize, + x, y); + } + float getFFTPhaseAt(size_t x, size_t y) const { + return m_fftServer->getPhaseAt(getWindowIncrement(), m_fftSize, + x, y); + } + void getFFTValuesAt(size_t x, size_t y, float &real, float &imag) const { + m_fftServer->getValuesAt(getWindowIncrement(), m_fftSize, + x, y, real, imag); + } + bool isFFTLocalPeak(size_t x, size_t y) const { + return m_fftServer->isLocalPeak(getWindowIncrement(), m_fftSize, + x, y); + } + bool isFFTOverThreshold(size_t x, size_t y, float threshold) const { + return m_fftServer->isOverThreshold(getWindowIncrement(), m_fftSize, + x, y, threshold); + } + bool isFFTColumnReady(size_t x) const { + return m_fftServer->isColumnReady(getWindowIncrement(), m_fftSize, x); + } }; #endif