# HG changeset patch # User Chris Cannam # Date 1233835528 0 # Node ID c860cab859041e3d0f6348aeb66abaeabf40a483 # Parent 3f9fddc890e0701718921e77bdb11f9288c03d7d * Finer locking in fft caches; fix displayed bin ranges in spectrogram diff -r 3f9fddc890e0 -r c860cab85904 layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Wed Feb 04 20:39:11 2009 +0000 +++ b/layer/SpectrogramLayer.cpp Thu Feb 05 12:05:28 2009 +0000 @@ -45,7 +45,7 @@ #include #include -//#define DEBUG_SPECTROGRAM_REPAINT 1 +#define DEBUG_SPECTROGRAM_REPAINT 1 SpectrogramLayer::SpectrogramLayer(Configuration config) : m_model(0), @@ -1321,12 +1321,10 @@ bool logarithmic = (m_frequencyScale == LogFrequencyScale); - //!!! wrong for smoothing -- wrong fft size for fft model - q0 = v->getFrequencyForY(y, minf, maxf, logarithmic); q1 = v->getFrequencyForY(y - 1, minf, maxf, logarithmic); - // Now map these on to actual bins + // Now map these on to actual bins, using raw FFT size (unsmoothed) int b0 = int((q0 * m_fftSize) / sr); int b1 = int((q1 * m_fftSize) / sr); @@ -1340,6 +1338,39 @@ return true; } + +bool +SpectrogramLayer::getSmoothedYBinRange(View *v, int y, float &q0, float &q1) const +{ + Profiler profiler("SpectrogramLayer::getSmoothedYBinRange"); + + int h = v->height(); + if (y < 0 || y >= h) return false; + + int sr = m_model->getSampleRate(); + float minf = getEffectiveMinFrequency(); + float maxf = getEffectiveMaxFrequency(); + + bool logarithmic = (m_frequencyScale == LogFrequencyScale); + + q0 = v->getFrequencyForY(y, minf, maxf, logarithmic); + q1 = v->getFrequencyForY(y - 1, minf, maxf, logarithmic); + + // Now map these on to actual bins, using zero-padded FFT size if + // appropriate + + int b0 = int((q0 * getFFTSize(v)) / sr); + int b1 = int((q1 * getFFTSize(v)) / sr); + + //!!! this is supposed to return fractions-of-bins, as it were, hence the floats + q0 = b0; + q1 = b1; + +// q0 = (b0 * sr) / m_fftSize; +// q1 = (b1 * sr) / m_fftSize; + + return true; +} bool SpectrogramLayer::getXBinRange(View *v, int x, float &s0, float &s1) const @@ -1693,8 +1724,13 @@ i != m_fftModels.end(); ++i) { delete i->second.first; } + for (PeakCacheMap::iterator i = m_peakCaches.begin(); + i != m_peakCaches.end(); ++i) { + delete i->second; + } m_fftModels.clear(); + m_peakCaches.clear(); if (m_sliceableModel) { std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << std::endl; @@ -2263,10 +2299,11 @@ for (int y = 0; y < h; ++y) { float q0 = 0, q1 = 0; - if (!getYBinRange(v, h-y-1, q0, q1)) { + if (!getSmoothedYBinRange(v, h-y-1, q0, q1)) { binfory[y] = -1; } else { binfory[y] = int(q0 + 0.0001); + cerr << "binfory[" << y << "] = " << binfory[y] << endl; } } diff -r 3f9fddc890e0 -r c860cab85904 layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Wed Feb 04 20:39:11 2009 +0000 +++ b/layer/SpectrogramLayer.h Thu Feb 05 12:05:28 2009 +0000 @@ -333,8 +333,16 @@ size_t modelStart; size_t modelEnd; }; + + // Note that the getYBin... methods return the nominal bin in the + // un-smoothed spectrogram. This is not necessarily the same bin + // as is pulled from the spectrogram and drawn at the given + // position, if the spectrogram has oversampling smoothing. Use + // getSmoothedYBinRange to obtain that. + bool getXBinRange(View *v, int x, float &windowMin, float &windowMax) const; bool getYBinRange(View *v, int y, float &freqBinMin, float &freqBinMax) const; + bool getSmoothedYBinRange(View *v, int y, float &freqBinMin, float &freqBinMax) const; bool getYBinSourceRange(View *v, int y, float &freqMin, float &freqMax) const; bool getAdjustedYBinSourceRange(View *v, int x, int y, diff -r 3f9fddc890e0 -r c860cab85904 layer/layer.pro --- a/layer/layer.pro Wed Feb 04 20:39:11 2009 +0000 +++ b/layer/layer.pro Thu Feb 05 12:05:28 2009 +0000 @@ -6,13 +6,6 @@ CONFIG += sv staticlib qt thread warn_on stl rtti exceptions QT += xml - -#!!! - debug { - CONFIG += precompile_header - PRECOMPILED_HEADER = ../stable.h - } - TARGET = svlayer DEPENDPATH += . ..