Mercurial > hg > svapp
changeset 728:2dce002539a0
Merge from branch spectrogram-export
author | Chris Cannam |
---|---|
date | Fri, 10 Jan 2020 14:54:43 +0000 |
parents | 55f317633b93 (current diff) e2ad6fe768b0 (diff) |
children | 15da3ab3d416 8cf265f9b1b3 |
files | |
diffstat | 3 files changed, 97 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/framework/MainWindowBase.cpp Fri Dec 06 13:09:29 2019 +0000 +++ b/framework/MainWindowBase.cpp Fri Jan 10 14:54:43 2020 +0000 @@ -37,6 +37,7 @@ #include "layer/NoteLayer.h" #include "layer/FlexiNoteLayer.h" #include "layer/RegionLayer.h" +#include "layer/SpectrogramLayer.h" #include "widgets/ListInputDialog.h" #include "widgets/CommandHistory.h" @@ -61,6 +62,8 @@ #include "rdf/RDFImporter.h" #include "rdf/RDFExporter.h" +#include "transform/ModelTransformerFactory.h" + #include "base/RecentFiles.h" #include "base/XmlExportable.h" @@ -159,7 +162,6 @@ m_recentTransforms("RecentTransforms", 20), m_documentModified(false), m_openingAudioFile(false), - m_abandoning(false), m_labeller(nullptr), m_lastPlayStatusSec(0), m_initialDarkBackground(false), @@ -527,7 +529,7 @@ connect(m_oscQueue, SIGNAL(messagesAvailable()), this, SLOT(pollOSC())); QTimer *oscTimer = new QTimer(this); connect(oscTimer, SIGNAL(timeout()), this, SLOT(pollOSC())); - oscTimer->start(1000); + oscTimer->start(2000); if (m_oscQueue->hasPort()) { SVDEBUG << "Finished setting up OSC interface" << endl; @@ -686,6 +688,9 @@ bool haveCurrentColour3DPlot = (haveCurrentLayer && dynamic_cast<Colour3DPlotLayer *>(currentLayer)); + bool haveCurrentSpectrogram = + (haveCurrentLayer && + dynamic_cast<SpectrogramLayer *>(currentLayer)); bool haveClipboardContents = (m_viewManager && !m_viewManager->getClipboard().empty()); @@ -704,7 +709,9 @@ emit canExportAudio(haveMainModel); emit canChangeSessionTemplate(haveMainModel); emit canExportLayer(haveMainModel && - (haveCurrentEditableLayer || haveCurrentColour3DPlot)); + (haveCurrentEditableLayer || + haveCurrentColour3DPlot || + haveCurrentSpectrogram)); emit canExportImage(haveMainModel && haveCurrentPane); emit canDeleteCurrentLayer(haveCurrentLayer); emit canRenameLayer(haveCurrentLayer); @@ -2797,13 +2804,20 @@ } bool -MainWindowBase::exportLayerTo(Layer *layer, QString path, QString &error) +MainWindowBase::exportLayerTo(Layer *layer, View *fromView, + MultiSelection *selectionsToWrite, + QString path, QString &error) { + //!!! should we pull out the whole export logic into another + // class? then we can more reasonably query it for things like + // "can we export this layer type to this file format? can we + // export selections, or only the whole layer?" + if (QFileInfo(path).suffix() == "") path += ".svl"; QString suffix = QFileInfo(path).suffix().toLower(); - auto model = ModelById::get(layer->getModel()); + auto model = ModelById::get(layer->getExportModel(fromView)); if (!model) { error = tr("Internal error: unknown model"); return false; @@ -2839,8 +2853,27 @@ if (!nm) { error = tr("Can't export non-note layers to MIDI"); + } else if (!selectionsToWrite) { + MIDIFileWriter writer(path, nm.get(), nm->getSampleRate()); + writer.write(); + if (!writer.isOK()) { + error = writer.getError(); + } } else { - MIDIFileWriter writer(path, nm.get(), nm->getSampleRate()); + NoteModel temporary(nm->getSampleRate(), + nm->getResolution(), + nm->getValueMinimum(), + nm->getValueMaximum(), + false); + temporary.setScaleUnits(nm->getScaleUnits()); + for (const auto &s: selectionsToWrite->getSelections()) { + EventVector ev(nm->getEventsStartingWithin + (s.getStartFrame(), s.getDuration())); + for (const auto &e: ev) { + temporary.add(e); + } + } + MIDIFileWriter writer(path, &temporary, temporary.getSampleRate()); writer.write(); if (!writer.isOK()) { error = writer.getError(); @@ -2861,12 +2894,25 @@ } else { - CSVFileWriter writer(path, model.get(), + ProgressDialog dialog { + QObject::tr("Exporting layer..."), true, 500, this, + Qt::ApplicationModal + }; + + CSVFileWriter writer(path, model.get(), &dialog, ((suffix == "csv") ? "," : "\t")); - writer.write(); + + if (selectionsToWrite) { + writer.writeSelection(*selectionsToWrite); + } else { + writer.write(); + } if (!writer.isOK()) { error = writer.getError(); + if (error == "") { + error = tr("Failed to export layer for an unknown reason"); + } } } @@ -4164,17 +4210,46 @@ MainWindowBase::pollOSC() { if (!m_oscQueue || m_oscQueue->isEmpty()) return; - SVDEBUG << "MainWindowBase::pollOSC: have " << m_oscQueue->getMessagesAvailable() << " messages" << endl; - - if (m_openingAudioFile) return; - - OSCMessage message = m_oscQueue->readMessage(); - - if (message.getTarget() != 0) { - return; //!!! for now -- this class is target 0, others not handled yet + + while (!m_oscQueue->isEmpty()) { + + if (m_openingAudioFile) { + SVDEBUG << "MainWindowBase::pollOSC: " + << "waiting for audio to finish loading" + << endl; + return; + } + + if (ModelTransformerFactory::getInstance()->haveRunningTransformers()) { + SVDEBUG << "MainWindowBase::pollOSC: " + << "waiting for running transforms to complete" + << endl; + return; + } + + SVDEBUG << "MainWindowBase::pollOSC: have " + << m_oscQueue->getMessagesAvailable() + << " messages" << endl; + + OSCMessage message = m_oscQueue->readMessage(); + + if (message.getTarget() != 0) { + SVCERR << "MainWindowBase::pollOSC: ignoring message with target " + << message.getTarget() << " (we are target 0)" << endl; + continue; + } + + handleOSCMessage(message); + + disconnect(m_oscQueue, SIGNAL(messagesAvailable()), + this, SLOT(pollOSC())); + + QApplication::processEvents(QEventLoop::ExcludeUserInputEvents | + QEventLoop::ExcludeSocketNotifiers); + + connect(m_oscQueue, SIGNAL(messagesAvailable()), + this, SLOT(pollOSC())); } - - handleOSCMessage(message); } void
--- a/framework/MainWindowBase.h Fri Dec 06 13:09:29 2019 +0000 +++ b/framework/MainWindowBase.h Fri Jan 10 14:54:43 2020 +0000 @@ -165,7 +165,9 @@ virtual bool saveSessionFile(QString path); virtual bool saveSessionTemplate(QString path); - virtual bool exportLayerTo(Layer *layer, QString path, QString &error); + virtual bool exportLayerTo(Layer *layer, View *fromView, + MultiSelection *selectionsToWrite, // or null + QString toPath, QString &error); void cueOSCScript(QString filename); @@ -428,7 +430,6 @@ bool m_documentModified; bool m_openingAudioFile; - bool m_abandoning; Labeller *m_labeller;
--- a/framework/OSCScript.h Fri Dec 06 13:09:29 2019 +0000 +++ b/framework/OSCScript.h Fri Jan 10 14:54:43 2020 +0000 @@ -105,7 +105,7 @@ message.addArg(parts[i]); } SVCERR << "OSCScript: " << reportedFilename << ":" << lineno - << ": invoking: \"" << parts[0] << "\"" << endl; + << ": posting " << message.toString() << endl; m_queue->postMessage(message); } else {