diff layer/SpectrumLayer.cpp @ 1473:886c1cd48f9d by-id

Further layer updates for ModelById
author Chris Cannam
date Tue, 02 Jul 2019 11:49:52 +0100
parents f2525e6cbdf1
children e540aa5d89cd
line wrap: on
line diff
--- 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<Model *>
-        (static_cast<const Model *>(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<Model *>
-            (static_cast<const Model *>(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<Model *>
-            (static_cast<const Model *>(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<FFTModel>(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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<DenseThreeDimensionalModel>
+        (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<SpectrumLayer *>(this)->setupFFT(); //ugh
     }
 
-    FFTModel *fft = dynamic_cast<FFTModel *>
-        (const_cast<DenseThreeDimensionalModel *>(m_sliceableModel));
+    auto fft = ModelById::getAs<FFTModel>(m_sliceableModel);
+    if (!fft) return;
 
     double thresh = (pow(10, -6) / m_gain) * (getFFTSize() / 2.0); // -60dB adj