Mercurial > hg > sonic-segmenter
changeset 3:36855d576f53
* Updates to putative segmenter program
| author | Chris Cannam |
|---|---|
| date | Tue, 09 Jun 2009 13:02:03 +0000 |
| parents | 965b71bb2d0f |
| children | a88c2a0279ba |
| files | main/MainWindow.cpp main/MainWindow.h |
| diffstat | 2 files changed, 223 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/main/MainWindow.cpp Thu Apr 23 08:58:15 2009 +0000 +++ b/main/MainWindow.cpp Tue Jun 09 13:02:03 2009 +0000 @@ -67,6 +67,7 @@ #include "base/UnitDatabase.h" #include "layer/ColourDatabase.h" #include "data/osc/OSCQueue.h" +#include "rdf/PluginRDFDescription.h" //!!! #include "data/model/AggregateWaveModel.h" @@ -122,6 +123,7 @@ m_recentFilesMenu(0), m_rightButtonMenu(0), m_rightButtonPlaybackMenu(0), + m_segmentersMenu(0), m_deleteSelectedAction(0), m_ffwdAction(0), m_rwdAction(0), @@ -165,13 +167,14 @@ settings.setValue("waveform", QString("<layer scale=\"%1\" channelMode=\"%2\"/>") - .arg(int(WaveformLayer::MeterScale)) -// .arg(int(WaveformLayer::LinearScale)) +// .arg(int(WaveformLayer::MeterScale)) + .arg(int(WaveformLayer::LinearScale)) .arg(int(WaveformLayer::MergeChannels))); settings.setValue("timevalues", QString("<layer plotStyle=\"%1\"/>") - .arg(int(TimeValueLayer::PlotStems))); +// .arg(int(TimeValueLayer::PlotStems))); + .arg(int(TimeValueLayer::PlotCurve))); settings.setValue("spectrogram", QString("<layer channel=\"-1\" windowSize=\"2048\" windowHopLevel=\"2\"/>")); @@ -185,8 +188,8 @@ settings.setValue("showstatusbar", false); settings.endGroup(); - m_viewManager->setAlignMode(true); - m_viewManager->setPlaySoloMode(true); +// m_viewManager->setAlignMode(true); +// m_viewManager->setPlaySoloMode(true); m_viewManager->setToolMode(ViewManager::NavigateMode); m_viewManager->setZoomWheelsEnabled(false); m_viewManager->setIlluminateLocalFeatures(false); @@ -319,6 +322,8 @@ frame->setLayout(layout); + findSegmentationTransforms(); + setupMenus(); setupToolbars(); setupHelpMenu(); @@ -359,6 +364,7 @@ setupFileMenu(); // setupEditMenu(); setupViewMenu(); + setupSegmentersMenu(); m_mainMenusCreated = true; } @@ -611,6 +617,72 @@ } void +MainWindow::setupSegmentersMenu() +{ + if (m_segmentersMenu) { + m_segmenterActions.clear(); + m_segmentersMenu->clear(); + } else { + m_segmentersMenu = menuBar()->addMenu(tr("&Segmenters")); + m_segmentersMenu->setTearOffEnabled(true); + m_segmentersMenu->setSeparatorsCollapsible(true); + } + + std::set<QString> seenNames, duplicateNames, seenPluginNames, duplicatePluginNames; + for (unsigned int i = 0; i < m_segmentationTransforms.size(); ++i) { + QString name = m_segmentationTransforms[i].name; + QString pluginName = name.section(": ", 0, 0); + if (seenNames.find(name) != seenNames.end()) { + duplicateNames.insert(name); + } else { + seenNames.insert(name); + } + if (seenPluginNames.find(pluginName) != seenPluginNames.end()) { + duplicatePluginNames.insert(pluginName); + } else { + seenPluginNames.insert(pluginName); + } + } + + for (unsigned int i = 0; i < m_segmentationTransforms.size(); ++i) { + + QString name = m_segmentationTransforms[i].name; + if (name == "") name = m_segmentationTransforms[i].identifier; + + QString maker = m_segmentationTransforms[i].maker; + if (maker == "") maker = tr("Unknown"); + maker.replace(QRegExp(tr(" [\\(<].*$")), ""); + + QString pluginName = name.section(": ", 0, 0); + QString output = name.section(": ", 1); + + if (duplicateNames.find(pluginName) != duplicateNames.end()) { + pluginName = QString("%1 <%2>") + .arg(pluginName) + .arg(m_segmentationTransforms[i].identifier.section(':', 1, 1)); + if (output == "") { + name = pluginName; + } else { + name = QString("%1: %2") + .arg(pluginName) + .arg(output); + } + } else if (duplicatePluginNames.find(pluginName) == + duplicatePluginNames.end()) { + name = pluginName; + } + + QAction *action = new QAction(tr("%1...").arg(name), this); + connect(action, SIGNAL(triggered()), this, SLOT(addSegmentation())); + m_segmenterActions[action] = m_segmentationTransforms[i].identifier; + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + action->setStatusTip(m_segmentationTransforms[i].longDescription); + + m_segmentersMenu->addAction(action); + } +} + +void MainWindow::setupHelpMenu() { QMenu *menu = menuBar()->addMenu(tr("&Help")); @@ -928,15 +1000,18 @@ createDocument(); m_document->setAutoAlignment(true); - Pane *pane = m_paneStack->addPane(); + Pane *pane; + Layer *waveform; - connect(pane, SIGNAL(contextHelpChanged(const QString &)), - this, SLOT(contextHelpChanged(const QString &))); - - Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform); - m_document->addLayerToView(pane, waveform); - - m_overview->registerView(pane); + for (int i = 0; i < 2; ++i) { + pane = m_paneStack->addPane(); + pane->setFollowGlobalPan(false); + connect(pane, SIGNAL(contextHelpChanged(const QString &)), + this, SLOT(contextHelpChanged(const QString &))); + waveform = m_document->createMainModelLayer(LayerFactory::Waveform); + m_document->addLayerToView(pane, waveform); + m_overview->registerView(pane); + } CommandHistory::getInstance()->clear(); CommandHistory::getInstance()->documentSaved(); @@ -1073,12 +1148,16 @@ } } -Model * +bool MainWindow::selectExistingModeLayer(Pane *pane, QString name) { - Model *model = 0; + // return false if we do not need to go on and create a new layer + // -- either because a suitable hidden one has been dredged up, or + // because no layer that needed replacing was found in this pane - bool have = false; + if (!m_document) return false; + + bool required = false; for (int i = 0; i < pane->getLayerCount(); ++i) { @@ -1087,7 +1166,20 @@ Model *lm = layer->getModel(); while (lm && lm->getSourceModel()) lm = lm->getSourceModel(); - if (dynamic_cast<WaveFileModel *>(lm)) model = lm; + if (dynamic_cast<WaveFileModel *>(lm)) { + if (lm == m_document->getMainModel()) { + required = true; + break; + } + } + } + + if (!required) return false; + + for (int i = 0; i < pane->getLayerCount(); ++i) { + + Layer *layer = pane->getLayer(i); + if (!layer) continue; QString ln = layer->objectName(); if (ln != name) { @@ -1095,11 +1187,7 @@ m_document->removeLayerFromView(pane, layer); continue; } - - have = true; } - - if (have) return 0; LayerSet &ls = m_hiddenLayers[pane]; bool found = false; @@ -1112,9 +1200,97 @@ } } - if (found) return 0; + return !found; +} - return model; +void +MainWindow::addSegmentation() +{ + QObject *s = sender(); + QAction *action = dynamic_cast<QAction *>(s); + + if (!action) { + std::cerr << "WARNING: MainWindow::addSegmentation: sender is not an action" + << std::endl; + return; + } + + TransformActionMap::iterator i = m_segmenterActions.find(action); + if (i == m_segmenterActions.end()) return; + + // We always ask for configuration, even if the plugin isn't + // supposed to be configurable, because we need to let the user + // change the execution context (block size etc). + + QString transformId = i->second; + + Transform transform = TransformFactory::getInstance()-> + getDefaultTransformFor(transformId); + + Model *defaultInputModel = m_document->getMainModel(); + std::vector<Model *> candidateInputModels; + candidateInputModels.push_back(defaultInputModel); + + ModelTransformer::Input input = ModelTransformerFactory::getInstance()-> + getConfigurationForTransform + (transform, + candidateInputModels, + defaultInputModel, + m_playSource, + 0, + 0); + + if (!input.getModel()) return; + +// std::cerr << "MainWindow::addLayer: Input model is " << input.getModel() << " \"" << input.getModel()->objectName().toStdString() << "\"" << std::endl << "transform:" << std::endl << transform.toXmlString().toStdString() << std::endl; + + Layer *newLayer = m_document->createDerivedLayer(transform, input); + + if (newLayer) { + + AddPaneCommand *command = new AddPaneCommand(this); + CommandHistory::getInstance()->addCommand(command); + + Pane *pane = command->getPane(); + if (!pane) return; + + // Set the source model to NULL to avoid us treating it as a + // different visualisation for the main model and replacing it + // when one of the visualisation mode toggles is activated + newLayer->getModel()->setSourceModel(0); + + m_document->addLayerToView(pane, newLayer); + m_document->setChannel(newLayer, input.getChannel()); +// m_paneStack->setCurrentLayer(pane, newLayer); + } + + updateMenuStates(); +} + +void +MainWindow::findSegmentationTransforms() +{ + m_segmentationTransforms.clear(); + TransformList all = + TransformFactory::getInstance()->getAllTransformDescriptions(); + for (TransformList::iterator i = all.begin(); i != all.end(); ++i) { + if (i->type != Transform::FeatureExtraction) continue; + Transform t; + t.setIdentifier(i->identifier); + QString pluginId = t.getPluginIdentifier(); + QString outputId = t.getOutput(); + PluginRDFDescription desc(pluginId); + if (!desc.haveDescription()) continue; + QString feature = desc.getOutputEventTypeURI(outputId); + if (feature == "") continue; + std::cerr << "Feature: " << feature.toStdString() << std::endl; + //!!! This is grotesque + if (feature.endsWith("Segment") || feature.endsWith("Change")) { + m_segmentationTransforms.push_back(*i); + } + } + std::cerr << "MainWindow::findSegmentationTransforms: Found " + << m_segmentationTransforms.size() << " transforms" << std::endl; } void @@ -1127,7 +1303,8 @@ Pane *pane = m_paneStack->getPane(i); if (!pane) continue; - Model *model = selectExistingModeLayer(pane, name); + if (!selectExistingModeLayer(pane, name)) continue; + Model *model = m_document->getMainModel(); if (!model) continue; TransformId id = "vamp:qm-vamp-plugins:qm-onsetdetector:detection_fn"; @@ -1145,7 +1322,8 @@ //!!! no equivalent for this yet context.updates = false; - Layer *newLayer = m_document->createDerivedLayer(transform, model); + Layer *newLayer = m_document->createDerivedLayer + (transform, model); if (newLayer) { newLayer->setObjectName(name); @@ -1154,7 +1332,7 @@ } } else { - std::cerr << "No Aubio onset detector plugin available" << std::endl; + std::cerr << "No QM onset detector plugin available" << std::endl; } } @@ -1171,7 +1349,8 @@ Pane *pane = m_paneStack->getPane(i); if (!pane) continue; - Model *model = selectExistingModeLayer(pane, name); + if (!selectExistingModeLayer(pane, name)) continue; + Model *model = m_document->getMainModel(); if (!model) continue; Layer *newLayer = m_document->createLayer(LayerFactory::Waveform); @@ -1194,7 +1373,8 @@ Pane *pane = m_paneStack->getPane(i); if (!pane) continue; - Model *model = selectExistingModeLayer(pane, name); + if (!selectExistingModeLayer(pane, name)) continue; + Model *model = m_document->getMainModel(); if (!model) continue; Layer *newLayer = m_document->createLayer(LayerFactory::Spectrogram); @@ -1217,7 +1397,8 @@ Pane *pane = m_paneStack->getPane(i); if (!pane) continue; - Model *model = selectExistingModeLayer(pane, name); + if (!selectExistingModeLayer(pane, name)) continue; + Model *model = m_document->getMainModel(); if (!model) continue; Layer *newLayer = m_document->createLayer
--- a/main/MainWindow.h Thu Apr 23 08:58:15 2009 +0000 +++ b/main/MainWindow.h Tue Jun 09 13:02:03 2009 +0000 @@ -29,6 +29,7 @@ #include "base/RecentFiles.h" #include "layer/LayerFactory.h" #include "transform/Transform.h" +#include "transform/TransformDescription.h" #include "framework/SVFileReader.h" #include "data/fileio/FileFinder.h" #include <map> @@ -131,6 +132,8 @@ virtual void setupRecentFilesMenu(); + virtual void addSegmentation(); + virtual void showLayerTree(); virtual void handleOSCMessage(const OSCMessage &); @@ -156,6 +159,7 @@ QMenu *m_recentFilesMenu; QMenu *m_rightButtonMenu; QMenu *m_rightButtonPlaybackMenu; + QMenu *m_segmentersMenu; QAction *m_deleteSelectedAction; QAction *m_ffwdAction; @@ -170,10 +174,15 @@ typedef std::map<Pane *, LayerSet> PaneLayerMap; PaneLayerMap m_hiddenLayers; + TransformList m_segmentationTransforms; + + void findSegmentationTransforms(); + virtual void setupMenus(); virtual void setupFileMenu(); virtual void setupEditMenu(); virtual void setupViewMenu(); + virtual void setupSegmentersMenu(); virtual void setupHelpMenu(); virtual void setupToolbars(); @@ -189,11 +198,14 @@ typedef std::map<Model *, Model *> ModelPairMap; ModelPairMap m_fftModelMap; + typedef std::map<QAction *, TransformId> TransformActionMap; + TransformActionMap m_segmenterActions; + virtual void closeEvent(QCloseEvent *e); bool checkSaveModified(); virtual void configureNewPane(Pane *p); - virtual Model *selectExistingModeLayer(Pane *, QString); + virtual bool selectExistingModeLayer(Pane *, QString); virtual void updateVisibleRangeDisplay(Pane *p) const; };
