changeset 778:83a7b10b7415

Merge from branch pitch-align
author Chris Cannam
date Fri, 26 Jun 2020 13:48:52 +0100
parents 7bded7599874 (diff) 87d33e79855b (current diff)
children 5de2b710cfae
files framework/Document.cpp
diffstat 5 files changed, 119 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/audio/AudioCallbackPlaySource.cpp	Thu Jun 25 17:43:10 2020 +0100
+++ b/audio/AudioCallbackPlaySource.cpp	Fri Jun 26 13:48:52 2020 +0100
@@ -171,6 +171,8 @@
 {
     if (m_models.find(modelId) != m_models.end()) return;
 
+    Profiler profiler("AudioCallbackPlaySource::addModel");
+    
     bool willPlay = m_audioGenerator->addModel(modelId);
 
     auto model = ModelById::get(modelId);
@@ -200,7 +202,7 @@
     if (m_sourceSampleRate == 0) {
 
         SVDEBUG << "AudioCallbackPlaySource::addModel: Source rate changing from 0 to "
-            << model->getSampleRate() << endl;
+                << model->getSampleRate() << endl;
 
         m_sourceSampleRate = model->getSampleRate();
         srChanged = true;
@@ -332,6 +334,8 @@
     auto model = ModelById::get(modelId);
     if (!model) return;
     
+    Profiler profiler("AudioCallbackPlaySource::removeModel");
+
     m_mutex.lock();
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
@@ -885,6 +889,8 @@
 void
 AudioCallbackPlaySource::rebuildRangeLists()
 {
+    Profiler profiler("AudioCallbackPlaySource::rebuildRangeLists");
+    
     bool constrained = (m_viewManager->getPlaySelectionMode());
 
     m_rangeStarts.clear();
--- a/audio/AudioCallbackPlaySource.h	Thu Jun 25 17:43:10 2020 +0100
+++ b/audio/AudioCallbackPlaySource.h	Fri Jun 26 13:48:52 2020 +0100
@@ -399,8 +399,7 @@
     void clearRingBuffers(bool haveLock = false, int count = 0);
     void unifyRingBuffers();
 
-    // Called from fill thread, m_playing true, mutex held
-    // Return true if work done
+    // Called from fill thread, mutex held.  Return true if work done
     bool fillBuffers();
     
     // Called from fillBuffers.  Return the number of frames written,
--- a/framework/Document.cpp	Thu Jun 25 17:43:10 2020 +0100
+++ b/framework/Document.cpp	Fri Jun 26 13:48:52 2020 +0100
@@ -64,6 +64,8 @@
 
 Document::~Document()
 {
+    Profiler profiler("Document::~Document");
+    
     //!!! Document should really own the command history.  atm we
     //still refer to it in various places that don't have access to
     //the document, be nice to fix that
@@ -115,6 +117,8 @@
 Layer *
 Document::createLayer(LayerFactory::LayerType type)
 {
+    Profiler profiler("Document::createLayer");
+    
     Layer *newLayer = LayerFactory::getInstance()->createLayer(type);
     if (!newLayer) return nullptr;
 
@@ -135,6 +139,8 @@
 Layer *
 Document::createMainModelLayer(LayerFactory::LayerType type)
 {
+    Profiler profiler("Document::createMainModelLayer");
+    
     Layer *newLayer = createLayer(type);
     if (!newLayer) return nullptr;
     setModel(newLayer, m_mainModel);
@@ -144,6 +150,8 @@
 Layer *
 Document::createImportedLayer(ModelId modelId)
 {
+    Profiler profiler("Document::createImportedLayer");
+    
     LayerFactory::LayerTypeSet types =
         LayerFactory::getInstance()->getValidLayerTypes(modelId);
 
@@ -180,6 +188,8 @@
 Layer *
 Document::createEmptyLayer(LayerFactory::LayerType type)
 {
+    Profiler profiler("Document::createEmptyLayer");
+    
     if (m_mainModel.isNone()) return nullptr;
 
     auto newModel =
@@ -202,6 +212,8 @@
 Document::createDerivedLayer(LayerFactory::LayerType type,
                              TransformId transform)
 {
+    Profiler profiler("Document::createDerivedLayer (type)");
+    
     Layer *newLayer = createLayer(type);
     if (!newLayer) return nullptr;
 
@@ -216,6 +228,8 @@
 Document::createDerivedLayer(const Transform &transform,
                              const ModelTransformer::Input &input)
 {
+    Profiler profiler("Document::createDerivedLayer (transform)");
+    
     Transforms transforms;
     transforms.push_back(transform);
     vector<Layer *> layers = createDerivedLayers(transforms, input);
@@ -227,6 +241,8 @@
 Document::createDerivedLayers(const Transforms &transforms,
                               const ModelTransformer::Input &input)
 {
+    Profiler profiler("Document::createDerivedLayers");
+    
     QString message;
     vector<ModelId> newModels =
         addDerivedModels(transforms, input, message, nullptr);
@@ -309,6 +325,8 @@
                                    const ModelTransformer::Input &input,
                                    LayerCreationHandler *handler)
 {
+    Profiler profiler("Document::createDerivedLayersAsync");
+    
     QString message;
 
     AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler);
@@ -351,6 +369,8 @@
 Document::createLayersForDerivedModels(vector<ModelId> newModels, 
                                        QStringList names)
 {
+    Profiler profiler("Document::createLayersForDerivedModels");
+    
     vector<Layer *> layers;
     
     for (int i = 0; in_range_for(newModels, i); ++i) {
@@ -400,6 +420,8 @@
 void
 Document::setMainModel(ModelId modelId)
 {
+    Profiler profiler("Document::setMainModel");
+    
     ModelId oldMainModel = m_mainModel;
     m_mainModel = modelId;
     
@@ -583,6 +605,8 @@
                                  const ModelTransformer::Input &input,
                                  ModelId outputModelToAdd)
 {
+    Profiler profiler("Document::addAlreadyDerivedModel");
+    
     if (m_models.find(outputModelToAdd) != m_models.end()) {
         SVCERR << "WARNING: Document::addAlreadyDerivedModel: Model already added"
                << endl;
@@ -620,6 +644,8 @@
 void
 Document::addNonDerivedModel(ModelId modelId)
 {
+    Profiler profiler("Document::addNonDerivedModel");
+    
     if (ModelById::isa<AggregateWaveModel>(modelId)) {
 #ifdef DEBUG_DOCUMENT
         SVCERR << "Document::addNonDerivedModel: Model " << modelId << " is an aggregate model, adding it to aggregates" << endl;
@@ -670,6 +696,8 @@
 void
 Document::addAdditionalModel(ModelId modelId)
 {
+    Profiler profiler("Document::addAdditionalModel");
+    
     if (m_models.find(modelId) != m_models.end()) {
         SVCERR << "WARNING: Document::addAdditionalModel: Model already added"
                << endl;
@@ -706,6 +734,8 @@
                           const ModelTransformer::Input &input,
                           QString &message)
 {
+    Profiler profiler("Document::addDerivedModel");
+    
     for (auto &rec : m_models) {
         if (rec.second.transform == transform &&
             rec.second.source == input.getModel() && 
@@ -728,6 +758,8 @@
                            QString &message,
                            AdditionalModelConverter *amc)
 {
+    Profiler profiler("Document::addDerivedModels");
+    
     vector<ModelId> mm = 
         ModelTransformerFactory::getInstance()->transformMultiple
         (transforms, input, message, amc);
@@ -768,6 +800,8 @@
 void
 Document::releaseModel(ModelId modelId)
 {
+    Profiler profiler("Document::releaseModel");
+    
     // This is called when a layer has been deleted or has replaced
     // its model, in order to reclaim storage for the old model. It
     // could be a no-op without making any functional difference, as
@@ -854,6 +888,8 @@
 void
 Document::deleteLayer(Layer *layer, bool force)
 {
+    Profiler profiler("Document::deleteLayer");
+    
     if (m_layerViewMap.find(layer) != m_layerViewMap.end() &&
         m_layerViewMap[layer].size() > 0) {
 
@@ -914,6 +950,8 @@
 void
 Document::setModel(Layer *layer, ModelId modelId)
 {
+    Profiler profiler("Document::setModel");
+    
     if (!modelId.isNone() && 
         modelId != m_mainModel &&
         m_models.find(modelId) == m_models.end()) {
--- a/framework/MainWindowBase.cpp	Thu Jun 25 17:43:10 2020 +0100
+++ b/framework/MainWindowBase.cpp	Fri Jun 26 13:48:52 2020 +0100
@@ -59,6 +59,7 @@
 #include "data/fileio/BZipFileDevice.h"
 #include "data/fileio/FileSource.h"
 #include "data/fileio/AudioFileReaderFactory.h"
+#include "data/fileio/TextTest.h"
 #include "rdf/RDFImporter.h"
 #include "rdf/RDFExporter.h"
 
@@ -160,6 +161,7 @@
     m_recentTransforms("RecentTransforms", 20),
     m_documentModified(false),
     m_openingAudioFile(false),
+    m_handlingOSC(false),
     m_labeller(nullptr),
     m_lastPlayStatusSec(0),
     m_initialDarkBackground(false),
@@ -373,7 +375,7 @@
 void
 MainWindowBase::emitHideSplash()
 {
-    SVDEBUG << "MainWindowBase: Hiding splash screen" << endl;
+    SVDEBUG << "MainWindowBase: Hiding splash screen (if not hidden already)" << endl;
     emit hideSplash(this);
 }
 
@@ -1465,18 +1467,17 @@
                            m_paneStack != nullptr &&
                            m_paneStack->getCurrentPane() != nullptr);
 
-    bool rdf = (source.getExtension().toLower() == "rdf" ||
-                source.getExtension().toLower() == "n3" ||
-                source.getExtension().toLower() == "ttl");
-
-    bool audio = AudioFileReaderFactory::getKnownExtensions().contains
-        (source.getExtension().toLower());
+    QString extension = source.getExtension().toLower();
+    
+    bool rdf = (extension == "rdf" || extension == "n3" || extension == "ttl");
+    bool audio =
+        AudioFileReaderFactory::getKnownExtensions().contains(extension);
 
     bool rdfSession = false;
     if (rdf) {
         RDFImporter::RDFDocumentType rdfType = 
             RDFImporter::identifyDocumentType
-            (QUrl::fromLocalFile(source.getLocalFilename()).toString());
+            (QUrl::fromLocalFile(source.getLocalFilename()));
         if (rdfType == RDFImporter::AudioRefAndAnnotations ||
             rdfType == RDFImporter::AudioRef) {
             rdfSession = true;
@@ -1516,7 +1517,20 @@
         } else if ((status = openPlaylist(source, mode)) != FileOpenFailed) {
             return status;
         } else if (!canImportLayer) {
-            return FileOpenWrongMode;
+            // We already checked whether the file is RDF: we know
+            // it's not. But if it's another format that might be
+            // supported as a layer, reply that we can't open a layer
+            // here - otherwise assume it's an unknown file format
+            if (ImageLayer::isImageFileSupported(source.getLocation())) {
+                return FileOpenWrongMode;
+            }
+            if (extension == "mid" || extension == "midi") {
+                return FileOpenWrongMode;
+            }                
+            if (TextTest::isApparentTextDocument(source)) {
+                return FileOpenWrongMode;
+            }                
+            return FileOpenFailed;
         } else if ((status = openImage(source)) != FileOpenFailed) {
             return status;
         } else if ((status = openLayer(source)) != FileOpenFailed) {
@@ -1565,10 +1579,10 @@
         }
     }
 
+    m_openingAudioFile = true;
+
     source.waitForData();
 
-    m_openingAudioFile = true;
-
     sv_samplerate_t rate = 0;
 
     SVDEBUG << "Checking whether to preserve incoming audio file's sample rate"
@@ -1681,8 +1695,13 @@
         }
     }
 
+    if (mode != ReplaceSession && !m_document) {
+        SVDEBUG << "File open mode requested is something other than ReplaceSession, but we have no document at all yet, so we must use ReplaceSession mode" << endl;
+        mode = ReplaceSession;
+    }
+
     if (mode == CreateAdditionalModel && getMainModelId().isNone()) {
-        SVDEBUG << "Mode is CreateAdditionalModel but we have no main model, switching to ReplaceSession mode" << endl;
+        SVDEBUG << "File open mode requested is CreateAdditionalModel, but we have no main model, so switching to ReplaceSession mode" << endl;
         mode = ReplaceSession;
     }
 
@@ -1904,7 +1923,7 @@
     QString path = source.getLocalFilename();
 
     RDFImporter::RDFDocumentType rdfType = 
-        RDFImporter::identifyDocumentType(QUrl::fromLocalFile(path).toString());
+        RDFImporter::identifyDocumentType(QUrl::fromLocalFile(path));
 
 //    cerr << "RDF type:  (in layer) " << (int) rdfType << endl;
 
@@ -2052,7 +2071,7 @@
 
     // We don't put the image file in Recent Files
 
-    cerr << "openImage: trying location \"" << source.getLocation() << "\" in image layer" << endl;
+    SVCERR << "openImage: trying location \"" << source.getLocation() << "\" in image layer" << endl;
 
     if (!il->addImage(m_viewManager->getGlobalCentreFrame(), source.getLocation())) {
         if (newLayer) {
@@ -2133,22 +2152,29 @@
     QString sessionExt = 
         InteractiveFileFinder::getInstance()->getApplicationSessionExtension();
 
-    if (source.getExtension().toLower() != sessionExt) {
-
-        RDFImporter::RDFDocumentType rdfType = 
-            RDFImporter::identifyDocumentType
-            (QUrl::fromLocalFile(source.getLocalFilename()).toString());
+    QString extension = source.getExtension().toLower();
+    
+    bool rdf = (extension == "rdf" || extension == "n3" || extension == "ttl");
+
+    if (extension != sessionExt) {
+
+        if (rdf) {
+        
+            RDFImporter::RDFDocumentType rdfType = 
+                RDFImporter::identifyDocumentType
+                (QUrl::fromLocalFile(source.getLocalFilename()));
 
 //        cerr << "RDF type: " << (int)rdfType << endl;
 
-        if (rdfType == RDFImporter::AudioRefAndAnnotations ||
-            rdfType == RDFImporter::AudioRef) {
-            return openSessionFromRDF(source);
-        } else if (rdfType != RDFImporter::NotRDF) {
-            return FileOpenFailed;
-        }
-
-        if (source.getExtension().toLower() == "xml") {
+            if (rdfType == RDFImporter::AudioRefAndAnnotations ||
+                rdfType == RDFImporter::AudioRef) {
+                return openSessionFromRDF(source);
+            } else if (rdfType != RDFImporter::NotRDF) {
+                return FileOpenFailed;
+            }
+
+        } else if (extension == "xml") {
+            
             if (SVFileReader::identifyXmlFile(source.getLocalFilename()) ==
                 SVFileReader::SVSessionFile) {
                 cerr << "This XML file looks like a session file, attempting to open it as a session" << endl;
@@ -2164,7 +2190,7 @@
     BZipFileDevice *bzFile = nullptr;
     QFile *rawFile = nullptr;
 
-    if (source.getExtension().toLower() == sessionExt) {
+    if (extension == sessionExt) {
         bzFile = new BZipFileDevice(source.getLocalFilename());
         if (!bzFile->open(QIODevice::ReadOnly)) {
             delete bzFile;
@@ -4141,6 +4167,7 @@
 void
 MainWindowBase::layerRemoved(Layer *)
 {
+    Profiler profiler("MainWindowBase::layerRemoved");
 //    SVDEBUG << "MainWindowBase::layerRemoved(" << layer << ")" << endl;
     updateMenuStates();
 }
@@ -4279,12 +4306,22 @@
 {
     if (!m_oscQueue || m_oscQueue->isEmpty()) return;
 
+    if (m_handlingOSC) {
+        SVDEBUG << "MainWindowBase::pollOSC: "
+                << "not making nested invocations, waiting"
+                << endl;
+        return;
+    }
+    
+    m_handlingOSC = true;
+
     while (!m_oscQueue->isEmpty()) {
 
         if (m_openingAudioFile) {
             SVDEBUG << "MainWindowBase::pollOSC: "
                     << "waiting for audio to finish loading"
                     << endl;
+            m_handlingOSC = false;
             return;
         }
 
@@ -4292,6 +4329,7 @@
             SVDEBUG << "MainWindowBase::pollOSC: "
                     << "waiting for running transforms to complete"
                     << endl;
+            m_handlingOSC = false;
             return;
         }
 
@@ -4304,6 +4342,7 @@
         if (message.getTarget() != 0) {
             SVCERR << "MainWindowBase::pollOSC: ignoring message with target "
                    << message.getTarget() << " (we are target 0)" << endl;
+            m_handlingOSC = false;
             continue;
         }
 
@@ -4314,10 +4353,12 @@
         
         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents |
                                     QEventLoop::ExcludeSocketNotifiers);
-
-        connect(m_oscQueue, SIGNAL(messagesAvailable()),
-                this, SLOT(pollOSC()));
     }
+
+    m_handlingOSC = false;
+
+    connect(m_oscQueue, SIGNAL(messagesAvailable()),
+            this, SLOT(pollOSC()));
 }
 
 void
--- a/framework/MainWindowBase.h	Thu Jun 25 17:43:10 2020 +0100
+++ b/framework/MainWindowBase.h	Fri Jun 26 13:48:52 2020 +0100
@@ -449,6 +449,7 @@
 
     bool                     m_documentModified;
     bool                     m_openingAudioFile;
+    bool                     m_handlingOSC;
 
     Labeller                *m_labeller;