diff layer/WaveformLayer.cpp @ 1486:ac0a8addabcf

Merge from branch by-id
author Chris Cannam
date Wed, 17 Jul 2019 14:25:16 +0100
parents 36ad3cdabf55
children 1ccb64bfb22b
line wrap: on
line diff
--- a/layer/WaveformLayer.cpp	Thu Jun 13 15:35:01 2019 +0100
+++ b/layer/WaveformLayer.cpp	Wed Jul 17 14:25:16 2019 +0100
@@ -41,7 +41,6 @@
 
 WaveformLayer::WaveformLayer() :
     SingleColourLayer(),
-    m_model(nullptr),
     m_gain(1.0f),
     m_autoNormalize(false),
     m_showMeans(true),
@@ -60,29 +59,47 @@
     delete m_cache;
 }
 
+const ZoomConstraint *
+WaveformLayer::getZoomConstraint() const
+{
+    auto model = ModelById::get(m_model);
+    if (model) return model->getZoomConstraint();
+    else return nullptr;
+}
+
 void
-WaveformLayer::setModel(const RangeSummarisableTimeValueModel *model)
+WaveformLayer::setModel(ModelId modelId)
 {
+    auto oldModel = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    auto newModel = ModelById::getAs<RangeSummarisableTimeValueModel>(modelId);
+
+    if (!modelId.isNone() && !newModel) {
+        throw std::logic_error("Not a RangeSummarisableTimeValueModel");
+    }
+    
+    if (m_model == modelId) return;
+    m_model = modelId;
+
+    m_cacheValid = false;
+    
     bool channelsChanged = false;
     if (m_channel == -1) {
-        if (!m_model) {
-            if (model) {
+        if (!oldModel) {
+            if (newModel) {
                 channelsChanged = true;
             }
         } else {
-            if (model &&
-                m_model->getChannelCount() != model->getChannelCount()) {
+            if (newModel &&
+                oldModel->getChannelCount() != newModel->getChannelCount()) {
                 channelsChanged = true;
             }
         }
     }
 
-    m_model = model;
-    m_cacheValid = false;
-    if (!m_model || !m_model->isOK()) return;
-
-    connectSignals(m_model);
-
+    if (newModel) {
+        connectSignals(m_model);
+    }
+        
     emit modelReplaced();
 
     if (channelsChanged) emit layerParametersChanged();
@@ -96,7 +113,8 @@
     list.push_back("Gain");
     list.push_back("Normalize Visible Area");
 
-    if (m_model && m_model->getChannelCount() > 1 && m_channel == -1) {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (model && model->getChannelCount() > 1 && m_channel == -1) {
         list.push_back("Channels");
     }
 
@@ -323,8 +341,9 @@
 WaveformLayer::getCompletion(LayerGeometryProvider *) const
 {
     int completion = 100;
-    if (!m_model || !m_model->isOK()) return completion;
-    if (m_model->isReady(&completion)) return 100;
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model || !model->isOK()) return completion;
+    if (model->isReady(&completion)) return 100;
     return completion;
 }
 
@@ -361,9 +380,10 @@
                                      bool &merging, bool &mixing)
     const
 {
-    if (!m_model || !m_model->isOK()) return 0;
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model || !model->isOK()) return 0;
 
-    int channels = m_model->getChannelCount();
+    int channels = model->getChannelCount();
     if (channels == 0) return 0;
 
     int rawChannels = channels;
@@ -406,6 +426,9 @@
                                    int x, int modelZoomLevel,
                                    sv_frame_t &f0, sv_frame_t &f1) const
 {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model) return false;
+    
     sv_frame_t viewFrame = v->getFrameForX(x);
     if (viewFrame < 0) {
         f0 = 0;
@@ -426,17 +449,20 @@
         f1 = f1 * modelZoomLevel;
     }
     
-    return (f0 < m_model->getEndFrame());
+    return (f0 < model->getEndFrame());
 }
 
 float
 WaveformLayer::getNormalizeGain(LayerGeometryProvider *v, int channel) const
 {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model) return 0.f;
+    
     sv_frame_t startFrame = v->getStartFrame();
     sv_frame_t endFrame = v->getEndFrame();
 
-    sv_frame_t modelStart = m_model->getStartFrame();
-    sv_frame_t modelEnd = m_model->getEndFrame();
+    sv_frame_t modelStart = model->getStartFrame();
+    sv_frame_t modelEnd = model->getEndFrame();
     
     sv_frame_t rangeStart, rangeEnd;
             
@@ -450,7 +476,7 @@
     if (rangeEnd < rangeStart) rangeEnd = rangeStart;
 
     RangeSummarisableTimeValueModel::Range range =
-        m_model->getSummary(channel, rangeStart, rangeEnd - rangeStart);
+        model->getSummary(channel, rangeStart, rangeEnd - rangeStart);
 
     int minChannel = 0, maxChannel = 0;
     bool mergingChannels = false, mixingChannels = false;
@@ -460,7 +486,7 @@
 
     if (mergingChannels || mixingChannels) {
         RangeSummarisableTimeValueModel::Range otherRange =
-            m_model->getSummary(1, rangeStart, rangeEnd - rangeStart);
+            model->getSummary(1, rangeStart, rangeEnd - rangeStart);
         range.setMax(std::max(range.max(), otherRange.max()));
         range.setMin(std::min(range.min(), otherRange.min()));
         range.setAbsmean(std::min(range.absmean(), otherRange.absmean()));
@@ -472,7 +498,8 @@
 void
 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const
 {
-    if (!m_model || !m_model->isOK()) {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model || !model->isOK()) {
         return;
     }
   
@@ -576,7 +603,7 @@
     if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
         desiredBlockSize = zoomLevel.level;
     }
-    int blockSize = m_model->getSummaryBlockSize(desiredBlockSize);
+    int blockSize = model->getSummaryBlockSize(desiredBlockSize);
 
     sv_frame_t frame0;
     sv_frame_t frame1;
@@ -625,7 +652,7 @@
     }
 
     if (m_aggressive) {
-        if (m_model->isReady() && rect == v->getPaintRect()) {
+        if (model->isReady() && rect == v->getPaintRect()) {
             m_cacheValid = true;
             m_cacheZoomLevel = zoomLevel;
         }
@@ -642,9 +669,12 @@
                                 int blockSize, RangeVec &ranges)
     const
 {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model) return;
+    
     for (int ch = minChannel; ch <= maxChannel; ++ch) {
         ranges.push_back({});
-        m_model->getSummaries(ch, frame0, frame1 - frame0,
+        model->getSummaries(ch, frame0, frame1 - frame0,
                               ranges[ch - minChannel], blockSize);
 #ifdef DEBUG_WAVEFORM_PAINT
             SVCERR << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
@@ -654,9 +684,9 @@
     if (mixingOrMerging) {
         if (minChannel != 0 || maxChannel != 0) {
             throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels");
-        } else if (m_model->getChannelCount() > 1) {
+        } else if (model->getChannelCount() > 1) {
             ranges.push_back({});
-            m_model->getSummaries
+            model->getSummaries
                 (1, frame0, frame1 - frame0, ranges[1], blockSize);
         }
     }
@@ -669,11 +699,14 @@
                                     int oversampleBy, RangeVec &ranges)
     const
 {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model) return;
+    
     if (mixingOrMerging) {
         if (minChannel != 0 || maxChannel != 0) {
             throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels");
         }
-        if (m_model->getChannelCount() > 1) {
+        if (model->getChannelCount() > 1) {
             // call back on self for the individual channels with
             // mixingOrMerging false
             getOversampledRanges
@@ -686,8 +719,8 @@
     // sample rate, not the oversampled rate
 
     sv_frame_t tail = 16;
-    sv_frame_t startFrame = m_model->getStartFrame();
-    sv_frame_t endFrame = m_model->getEndFrame();
+    sv_frame_t startFrame = model->getStartFrame();
+    sv_frame_t endFrame = model->getEndFrame();
 
     sv_frame_t rf0 = frame0 - tail;
     if (rf0 < startFrame) {
@@ -706,7 +739,7 @@
     
     for (int ch = minChannel; ch <= maxChannel; ++ch) {
         floatvec_t oversampled = WaveformOversampler::getOversampledData
-            (m_model, ch, frame0, frame1 - frame0, oversampleBy);
+            (*model, ch, frame0, frame1 - frame0, oversampleBy);
         RangeSummarisableTimeValueModel::RangeBlock rr;
         for (float v: oversampled) {
             RangeSummarisableTimeValueModel::Range r;
@@ -738,6 +771,9 @@
                             sv_frame_t frame1)
     const
 {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model) return;
+    
     int x0 = rect.left();
     int y0 = rect.top();
 
@@ -759,9 +795,9 @@
     if (midColour == Qt::black) {
         midColour = Qt::gray;
     } else if (v->hasLightBackground()) {
-        midColour = midColour.light(150);
+        midColour = midColour.lighter(150);
     } else {
-        midColour = midColour.light(50);
+        midColour = midColour.lighter(50);
     }
 
     double gain = m_effectiveGains[ch];
@@ -1033,7 +1069,7 @@
         penWidth = 0.0;
     }
     
-    if (m_model->isReady()) {
+    if (model->isReady()) {
         paint->setPen(QPen(baseColour, penWidth));
     } else {
         paint->setPen(QPen(midColour, penWidth));
@@ -1136,7 +1172,8 @@
 {
     int x = pos.x();
 
-    if (!m_model || !m_model->isOK()) return "";
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model || !model->isOK()) return "";
 
     ZoomLevel zoomLevel = v->getZoomLevel();
 
@@ -1145,15 +1182,15 @@
         desiredBlockSize = zoomLevel.level;
     }
 
-    int blockSize = m_model->getSummaryBlockSize(desiredBlockSize);
+    int blockSize = model->getSummaryBlockSize(desiredBlockSize);
 
     sv_frame_t f0, f1;
     if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return "";
     
     QString text;
 
-    RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate());
-    RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate());
+    RealTime rt0 = RealTime::frame2RealTime(f0, model->getSampleRate());
+    RealTime rt1 = RealTime::frame2RealTime(f1, model->getSampleRate());
 
     if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) {
         text += tr("Time:\t%1 - %2")
@@ -1174,7 +1211,7 @@
     for (int ch = minChannel; ch <= maxChannel; ++ch) {
 
         RangeSummarisableTimeValueModel::RangeBlock ranges;
-        m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
+        model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
 
         if (ranges.empty()) continue;
         
@@ -1374,6 +1411,11 @@
 int
 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) 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"
+
     if (m_scale == LinearScale) {
         return paint.fontMetrics().width("0.0") + 13;
     } else {
@@ -1385,7 +1427,8 @@
 void
 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const
 {
-    if (!m_model || !m_model->isOK()) {
+    auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
+    if (!model || !model->isOK()) {
         return;
     }