# HG changeset patch # User Chris Cannam # Date 1562064592 -3600 # Node ID 886c1cd48f9d6fdec6e456134a2ca626dee8ffc2 # Parent dbff4b290bf0f0e80b40d2d829b45bdad270bd2c Further layer updates for ModelById diff -r dbff4b290bf0 -r 886c1cd48f9d layer/Colour3DPlotLayer.cpp --- a/layer/Colour3DPlotLayer.cpp Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/Colour3DPlotLayer.cpp Tue Jul 02 11:49:52 2019 +0100 @@ -183,8 +183,10 @@ invalidateRenderers(); invalidateMagnitudes(); - delete m_peakCache; - m_peakCache = nullptr; + if (!m_peakCache.isNone()) { + ModelById::release(m_peakCache); + m_peakCache = {}; + } } void @@ -206,11 +208,14 @@ m_viewMags.clear(); } -Dense3DModelPeakCache * +ModelId Colour3DPlotLayer::getPeakCache() const { - if (!m_peakCache) { - m_peakCache = new Dense3DModelPeakCache(m_model, m_peakCacheDivisor); + if (m_peakCache.isNone()) { + auto peakCache = std::make_shared + (m_model, m_peakCacheDivisor); + ModelById::add(peakCache); + m_peakCache = peakCache->getId(); } return m_peakCache; } diff -r dbff4b290bf0 -r 886c1cd48f9d layer/Colour3DPlotLayer.h --- a/layer/Colour3DPlotLayer.h Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/Colour3DPlotLayer.h Tue Jul 02 11:49:52 2019 +0100 @@ -187,10 +187,10 @@ static std::pair convertToColumnNorm(int value); static int convertFromColumnNorm(ColumnNormalization norm, bool visible); - mutable Dense3DModelPeakCache *m_peakCache; + mutable ModelId m_peakCache; const int m_peakCacheDivisor; void invalidatePeakCache(); - Dense3DModelPeakCache *getPeakCache() const; + ModelId getPeakCache() const; typedef std::map ViewMagMap; // key is view id mutable ViewMagMap m_viewMags; diff -r dbff4b290bf0 -r 886c1cd48f9d layer/Colour3DPlotRenderer.cpp --- a/layer/Colour3DPlotRenderer.cpp Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/Colour3DPlotRenderer.cpp Tue Jul 02 11:49:52 2019 +0100 @@ -426,7 +426,12 @@ if (fullColumn.empty()) { if (peakCacheIndex >= 0) { - fullColumn = m_sources.peakCaches[peakCacheIndex]->getColumn(sx); + auto peakCache = ModelById::getAs + (m_sources.peakCaches[peakCacheIndex]); + if (!peakCache) { + return vector(nbins, 0.f); + } + fullColumn = peakCache->getColumn(sx); } else { auto model = ModelById::getAs (m_sources.source); @@ -621,7 +626,10 @@ int binResolution = model->getResolution(); for (int ix = 0; in_range_for(m_sources.peakCaches, ix); ++ix) { - int bpp = m_sources.peakCaches[ix]->getColumnsPerPeak(); + auto peakCache = ModelById::getAs + (m_sources.peakCaches[ix]); + if (!peakCache) continue; + int bpp = peakCache->getColumnsPerPeak(); ZoomLevel equivZoom(ZoomLevel::FramesPerPixel, binResolution * bpp); #ifdef DEBUG_COLOUR_PLOT_REPAINT SVDEBUG << "getPreferredPeakCache: zoomLevel = " << zoomLevel @@ -956,14 +964,24 @@ Profiler profiler("Colour3DPlotRenderer::renderDrawBuffer"); int divisor = 1; - auto model = ModelById::getAs(m_sources.source); - if (!model) return 0; + + std::shared_ptr sourceModel; + + if (peakCacheIndex >= 0) { + auto peakCache = ModelById::getAs + (m_sources.peakCaches[peakCacheIndex]); + if (peakCache) { + divisor = peakCache->getColumnsPerPeak(); + sourceModel = peakCache; + } + } + + if (!sourceModel) { + sourceModel = ModelById::getAs + (m_sources.source); + } - const DenseThreeDimensionalModel *sourceModel = model.get(); - if (peakCacheIndex >= 0) { - divisor = m_sources.peakCaches[peakCacheIndex]->getColumnsPerPeak(); - sourceModel = m_sources.peakCaches[peakCacheIndex]; - } + if (!sourceModel) return 0; #ifdef DEBUG_COLOUR_PLOT_REPAINT SVDEBUG << "renderDrawBuffer: w = " << w << ", h = " << h diff -r dbff4b290bf0 -r 886c1cd48f9d layer/Colour3DPlotRenderer.h --- a/layer/Colour3DPlotRenderer.h Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/Colour3DPlotRenderer.h Tue Jul 02 11:49:52 2019 +0100 @@ -54,8 +54,8 @@ // These must all outlive this class const VerticalBinLayer *verticalBinLayer; // always ModelId source; // always; a DenseThreeDimensionalModel - ModelId fft; // optionally - std::vector peakCaches; // zero or more + ModelId fft; // optionally; an FFTModel; used for phase/peak-freq modes + std::vector peakCaches; // zero or more }; struct Parameters { diff -r dbff4b290bf0 -r 886c1cd48f9d layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/SpectrogramLayer.cpp Tue Jul 02 11:49:52 2019 +0100 @@ -82,8 +82,6 @@ m_synchronous(false), m_haveDetailedScale(false), m_exiting(false), - m_wholeCache(nullptr), - m_peakCache(nullptr), m_peakCacheDivisor(8) { QString colourConfigName = "spectrogram-colour"; @@ -138,17 +136,13 @@ void SpectrogramLayer::deleteDerivedModels() { - if (m_fftModel) m_fftModel->aboutToDelete(); - if (m_peakCache) m_peakCache->aboutToDelete(); - if (m_wholeCache) m_wholeCache->aboutToDelete(); - - delete m_fftModel; - delete m_peakCache; - delete m_wholeCache; - - m_fftModel = nullptr; - m_peakCache = nullptr; - m_wholeCache = nullptr; + ModelById::release(m_fftModel); + ModelById::release(m_peakCache); + ModelById::release(m_wholeCache); + + m_fftModel = {}; + m_peakCache = {}; + m_wholeCache = {}; } pair @@ -1107,7 +1101,10 @@ double SpectrogramLayer::getEffectiveMinFrequency() const { - sv_samplerate_t sr = m_model->getSampleRate(); + auto model = ModelById::getAs(m_model); + if (!model) return 0.0; + + sv_samplerate_t sr = model->getSampleRate(); double minf = double(sr) / getFFTSize(); if (m_minFrequency > 0.0) { @@ -1122,7 +1119,10 @@ double SpectrogramLayer::getEffectiveMaxFrequency() const { - sv_samplerate_t sr = m_model->getSampleRate(); + auto model = ModelById::getAs(m_model); + if (!model) return 0.0; + + sv_samplerate_t sr = model->getSampleRate(); double maxf = double(sr) / 2; if (m_maxFrequency > 0.0) { @@ -1148,10 +1148,13 @@ double SpectrogramLayer::getYForBin(const LayerGeometryProvider *v, double bin) const { + auto model = ModelById::getAs(m_model); + if (!model) return 0.0; + double minf = getEffectiveMinFrequency(); double maxf = getEffectiveMaxFrequency(); bool logarithmic = (m_binScale == BinScale::Log); - sv_samplerate_t sr = m_model->getSampleRate(); + sv_samplerate_t sr = model->getSampleRate(); double freq = (bin * sr) / getFFTSize(); @@ -1163,7 +1166,10 @@ double SpectrogramLayer::getBinForY(const LayerGeometryProvider *v, double y) const { - sv_samplerate_t sr = m_model->getSampleRate(); + auto model = ModelById::getAs(m_model); + if (!model) return 0.0; + + sv_samplerate_t sr = model->getSampleRate(); double minf = getEffectiveMinFrequency(); double maxf = getEffectiveMaxFrequency(); @@ -1180,8 +1186,11 @@ bool SpectrogramLayer::getXBinRange(LayerGeometryProvider *v, int x, double &s0, double &s1) const { - sv_frame_t modelStart = m_model->getStartFrame(); - sv_frame_t modelEnd = m_model->getEndFrame(); + auto model = ModelById::getAs(m_model); + if (!model) return false; + + sv_frame_t modelStart = model->getStartFrame(); + sv_frame_t modelEnd = model->getEndFrame(); // Each pixel column covers an exact range of sample frames: sv_frame_t f0 = v->getFrameForX(x) - modelStart; @@ -1204,6 +1213,9 @@ bool SpectrogramLayer::getXBinSourceRange(LayerGeometryProvider *v, int x, RealTime &min, RealTime &max) const { + auto model = ModelById::getAs(m_model); + if (!model) return false; + double s0 = 0, s1 = 0; if (!getXBinRange(v, x, s0, s1)) return false; @@ -1215,8 +1227,8 @@ int w1 = s1i * windowIncrement + windowIncrement + (m_windowSize - windowIncrement)/2 - 1; - min = RealTime::frame2RealTime(w0, m_model->getSampleRate()); - max = RealTime::frame2RealTime(w1, m_model->getSampleRate()); + min = RealTime::frame2RealTime(w0, model->getSampleRate()); + max = RealTime::frame2RealTime(w1, model->getSampleRate()); return true; } @@ -1224,13 +1236,16 @@ SpectrogramLayer::getYBinSourceRange(LayerGeometryProvider *v, int y, double &freqMin, double &freqMax) const { + auto model = ModelById::getAs(m_model); + if (!model) return false; + double q0 = 0, q1 = 0; if (!getYBinRange(v, y, q0, q1)) return false; int q0i = int(q0 + 0.001); int q1i = int(q1); - sv_samplerate_t sr = m_model->getSampleRate(); + sv_samplerate_t sr = model->getSampleRate(); for (int q = q0i; q <= q1i; ++q) { if (q == q0i) freqMin = (sr * q) / getFFTSize(); @@ -1245,11 +1260,12 @@ double &adjFreqMin, double &adjFreqMax) const { - if (!m_model || !m_model->isOK() || !m_model->isReady()) { + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK() || !model->isReady()) { return false; } - FFTModel *fft = getFFTModel(); + auto fft = ModelById::getAs(m_fftModel); if (!fft) return false; double s0 = 0, s1 = 0; @@ -1264,7 +1280,7 @@ int q0i = int(q0 + 0.001); int q1i = int(q1); - sv_samplerate_t sr = m_model->getSampleRate(); + sv_samplerate_t sr = model->getSampleRate(); bool haveAdj = false; @@ -1312,7 +1328,8 @@ double &min, double &max, double &phaseMin, double &phaseMax) const { - if (!m_model || !m_model->isOK() || !m_model->isReady()) { + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK() || !model->isReady()) { return false; } @@ -1330,7 +1347,7 @@ bool rv = false; - FFTModel *fft = getFFTModel(); + auto fft = ModelById::getAs(m_fftModel); if (fft) { @@ -1375,55 +1392,55 @@ { SVDEBUG << "SpectrogramLayer::recreateFFTModel called" << endl; - if (!m_model || !m_model->isOK()) { - emit sliceableModelReplaced(m_fftModel, nullptr); - deleteDerivedModels(); - return; + { // scope, avoid hanging on to this pointer + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK()) { + deleteDerivedModels(); + return; + } } - - if (m_fftModel) m_fftModel->aboutToDelete(); - if (m_peakCache) m_peakCache->aboutToDelete(); - delete m_peakCache; - m_peakCache = nullptr; - - if (m_wholeCache) m_wholeCache->aboutToDelete(); - delete m_wholeCache; - m_wholeCache = nullptr; - - FFTModel *newModel = new FFTModel(m_model, - m_channel, - m_windowType, - m_windowSize, - getWindowIncrement(), - getFFTSize()); - - if (!newModel->isOK()) { + deleteDerivedModels(); + + auto newFFTModel = std::make_shared(m_model, + m_channel, + m_windowType, + m_windowSize, + getWindowIncrement(), + getFFTSize()); + + if (!newFFTModel->isOK()) { QMessageBox::critical (nullptr, tr("FFT cache failed"), tr("Failed to create the FFT model for this spectrogram.\n" "There may be insufficient memory or disc space to continue.")); - delete newModel; - delete m_fftModel; - m_fftModel = nullptr; return; } - FFTModel *oldModel = m_fftModel; - m_fftModel = newModel; + ModelById::add(newFFTModel); + m_fftModel = newFFTModel->getId(); bool createWholeCache = false; checkCacheSpace(&m_peakCacheDivisor, &createWholeCache); if (createWholeCache) { - m_wholeCache = new Dense3DModelPeakCache(m_fftModel, 1); - m_peakCache = new Dense3DModelPeakCache(m_wholeCache, m_peakCacheDivisor); + + auto whole = std::make_shared(m_fftModel, 1); + ModelById::add(whole); + m_wholeCache = whole->getId(); + + auto peaks = std::make_shared(m_wholeCache, + m_peakCacheDivisor); + ModelById::add(peaks); + m_peakCache = peaks->getId(); + } else { - m_peakCache = new Dense3DModelPeakCache(m_fftModel, m_peakCacheDivisor); + + auto peaks = std::make_shared(m_fftModel, + m_peakCacheDivisor); + ModelById::add(peaks); + m_peakCache = peaks->getId(); } - - emit sliceableModelReplaced(oldModel, m_fftModel); - delete oldModel; } void @@ -1432,12 +1449,13 @@ { *suggestedPeakDivisor = 8; *createWholeCache = false; - - if (!m_fftModel) return; + + auto fftModel = ModelById::getAs(m_fftModel); + if (!fftModel) return; size_t sz = - size_t(m_fftModel->getWidth()) * - size_t(m_fftModel->getHeight()) * + size_t(fftModel->getWidth()) * + size_t(fftModel->getHeight()) * sizeof(float); try { @@ -1467,7 +1485,7 @@ } } -const Model * +ModelId SpectrogramLayer::getSliceableModel() const { return m_fftModel; @@ -1497,10 +1515,10 @@ Colour3DPlotRenderer::Sources sources; sources.verticalBinLayer = this; - sources.fft = getFFTModel(); + sources.fft = m_fftModel; sources.source = sources.fft; - if (m_peakCache) sources.peakCaches.push_back(m_peakCache); - if (m_wholeCache) sources.peakCaches.push_back(m_wholeCache); + if (!m_peakCache.isNone()) sources.peakCaches.push_back(m_peakCache); + if (!m_wholeCache.isNone()) sources.peakCaches.push_back(m_wholeCache); ColourScale::Parameters cparams; cparams.colourMap = m_colourMap; @@ -1636,7 +1654,8 @@ cerr << "SpectrogramLayer::paint(): rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl; #endif - if (!m_model || !m_model->isOK() || !m_model->isReady()) { + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK() || !model->isReady()) { return; } @@ -1650,8 +1669,10 @@ { Profiler profiler("SpectrogramLayer::illuminateLocalFeatures"); + auto model = ModelById::getAs(m_model); + QPoint localPos; - if (!v->shouldIlluminateLocalFeatures(this, localPos) || !m_model) { + if (!v->shouldIlluminateLocalFeatures(this, localPos) || !model) { return; } @@ -1709,8 +1730,9 @@ int SpectrogramLayer::getCompletion(LayerGeometryProvider *) const { - if (!m_fftModel) return 100; - int completion = m_fftModel->getCompletion(); + auto fftModel = ModelById::getAs(m_fftModel); + if (!fftModel) return 100; + int completion = fftModel->getCompletion(); #ifdef DEBUG_SPECTROGRAM_REPAINT cerr << "SpectrogramLayer::getCompletion: completion = " << completion << endl; #endif @@ -1720,17 +1742,19 @@ QString SpectrogramLayer::getError(LayerGeometryProvider *) const { - if (!m_fftModel) return ""; - return m_fftModel->getError(); + auto fftModel = ModelById::getAs(m_fftModel); + if (!fftModel) return ""; + return fftModel->getError(); } bool SpectrogramLayer::getValueExtents(double &min, double &max, bool &logarithmic, QString &unit) const { - if (!m_model) return false; - - sv_samplerate_t sr = m_model->getSampleRate(); + auto model = ModelById::getAs(m_model); + if (!model) return false; + + sv_samplerate_t sr = model->getSampleRate(); min = double(sr) / getFFTSize(); max = double(sr) / 2; @@ -1752,12 +1776,13 @@ bool SpectrogramLayer::setDisplayExtents(double min, double max) { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; // SVDEBUG << "SpectrogramLayer::setDisplayExtents: " << min << "->" << max << endl; if (min < 0) min = 0; - if (max > m_model->getSampleRate()/2.0) max = m_model->getSampleRate()/2.0; + if (max > model->getSampleRate()/2.0) max = model->getSampleRate()/2.0; int minf = int(lrint(min)); int maxf = int(lrint(max)); @@ -1832,6 +1857,11 @@ QPoint cursorPos, vector &extents) const { + // Qt 5.13 deprecates QFontMetrics::width(), but its suggested + // replacement (horizontalAdvance) was only added in Qt 5.11 + // which is too new for us +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + QRect vertical(cursorPos.x() - 12, 0, 12, v->getPaintHeight()); extents.push_back(vertical); @@ -1870,6 +1900,9 @@ SpectrogramLayer::paintCrosshairs(LayerGeometryProvider *v, QPainter &paint, QPoint cursorPos) const { + auto model = ModelById::getAs(m_model); + if (!model) return; + paint.save(); int sw = getVerticalScaleWidth(v, m_haveDetailedScale, paint); @@ -1886,35 +1919,39 @@ double fundamental = getFrequencyForY(v, cursorPos.y()); - PaintAssistant::drawVisibleText(v, paint, - sw + 2, - cursorPos.y() - 2, - QString("%1 Hz").arg(fundamental), - PaintAssistant::OutlinedText); + PaintAssistant::drawVisibleText + (v, paint, + sw + 2, + cursorPos.y() - 2, + QString("%1 Hz").arg(fundamental), + PaintAssistant::OutlinedText); if (Pitch::isFrequencyInMidiRange(fundamental)) { QString pitchLabel = Pitch::getPitchLabelForFrequency(fundamental); - PaintAssistant::drawVisibleText(v, paint, - sw + 2, - cursorPos.y() + paint.fontMetrics().ascent() + 2, - pitchLabel, - PaintAssistant::OutlinedText); + PaintAssistant::drawVisibleText + (v, paint, + sw + 2, + cursorPos.y() + paint.fontMetrics().ascent() + 2, + pitchLabel, + PaintAssistant::OutlinedText); } sv_frame_t frame = v->getFrameForX(cursorPos.x()); - RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate()); + RealTime rt = RealTime::frame2RealTime(frame, model->getSampleRate()); QString rtLabel = QString("%1 s").arg(rt.toText(true).c_str()); QString frameLabel = QString("%1").arg(frame); - PaintAssistant::drawVisibleText(v, paint, - cursorPos.x() - paint.fontMetrics().width(frameLabel) - 2, - v->getPaintHeight() - 2, - frameLabel, - PaintAssistant::OutlinedText); - PaintAssistant::drawVisibleText(v, paint, - cursorPos.x() + 2, - v->getPaintHeight() - 2, - rtLabel, - PaintAssistant::OutlinedText); + PaintAssistant::drawVisibleText + (v, paint, + cursorPos.x() - paint.fontMetrics().width(frameLabel) - 2, + v->getPaintHeight() - 2, + frameLabel, + PaintAssistant::OutlinedText); + PaintAssistant::drawVisibleText + (v, paint, + cursorPos.x() + 2, + v->getPaintHeight() - 2, + rtLabel, + PaintAssistant::OutlinedText); int harmonic = 2; @@ -1950,7 +1987,8 @@ int x = pos.x(); int y = pos.y(); - if (!m_model || !m_model->isOK()) return ""; + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK()) return ""; double magMin = 0, magMax = 0; double phaseMin = 0, phaseMax = 0; @@ -2069,7 +2107,8 @@ int SpectrogramLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool detailed, QPainter &paint) const { - if (!m_model || !m_model->isOK()) return 0; + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK()) return 0; int cw = 0; if (detailed) cw = getColourScaleWidth(paint); @@ -2077,7 +2116,7 @@ int tw = paint.fontMetrics().width(QString("%1") .arg(m_maxFrequency > 0 ? m_maxFrequency - 1 : - m_model->getSampleRate() / 2)); + model->getSampleRate() / 2)); int fw = paint.fontMetrics().width(tr("43Hz")); if (tw < fw) tw = fw; @@ -2091,7 +2130,8 @@ SpectrogramLayer::paintVerticalScale(LayerGeometryProvider *v, bool detailed, QPainter &paint, QRect rect) const { - if (!m_model || !m_model->isOK()) { + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK()) { return; } @@ -2111,7 +2151,7 @@ int pkw = (m_binScale == BinScale::Log ? 10 : 0); int bins = getFFTSize() / 2; - sv_samplerate_t sr = m_model->getSampleRate(); + sv_samplerate_t sr = model->getSampleRate(); if (m_maxFrequency > 0) { bins = int((double(m_maxFrequency) * getFFTSize()) / sr + 0.1); @@ -2381,9 +2421,10 @@ int SpectrogramLayer::getVerticalZoomSteps(int &defaultStep) const { - if (!m_model) return 0; - - sv_samplerate_t sr = m_model->getSampleRate(); + auto model = ModelById::getAs(m_model); + if (!model) return 0; + + sv_samplerate_t sr = model->getSampleRate(); SpectrogramRangeMapper mapper(sr, getFFTSize()); @@ -2404,12 +2445,13 @@ int SpectrogramLayer::getCurrentVerticalZoomStep() const { - if (!m_model) return 0; + auto model = ModelById::getAs(m_model); + if (!model) return 0; double dmin, dmax; getDisplayExtents(dmin, dmax); - SpectrogramRangeMapper mapper(m_model->getSampleRate(), getFFTSize()); + SpectrogramRangeMapper mapper(model->getSampleRate(), getFFTSize()); int n = mapper.getPositionForValue(dmax - dmin); // SVDEBUG << "SpectrogramLayer::getCurrentVerticalZoomStep: " << n << endl; return n; @@ -2418,14 +2460,15 @@ void SpectrogramLayer::setVerticalZoomStep(int step) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; double dmin = m_minFrequency, dmax = m_maxFrequency; // getDisplayExtents(dmin, dmax); // cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << endl; - sv_samplerate_t sr = m_model->getSampleRate(); + sv_samplerate_t sr = model->getSampleRate(); SpectrogramRangeMapper mapper(sr, getFFTSize()); double newdist = mapper.getValueForPosition(step); @@ -2486,8 +2529,9 @@ RangeMapper * SpectrogramLayer::getNewVerticalZoomRangeMapper() const { - if (!m_model) return nullptr; - return new SpectrogramRangeMapper(m_model->getSampleRate(), getFFTSize()); + auto model = ModelById::getAs(m_model); + if (!model) return nullptr; + return new SpectrogramRangeMapper(model->getSampleRate(), getFFTSize()); } void diff -r dbff4b290bf0 -r 886c1cd48f9d layer/SpectrogramLayer.h --- a/layer/SpectrogramLayer.h Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/SpectrogramLayer.h Tue Jul 02 11:49:52 2019 +0100 @@ -306,10 +306,11 @@ int getFFTSize() const; // m_windowSize * getOversampling() + // We take responsibility for registering/deregistering these + // models and caches with ModelById ModelId m_fftModel; // an FFTModel - Dense3DModelPeakCache *m_wholeCache; - Dense3DModelPeakCache *m_peakCache; - Dense3DModelPeakCache *getPeakCache() const { return m_peakCache; } + ModelId m_wholeCache; // a Dense3DModelPeakCache + ModelId m_peakCache; // a Dense3DModelPeakCache int m_peakCacheDivisor; void checkCacheSpace(int *suggestedPeakDivisor, bool *createWholeCache) const; diff -r dbff4b290bf0 -r 886c1cd48f9d layer/SpectrumLayer.cpp --- a/layer/SpectrumLayer.cpp Mon Jul 01 14:25:53 2019 +0100 +++ b/layer/SpectrumLayer.cpp Tue Jul 02 11:49:52 2019 +0100 @@ -33,7 +33,6 @@ SpectrumLayer::SpectrumLayer() : - m_originModel(nullptr), m_channel(-1), m_channelSet(false), m_windowSize(4096), @@ -56,11 +55,7 @@ SpectrumLayer::~SpectrumLayer() { - Model *m = const_cast - (static_cast(m_sliceableModel)); - if (m) m->aboutToDelete(); - m_sliceableModel = nullptr; - delete m; + ModelById::release(m_sliceableModel); } void @@ -74,20 +69,6 @@ if (m_originModel == modelId) return; m_originModel = modelId; - if (newModel) { - //... - } - - //!!! todo - all of this - - if (m_sliceableModel) { - Model *m = const_cast - (static_cast(m_sliceableModel)); - m->aboutToDelete(); - setSliceableModel(nullptr); - delete m; - } - m_newFFTNeeded = true; emit layerParametersChanged(); @@ -112,26 +93,21 @@ void SpectrumLayer::setupFFT() { - if (m_sliceableModel) { - Model *m = const_cast - (static_cast(m_sliceableModel)); - m->aboutToDelete(); - setSliceableModel(nullptr); - delete m; - } + ModelById::release(m_sliceableModel); + m_sliceableModel = {}; - if (!m_originModel) { + if (m_originModel.isNone()) { return; } int fftSize = getFFTSize(); - FFTModel *newFFT = new FFTModel(m_originModel, - m_channel, - m_windowType, - m_windowSize, - getWindowIncrement(), - fftSize); + auto newFFT = std::make_shared(m_originModel, + m_channel, + m_windowType, + m_windowSize, + getWindowIncrement(), + fftSize); if (m_minbin == 0 && m_maxbin == 0) { m_minbin = 1; @@ -140,7 +116,8 @@ m_maxbin = newFFT->getHeight(); } - setSliceableModel(newFFT); + ModelById::add(newFFT); + setSliceableModel(newFFT->getId()); m_biasCurve.clear(); for (int i = 0; i < fftSize; ++i) { @@ -411,15 +388,19 @@ double SpectrumLayer::getBinForFrequency(double freq) const { - if (!m_sliceableModel) return 0; - double bin = (freq * getFFTSize()) / m_sliceableModel->getSampleRate(); + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return 0; + double bin = (freq * getFFTSize()) / sliceableModel->getSampleRate(); return bin; } double SpectrumLayer::getBinForX(const LayerGeometryProvider *v, double x) const { - if (!m_sliceableModel) return 0; + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return 0; double bin = getBinForFrequency(getFrequencyForX(v, x)); return bin; } @@ -427,7 +408,9 @@ double SpectrumLayer::getFrequencyForX(const LayerGeometryProvider *v, double x) const { - if (!m_sliceableModel) return 0; + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return 0; double fmin = getFrequencyForBin(m_minbin); double fmax = getFrequencyForBin(m_maxbin); @@ -439,15 +422,19 @@ double SpectrumLayer::getFrequencyForBin(double bin) const { - if (!m_sliceableModel) return 0; - double freq = (bin * m_sliceableModel->getSampleRate()) / getFFTSize(); + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return 0; + double freq = (bin * sliceableModel->getSampleRate()) / getFFTSize(); return freq; } double SpectrumLayer::getXForBin(const LayerGeometryProvider *v, double bin) const { - if (!m_sliceableModel) return 0; + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return 0; double x = getXForFrequency(v, getFrequencyForBin(bin)); return x; } @@ -455,7 +442,9 @@ double SpectrumLayer::getXForFrequency(const LayerGeometryProvider *v, double freq) const { - if (!m_sliceableModel) return 0; + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return 0; double fmin = getFrequencyForBin(m_minbin); double fmax = getFrequencyForBin(m_maxbin); @@ -483,8 +472,12 @@ if (value > 0.0) { value = 10.0 * log10(value); - if (value < m_threshold) value = m_threshold; - } else value = m_threshold; + if (value < m_threshold) { + value = m_threshold; + } + } else { + value = m_threshold; + } unit = "dBV"; @@ -521,6 +514,11 @@ int sw = getVerticalScaleWidth(v, false, paint); + // Qt 5.13 deprecates QFontMetrics::width(), but its suggested + // replacement (horizontalAdvance) was only added in Qt 5.11 + // which is too new for us +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + QRect value(sw, cursorPos.y() - paint.fontMetrics().ascent() - 2, paint.fontMetrics().width("0.0000001 V") + 2, paint.fontMetrics().height()); @@ -551,7 +549,9 @@ SpectrumLayer::paintCrosshairs(LayerGeometryProvider *v, QPainter &paint, QPoint cursorPos) const { - if (!m_sliceableModel) return; + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return; paint.save(); QFont fn = paint.font(); @@ -638,7 +638,9 @@ QString SpectrumLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &p) const { - if (!m_sliceableModel) return ""; + auto sliceableModel = ModelById::getAs + (m_sliceableModel); + if (!sliceableModel) return ""; int minbin = 0, maxbin = 0, range = 0; QString genericDesc = SliceLayer::getFeatureDescriptionAux @@ -659,10 +661,10 @@ QString binstr; QString hzstr; - int minfreq = int(lrint((minbin * m_sliceableModel->getSampleRate()) / + int minfreq = int(lrint((minbin * sliceableModel->getSampleRate()) / getFFTSize())); int maxfreq = int(lrint((std::max(maxbin, minbin) - * m_sliceableModel->getSampleRate()) / + * sliceableModel->getSampleRate()) / getFFTSize())); if (maxbin != minbin) { @@ -706,7 +708,7 @@ QString description; - if (range > int(m_sliceableModel->getResolution())) { + if (range > int(sliceableModel->getResolution())) { description = tr("%1\nBin:\t%2 (%3)\n%4 value:\t%5\ndB:\t%6") .arg(genericDesc) .arg(binstr) @@ -730,8 +732,8 @@ void SpectrumLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const { - if (!m_originModel || !m_originModel->isOK() || - !m_originModel->isReady()) { + auto originModel = ModelById::get(m_originModel); + if (!originModel || !originModel->isOK() || !originModel->isReady()) { SVDEBUG << "SpectrumLayer::paint: no origin model, or origin model not OK or not ready" << endl; return; } @@ -741,8 +743,8 @@ const_cast(this)->setupFFT(); //ugh } - FFTModel *fft = dynamic_cast - (const_cast(m_sliceableModel)); + auto fft = ModelById::getAs(m_sliceableModel); + if (!fft) return; double thresh = (pow(10, -6) / m_gain) * (getFFTSize() / 2.0); // -60dB adj