changeset 575:3c884bad3d44

Merge from branch by-id
author Chris Cannam
date Thu, 18 Jul 2019 13:38:24 +0100
parents 2cf4978eb724 (current diff) ca0ff30dae26 (diff)
children 335fd9b439a0
files repoint-lock.json repoint-project.json
diffstat 7 files changed, 115 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/pyin.pro	Thu Jun 20 11:10:59 2019 +0100
+++ b/pyin.pro	Thu Jul 18 13:38:24 2019 +0100
@@ -15,6 +15,8 @@
 
 INCLUDEPATH += $$PWD/vamp-plugin-sdk
 
+QMAKE_CXXFLAGS -= -Werror
+
 win32-msvc* {
     LIBS += -EXPORT:vampGetPluginDescriptor
 }
--- a/repoint-lock.json	Thu Jun 20 11:10:59 2019 +0100
+++ b/repoint-lock.json	Thu Jul 18 13:38:24 2019 +0100
@@ -4,13 +4,13 @@
       "pin": "62987b6d6a3b"
     },
     "svcore": {
-      "pin": "8efce64dd85e"
+      "pin": "4fec4527e50e"
     },
     "svgui": {
-      "pin": "de41a11cabc2"
+      "pin": "c3cc36c014b8"
     },
     "svapp": {
-      "pin": "a82b9d410393"
+      "pin": "155008f1bf10"
     },
     "checker": {
       "pin": "c8c17e51aab0"
@@ -46,10 +46,10 @@
       "pin": "1c8844bfa946"
     },
     "pyin": {
-      "pin": "550d5f186abb"
+      "pin": "6f17d912e1dd"
     },
     "chp": {
-      "pin": "456842723db6"
+      "pin": "de970142809f"
     }
   }
 }
--- a/src/Analyser.cpp	Thu Jun 20 11:10:59 2019 +0100
+++ b/src/Analyser.cpp	Thu Jul 18 13:38:24 2019 +0100
@@ -41,7 +41,6 @@
 
 Analyser::Analyser() :
     m_document(0),
-    m_fileModel(0),
     m_paneStack(0),
     m_pane(0),
     m_currentCandidate(-1),
@@ -69,7 +68,7 @@
 }
 
 QString
-Analyser::newFileLoaded(Document *doc, WaveFileModel *model,
+Analyser::newFileLoaded(Document *doc, ModelId model,
 			PaneStack *paneStack, Pane *pane)
 {
     m_document = doc;
@@ -77,7 +76,9 @@
     m_paneStack = paneStack;
     m_pane = pane;
 
-    if (!m_fileModel) return "Internal error: Analyser::newFileLoaded() called with no model present";
+    if (!ModelById::isa<WaveFileModel>(m_fileModel)) {
+        return "Internal error: Analyser::newFileLoaded() called with no model, or a non-WaveFileModel";
+    }
     
     connect(doc, SIGNAL(layerAboutToBeDeleted(Layer *)),
             this, SLOT(layerAboutToBeDeleted(Layer *)));
@@ -97,7 +98,7 @@
 
     if (!m_pane) return "Internal error: Analyser::analyseExistingFile() called with no pane present";
 
-    if (!m_fileModel) return "Internal error: Analyser::analyseExistingFile() called with no model present";
+    if (m_fileModel.isNone()) return "Internal error: Analyser::analyseExistingFile() called with no model present";
     
     if (m_layers[PitchTrack]) {
         m_document->removeLayerFromView(m_pane, m_layers[PitchTrack]);
@@ -196,32 +197,36 @@
 void
 Analyser::layerCompletionChanged()
 {
-    if (getInitialAnalysisCompletion() == 100) {
+    if (getInitialAnalysisCompletion() < 100) {
+        return;
+    }
 
-        emit initialAnalysisCompleted();
+    emit initialAnalysisCompleted();
 
-        if (m_layers[Audio]) {
+    if (!m_layers[Audio]) {
+        return;
+    }
 
-            // Extend pitch-track and note layers so as to nominally
-            // end at the same time as the audio. This affects any
-            // time-filling done on export etc.
-            
-            sv_frame_t endFrame = m_layers[Audio]->getModel()->getEndFrame();
+    // Extend pitch-track and note layers so as to nominally end at
+    // the same time as the audio. This affects any time-filling done
+    // on export etc.
+
+    auto audioModel = ModelById::get(m_layers[Audio]->getModel());
+    sv_frame_t endFrame = audioModel->getEndFrame();
         
-            if (m_layers[PitchTrack]) {
-                SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
-                    (m_layers[PitchTrack]->getModel());
-                if (model) {
-                    model->extendEndFrame(endFrame);
-                }
-            }
-            if (m_layers[Notes]) {
-                NoteModel *model = qobject_cast<NoteModel *>
-                    (m_layers[Notes]->getModel());
-                if (model) {
-                    model->extendEndFrame(endFrame);
-                }
-            }
+    if (m_layers[PitchTrack]) {
+        auto model = ModelById::getAs<SparseTimeValueModel>
+            (m_layers[PitchTrack]->getModel());
+        if (model) {
+            model->extendEndFrame(endFrame);
+        }
+    }
+
+    if (m_layers[Notes]) {
+        auto model = ModelById::getAs<NoteModel>
+            (m_layers[Notes]->getModel());
+        if (model) {
+            model->extendEndFrame(endFrame);
         }
     }
 }
@@ -229,7 +234,7 @@
 QString
 Analyser::addVisualisations()
 {
-    if (!m_fileModel) return "Internal error: Analyser::addVisualisations() called with no model present";
+    if (m_fileModel.isNone()) return "Internal error: Analyser::addVisualisations() called with no model present";
 
     // A spectrogram, off by default. Must go at the back because it's
     // opaque
@@ -314,7 +319,7 @@
     waveform->setShowMeans(false); // too small & pale for this
     waveform->setBaseColour
         (ColourDatabase::getInstance()->getColourIndex(tr("Grey")));
-    PlayParameters *params = waveform->getPlayParameters();
+    auto params = waveform->getPlayParameters();
     if (params) {
         params->setPlayPan(-1);
         params->setPlayGain(1);
@@ -329,6 +334,11 @@
 QString
 Analyser::addAnalyses()
 {
+    auto waveFileModel = ModelById::getAs<WaveFileModel>(m_fileModel);
+    if (!waveFileModel) {
+        return "Internal error: Analyser::addAnalyses() called with no model present";
+    }
+    
     // As with the spectrogram above, if these layers exist we use
     // them
     TimeValueLayer *existingPitch = 0;
@@ -395,7 +405,7 @@
     settings.endGroup();
 
     Transform t = tf->getDefaultTransformFor
-        (base + f0out, m_fileModel->getSampleRate());
+        (base + f0out, waveFileModel->getSampleRate());
     t.setStepSize(256);
     t.setBlockSize(2048);
 
@@ -457,7 +467,7 @@
         qobject_cast<TimeValueLayer *>(m_layers[PitchTrack]);
     if (pitchLayer) {
         pitchLayer->setBaseColour(cdb->getColourIndex(tr("Black")));
-        PlayParameters *params = pitchLayer->getPlayParameters();
+        auto params = pitchLayer->getPlayParameters();
         if (params) {
             params->setPlayPan(1);
             params->setPlayGain(0.5);
@@ -470,7 +480,7 @@
         qobject_cast<FlexiNoteLayer *>(m_layers[Notes]);
     if (flexiNoteLayer) {
         flexiNoteLayer->setBaseColour(cdb->getColourIndex(tr("Bright Blue")));
-        PlayParameters *params = flexiNoteLayer->getPlayParameters();
+        auto params = flexiNoteLayer->getPlayParameters();
         if (params) {
             params->setPlayPan(1);
             params->setPlayGain(0.5);
@@ -508,6 +518,11 @@
 {
     QMutexLocker locker(&m_asyncMutex);
 
+    auto waveFileModel = ModelById::getAs<WaveFileModel>(m_fileModel);
+    if (!waveFileModel) {
+        return "Internal error: Analyser::reAnalyseSelection() called with no model present";
+    }
+    
     if (!m_reAnalysingSelection.isEmpty()) {
         if (sel == m_reAnalysingSelection && range == m_reAnalysingRange) {
             cerr << "selection & range are same as current analysis, ignoring" << endl;
@@ -558,7 +573,7 @@
     }
 
     Transform t = tf->getDefaultTransformFor
-        (base + out, m_fileModel->getSampleRate());
+        (base + out, waveFileModel->getSampleRate());
     t.setStepSize(256);
     t.setBlockSize(2048);
 
@@ -580,8 +595,8 @@
     } else {
         endSample   -= 9*grid; // MM says: not sure what the CHP plugin does there
     }
-    RealTime start = RealTime::frame2RealTime(startSample, m_fileModel->getSampleRate()); 
-    RealTime end = RealTime::frame2RealTime(endSample, m_fileModel->getSampleRate());
+    RealTime start = RealTime::frame2RealTime(startSample, waveFileModel->getSampleRate()); 
+    RealTime end = RealTime::frame2RealTime(endSample, waveFileModel->getSampleRate());
 
     RealTime duration;
 
@@ -670,7 +685,7 @@
         for (int i = 0; i < (int)all.size(); ++i) {
             TimeValueLayer *t = qobject_cast<TimeValueLayer *>(all[i]);
             if (t) {
-                PlayParameters *params = t->getPlayParameters();
+                auto params = t->getPlayParameters();
                 if (params) {
                     params->setPlayAudible(false);
                 }
@@ -850,16 +865,20 @@
 Analyser::takePitchTrackFrom(Layer *otherLayer)
 {
     Layer *myLayer = m_layers[PitchTrack];
-    if (!myLayer) return;
+    if (!myLayer || !otherLayer) return;
+
+    auto myModel = ModelById::get(myLayer->getModel());
+    auto otherModel = ModelById::get(otherLayer->getModel());
+    if (!myModel || !otherModel) return;
 
     Clipboard clip;
-
-    Selection sel = Selection(myLayer->getModel()->getStartFrame(),
-                              myLayer->getModel()->getEndFrame());
+    
+    Selection sel = Selection(myModel->getStartFrame(),
+                              myModel->getEndFrame());
     myLayer->deleteSelection(sel);
 
-    sel = Selection(otherLayer->getModel()->getStartFrame(),
-                    otherLayer->getModel()->getEndFrame());
+    sel = Selection(otherModel->getStartFrame(),
+                    otherModel->getEndFrame());
     otherLayer->copy(m_pane, sel, clip);
 
     // Remove all pitches <= 0Hz -- we now save absent pitches as 0Hz
@@ -975,7 +994,7 @@
 Analyser::isAudible(Component c) const
 {
     if (m_layers[c]) {
-        PlayParameters *params = m_layers[c]->getPlayParameters();
+        auto params = m_layers[c]->getPlayParameters();
         if (!params) return false;
         return params->isPlayAudible();
     } else {
@@ -987,7 +1006,7 @@
 Analyser::setAudible(Component c, bool a)
 {
     if (m_layers[c]) {
-        PlayParameters *params = m_layers[c]->getPlayParameters();
+        auto params = m_layers[c]->getPlayParameters();
         if (!params) return;
         params->setPlayAudible(a);
         saveState(c);
@@ -998,7 +1017,7 @@
 Analyser::getGain(Component c) const
 {
     if (m_layers[c]) {
-        PlayParameters *params = m_layers[c]->getPlayParameters();
+        auto params = m_layers[c]->getPlayParameters();
         if (!params) return 1.f;
         return params->getPlayGain();
     } else {
@@ -1010,7 +1029,7 @@
 Analyser::setGain(Component c, float gain)
 {
     if (m_layers[c]) {
-        PlayParameters *params = m_layers[c]->getPlayParameters();
+        auto params = m_layers[c]->getPlayParameters();
         if (!params) return;
         params->setPlayGain(gain);
         saveState(c);
@@ -1021,7 +1040,7 @@
 Analyser::getPan(Component c) const
 {
     if (m_layers[c]) {
-        PlayParameters *params = m_layers[c]->getPlayParameters();
+        auto params = m_layers[c]->getPlayParameters();
         if (!params) return 1.f;
         return params->getPlayPan();
     } else {
@@ -1033,7 +1052,7 @@
 Analyser::setPan(Component c, float pan)
 {
     if (m_layers[c]) {
-        PlayParameters *params = m_layers[c]->getPlayParameters();
+        auto params = m_layers[c]->getPlayParameters();
         if (!params) return;
         params->setPlayPan(pan);
         saveState(c);
--- a/src/Analyser.h	Thu Jun 20 11:10:59 2019 +0100
+++ b/src/Analyser.h	Thu Jul 18 13:38:24 2019 +0100
@@ -26,8 +26,8 @@
 #include "framework/Document.h"
 #include "base/Selection.h"
 #include "base/Clipboard.h"
+#include "data/model/WaveFileModel.h"
 
-class WaveFileModel;
 class Pane;
 class PaneStack;
 class Layer;
@@ -43,11 +43,15 @@
     Analyser();
     virtual ~Analyser();
 
-    // Process new main model, add derived layers; return "" on success or error string on failure
-    QString newFileLoaded(Document *newDocument, WaveFileModel *model,
-                          PaneStack *paneStack, Pane *pane);
+    // Process new main model, add derived layers; return "" on
+    // success or error string on failure
+    QString newFileLoaded(Document *newDocument,
+                          ModelId model,
+                          PaneStack *paneStack,
+                          Pane *pane);
 
-    // Remove any derived layers, process the main model, add derived layers; return "" on success or error string on failure
+    // Remove any derived layers, process the main model, add derived
+    // layers; return "" on success or error string on failure
     QString analyseExistingFile();
 
     // Discard any layers etc associated with the current document
@@ -90,9 +94,12 @@
         }
     }
 
-    WaveFileModel *getMainModel() const {
+    ModelId getMainModelId() const {
         return m_fileModel;
     }
+    std::shared_ptr<WaveFileModel> getMainModel() const {
+        return ModelById::getAs<WaveFileModel>(m_fileModel);
+    }
 
     float getGain(Component c) const;
     void setGain(Component c, float gain);
@@ -223,7 +230,7 @@
 
 protected:
     Document *m_document;
-    WaveFileModel *m_fileModel;
+    ModelId m_fileModel;
     PaneStack *m_paneStack;
     Pane *m_pane;
 
--- a/src/MainWindow.cpp	Thu Jun 20 11:10:59 2019 +0100
+++ b/src/MainWindow.cpp	Thu Jul 18 13:38:24 2019 +0100
@@ -1313,7 +1313,7 @@
     Layer *layer = m_analyser->getLayer(Analyser::Notes);
     if (!layer) return;
 
-    NoteModel *model = qobject_cast<NoteModel *>(layer->getModel());
+    auto model = ModelById::getAs<NoteModel>(layer->getModel());
     if (!model) return;
 
     //!!! This seems like a strange and inefficient way to do this -
@@ -2111,7 +2111,8 @@
 QString
 MainWindow::exportToSVL(QString path, Layer *layer)
 {
-    Model *model = layer->getModel();
+    auto model = ModelById::get(layer->getModel());
+    if (!model) return "Internal error: No model in layer";
 
     QFile file(path);
     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
@@ -2202,10 +2203,13 @@
 
                 SVDEBUG << "MainWindow::importPitchLayer: Have model" << endl;
 
+                ModelId modelId = ModelById::add
+                    (std::shared_ptr<Model>(model));
+                
                 CommandHistory::getInstance()->startCompoundOperation
                     (tr("Import Pitch Track"), true);
 
-                Layer *newLayer = m_document->createImportedLayer(model);
+                Layer *newLayer = m_document->createImportedLayer(modelId);
 
                 m_analyser->takePitchTrackFrom(newLayer);
 
@@ -2213,8 +2217,6 @@
 
                 CommandHistory::getInstance()->endCompoundOperation();
 
-                //!!! swap all data in to existing layer instead of this
-
                 if (!source.isRemote()) {
                     registerLastOpenedFilePath
                         (FileFinder::LayerFile,
@@ -2239,8 +2241,7 @@
     Layer *layer = m_analyser->getLayer(Analyser::PitchTrack);
     if (!layer) return;
 
-    SparseTimeValueModel *model =
-        qobject_cast<SparseTimeValueModel *>(layer->getModel());
+    auto model = ModelById::getAs<SparseTimeValueModel>(layer->getModel());
     if (!model) return;
 
     FileFinder::FileType type = FileFinder::LayerFileNoMidiNonSV;
@@ -2263,7 +2264,7 @@
 
     } else if (suffix == "ttl" || suffix == "n3") {
 
-        RDFExporter exporter(path, model);
+        RDFExporter exporter(path, model.get());
         exporter.write();
         if (!exporter.isOK()) {
             error = exporter.getError();
@@ -2273,7 +2274,7 @@
 
         DataExportOptions options = DataExportFillGaps;
         
-        CSVFileWriter writer(path, model,
+        CSVFileWriter writer(path, model.get(),
                              ((suffix == "csv") ? "," : "\t"),
                              options);
         writer.write();
@@ -2296,7 +2297,7 @@
     Layer *layer = m_analyser->getLayer(Analyser::Notes);
     if (!layer) return;
 
-    NoteModel *model = qobject_cast<NoteModel *>(layer->getModel());
+    auto model = ModelById::getAs<NoteModel>(layer->getModel());
     if (!model) return;
 
     FileFinder::FileType type = FileFinder::LayerFileNonSV;
@@ -2317,7 +2318,7 @@
 
     } else if (suffix == "mid" || suffix == "midi") {
      
-        MIDIFileWriter writer(path, model, model->getSampleRate());
+        MIDIFileWriter writer(path, model.get(), model->getSampleRate());
         writer.write();
         if (!writer.isOK()) {
             error = writer.getError();
@@ -2325,7 +2326,7 @@
 
     } else if (suffix == "ttl" || suffix == "n3") {
 
-        RDFExporter exporter(path, model);
+        RDFExporter exporter(path, model.get());
         exporter.write();
         if (!exporter.isOK()) {
             error = exporter.getError();
@@ -2335,7 +2336,7 @@
 
         DataExportOptions options = DataExportOmitLevels;
         
-        CSVFileWriter writer(path, model,
+        CSVFileWriter writer(path, model.get(),
                              ((suffix == "csv") ? "," : "\t"),
                              options);
         writer.write();
@@ -2654,9 +2655,9 @@
 {
     Pane *pane = m_analyser->getPane();
     Layer *layer0 = m_analyser->getLayer(Analyser::Notes);
-    NoteModel *model = qobject_cast<NoteModel *>(layer0->getModel());
+    auto model = ModelById::getAs<NoteModel>(layer0->getModel());
     FlexiNoteLayer *layer = qobject_cast<FlexiNoteLayer *>(layer0);
-    if (!layer) return;
+    if (!layer || !model) return;
 
     MultiSelection::SelectionList selections = m_viewManager->getSelections();
 
@@ -2960,23 +2961,17 @@
 }
 
 void
-MainWindow::modelAdded(Model *model)
+MainWindow::modelAdded(ModelId model)
 {
     MainWindowBase::modelAdded(model);
-    DenseTimeValueModel *dtvm = qobject_cast<DenseTimeValueModel *>(model);
+    auto dtvm = ModelById::getAs<DenseTimeValueModel>(model);
     if (dtvm) {
         cerr << "A dense time-value model (such as an audio file) has been loaded" << endl;
     }
 }
 
 void
-MainWindow::modelAboutToBeDeleted(Model *model)
-{
-    MainWindowBase::modelAboutToBeDeleted(model);
-}
-
-void
-MainWindow::mainModelChanged(WaveFileModel *model)
+MainWindow::mainModelChanged(ModelId model)
 {
     m_panLayer->setModel(model);
 
@@ -3023,7 +3018,7 @@
 void
 MainWindow::analyseNewMainModel()
 {
-    WaveFileModel *model = getMainModel();
+    auto model = getMainModel();
 
     cerr << "MainWindow::analyseNewMainModel: main model is " << model << endl;
 
@@ -3073,7 +3068,7 @@
                 this, SLOT(regionOutlined(QRect)));
 
         QString error = m_analyser->newFileLoaded
-            (m_document, getMainModel(), m_paneStack, pane);
+            (m_document, getMainModelId(), m_paneStack, pane);
         if (error != "") {
             QMessageBox::warning
                 (this,
@@ -3083,13 +3078,11 @@
         }
     }
 
-    if (!m_withSpectrogram) 
-    {
+    if (!m_withSpectrogram) {
         m_analyser->setVisible(Analyser::Spectrogram, false);
     }
 
-    if (!m_withSonification) 
-    {
+    if (!m_withSonification) {
         m_analyser->setAudible(Analyser::PitchTrack, false);
         m_analyser->setAudible(Analyser::Notes, false);
     }
--- a/src/MainWindow.h	Thu Jun 20 11:10:59 2019 +0100
+++ b/src/MainWindow.h	Thu Jul 18 13:38:24 2019 +0100
@@ -134,10 +134,9 @@
     virtual void layerRemoved(Layer *);
     virtual void layerInAView(Layer *, bool);
 
-    virtual void mainModelChanged(WaveFileModel *);
+    virtual void mainModelChanged(ModelId);
     virtual void mainModelGainChanged(float);
-    virtual void modelAdded(Model *);
-    virtual void modelAboutToBeDeleted(Model *);
+    virtual void modelAdded(ModelId);
 
     virtual void modelGenerationFailed(QString, QString);
     virtual void modelGenerationWarning(QString, QString);
--- a/src/main.cpp	Thu Jun 20 11:10:59 2019 +0100
+++ b/src/main.cpp	Thu Jul 18 13:38:24 2019 +0100
@@ -27,7 +27,7 @@
 
 #include <QMetaType>
 #include <QApplication>
-#include <QDesktopWidget>
+#include <QScreen>
 #include <QMessageBox>
 #include <QTranslator>
 #include <QLocale>
@@ -284,8 +284,8 @@
         QObject::connect(gui, SIGNAL(hideSplash()), splash, SLOT(hide()));
     }
 
-    QDesktopWidget *desktop = QApplication::desktop();
-    QRect available = desktop->availableGeometry();
+    QScreen *screen = QApplication::primaryScreen();
+    QRect available = screen->availableGeometry();
 
     int width = (available.width() * 2) / 3;
     int height = available.height() / 2;