Mercurial > hg > svgui
changeset 484:a926fca1f280
* Make use of peak cache in spectrogram
author | Chris Cannam |
---|---|
date | Wed, 04 Feb 2009 15:03:42 +0000 |
parents | 18f38f564d7c |
children | 3f9fddc890e0 |
files | layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h |
diffstat | 2 files changed, 65 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp Wed Feb 04 13:09:02 2009 +0000 +++ b/layer/SpectrogramLayer.cpp Wed Feb 04 15:03:42 2009 +0000 @@ -4,7 +4,7 @@ Sonic Visualiser An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. - This file copyright 2006 Chris Cannam and QMUL. + This file copyright 2006-2009 Chris Cannam and QMUL. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -26,6 +26,7 @@ #include "widgets/CommandHistory.h" #include "ColourMapper.h" #include "ImageRegionFinder.h" +#include "data/model/Dense3DModelPeakCache.h" #include <QPainter> #include <QImage> @@ -995,6 +996,9 @@ delete m_fftModels[v].first; m_fftModels.erase(v); + + delete m_peakCaches[v]; + m_peakCaches.erase(v); } } else { @@ -1608,6 +1612,8 @@ #endif delete m_fftModels[v].first; m_fftModels.erase(v); + delete m_peakCaches[v]; + m_peakCaches.erase(v); } else { #ifdef DEBUG_SPECTROGRAM_REPAINT std::cerr << "SpectrogramLayer::getFFTModel(" << v << "): Found a good model of height " << m_fftModels[v].first->getHeight() << std::endl; @@ -1660,6 +1666,17 @@ return m_fftModels[v].first; } +Dense3DModelPeakCache * +SpectrogramLayer::getPeakCache(const View *v) const +{ + if (!m_peakCaches[v]) { + FFTModel *f = getFFTModel(v); + if (!f) return 0; + m_peakCaches[v] = new Dense3DModelPeakCache(f, 8); + } + return m_peakCaches[v]; +} + const Model * SpectrogramLayer::getSliceableModel() const { @@ -1778,12 +1795,13 @@ const_cast<SpectrogramLayer *>(this)->Layer::setLayerDormant(v, false); size_t fftSize = getFFTSize(v); +/* FFTModel *fft = getFFTModel(v); if (!fft) { std::cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << std::endl; return; } - +*/ ImageCache &cache = m_imageCaches[v]; #ifdef DEBUG_SPECTROGRAM_REPAINT @@ -2211,6 +2229,8 @@ int binforx[bufwid]; int binfory[h]; + bool usePeaksCache = false; + if (bufferBinResolution) { for (int x = 0; x < bufwid; ++x) { binforx[x] = (leftBoundaryFrame / increment) + x; @@ -2229,6 +2249,7 @@ if (m_drawBuffer.width() < bufwid || m_drawBuffer.height() < h) { m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8); } + usePeaksCache = (increment * 8) < zoomLevel; } m_drawBuffer.setNumColors(256); @@ -2247,7 +2268,7 @@ } } - paintDrawBuffer(v, fft, bufwid, h, binforx, binfory); + paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache); /* for (int x = 0; x < w / xPixelRatio; ++x) { @@ -2404,11 +2425,11 @@ bool SpectrogramLayer::paintDrawBuffer(View *v, - FFTModel *fft, int w, int h, int *binforx, - int *binfory) const + int *binfory, + bool usePeaksCache) const { Profiler profiler("SpectrogramLayer::paintDrawBuffer"); @@ -2419,17 +2440,33 @@ if (minbin < 0) minbin = 0; if (maxbin < 0) maxbin = minbin+1; + DenseThreeDimensionalModel *sourceModel = 0; + FFTModel *fft = 0; + int divisor = 1; + cerr << "Note: bin display = " << m_binDisplay << ", w = " << w << ", binforx[" << w-1 << "] = " << binforx[w-1] << ", binforx[0] = " << binforx[0] << endl; + if (usePeaksCache) { //!!! + sourceModel = getPeakCache(v); + divisor = 8;//!!! + minbin = 0; + maxbin = sourceModel->getHeight(); + } else { + sourceModel = fft = getFFTModel(v); + } + + if (!sourceModel) return false; + int psx = -1; float values[maxbin - minbin + 1]; + DenseThreeDimensionalModel::Column c; float peaks[h]; for (int x = 0; x < w; ++x) { if (binforx[x] < 0) continue; - int sx0 = binforx[x]; + int sx0 = binforx[x] / divisor; int sx1 = sx0; - if (x+1 < w) sx1 = binforx[x+1]; + if (x+1 < w) sx1 = binforx[x+1] / divisor; if (sx0 < 0) sx0 = sx1 - 1; if (sx0 < 0) continue; if (sx1 <= sx0) sx1 = sx0 + 1; @@ -2438,10 +2475,10 @@ for (int sx = sx0; sx < sx1; ++sx) { - if (sx < 0 || sx >= int(fft->getWidth())) continue; + if (sx < 0 || sx >= int(sourceModel->getWidth())) continue; if (!m_synchronous) { - if (!fft->isColumnAvailable(sx)) { + if (!sourceModel->isColumnAvailable(sx)) { #ifdef DEBUG_SPECTROGRAM_REPAINT std::cerr << "Met unavailable column at col " << sx << std::endl; #endif @@ -2450,8 +2487,13 @@ } if (sx != psx) { - cerr << "Retrieving column " << sx << endl; - fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); + if (fft) { + cerr << "Retrieving column " << sx << " from fft directly" << endl; + fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); + } else { + cerr << "Retrieving column " << sx << " from peaks cache" << endl; + c = sourceModel->getColumn(sx); + } psx = sx; } @@ -2472,7 +2514,10 @@ for (int sy = sy0; sy < sy1; ++sy) { - float value = values[sy - minbin]; + float value = 0.f; + if (fft) value = values[sy - minbin]; + else value = c[sy]; + /* if (m_colourScale != PhaseColourScale) { if (!m_normalizeColumns) {
--- a/layer/SpectrogramLayer.h Wed Feb 04 13:09:02 2009 +0000 +++ b/layer/SpectrogramLayer.h Wed Feb 04 15:03:42 2009 +0000 @@ -36,6 +36,7 @@ class QPixmap; class QTimer; class FFTModel; +class Dense3DModelPeakCache; /** @@ -235,7 +236,7 @@ protected: const DenseTimeValueModel *m_model; // I do not own this - + int m_channel; size_t m_windowSize; WindowType m_windowType; @@ -352,12 +353,14 @@ size_t getZeroPadLevel(const View *v) const; size_t getFFTSize(const View *v) const; FFTModel *getFFTModel(const View *v) const; + Dense3DModelPeakCache *getPeakCache(const View *v) const; void invalidateFFTModels(); typedef std::pair<FFTModel *, int> FFTFillPair; // model, last fill typedef std::map<const View *, FFTFillPair> ViewFFTMap; - typedef std::vector<float> FloatVector; + typedef std::map<const View *, Dense3DModelPeakCache *> PeakCacheMap; mutable ViewFFTMap m_fftModels; + mutable PeakCacheMap m_peakCaches; mutable Model *m_sliceableModel; class MagnitudeRange { @@ -413,8 +416,9 @@ mutable std::vector<MagnitudeRange> m_columnMags; void invalidateMagnitudes(); bool updateViewMagnitudes(View *v) const; - bool paintDrawBuffer(View *v, FFTModel *fft, int w, int h, - int *binforx, int *binfory) const; + bool paintDrawBuffer(View *v, int w, int h, + int *binforx, int *binfory, + bool usePeaksCache) const; //!!! phasing this one out: bool paintColumnValues(View *v, FFTModel *fft, int x0, int x, int minbin, int maxbin,