# HG changeset patch # User Chris Cannam # Date 1353086086 0 # Node ID ab5b3300ba1ab3bb2a1c00197a47d317418951e0 # Parent c2a0d8666017496b9157ae00af90a7570208c588 Add analyser, calculate some transforms when a file is loaded diff -r c2a0d8666017 -r ab5b3300ba1a .hgsubstate --- a/.hgsubstate Fri Nov 16 13:22:37 2012 +0000 +++ b/.hgsubstate Fri Nov 16 17:14:46 2012 +0000 @@ -1,3 +1,3 @@ 5c045faf74a988a0721c1bbf50d4553b74a7d320 svapp -8b79ad680ee720488700402482fd17b63e4bc090 svcore -7ac63919fd52761b5ffc2cf3a4686b2e4ee88932 svgui +c9fc7728ab0d19a5496ce01a69c0eb99950df71e svcore +156a120345aebfa74dcca1d02d6a7dfa26bed483 svgui diff -r c2a0d8666017 -r ab5b3300ba1a src/Analyser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Analyser.cpp Fri Nov 16 17:14:46 2012 +0000 @@ -0,0 +1,112 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Tony + An intonation analysis and annotation tool + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006-2012 Chris Cannam and QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "Analyser.h" + +#include "transform/TransformFactory.h" +#include "transform/ModelTransformer.h" +#include "framework/Document.h" +#include "data/model/WaveFileModel.h" +#include "view/Pane.h" +#include "view/PaneStack.h" +#include "layer/Layer.h" +#include "layer/TimeValueLayer.h" +#include "layer/NoteLayer.h" +#include "layer/ColourDatabase.h" + +Analyser::Analyser() : + m_document(0), + m_fileModel(0), + m_pane(0) +{ +} + +Analyser::~Analyser() +{ +} + +void +Analyser::newFileLoaded(Document *doc, WaveFileModel *model, + PaneStack *paneStack, Pane *pane) +{ + m_document = doc; + m_fileModel = model; + m_pane = pane; + + TransformId f0 = "vamp:cepstral-pitchtracker:cepstral-pitchtracker:f0"; + TransformId notes = "vamp:cepstral-pitchtracker:cepstral-pitchtracker:notes"; + + // We don't want a waveform in the main pane. We must have a + // main-model layer of some sort, but the layers created by + // transforms are derived layers, so we'll create a time ruler for + // the main-model layer. It could subsequently be hidden if we + // didn't want it + + m_document->addLayerToView + (m_pane, m_document->createMainModelLayer(LayerFactory::TimeRuler)); + + Layer *layer = 0; + + layer = addLayerFor(f0); + + if (layer) { + TimeValueLayer *tvl = qobject_cast(layer); + if (tvl) { + tvl->setPlotStyle(TimeValueLayer::PlotDiscreteCurves); + tvl->setBaseColour(ColourDatabase::getInstance()-> + getColourIndex(QString("Black"))); + } + } + + layer = addLayerFor(notes); + + if (layer) { + NoteLayer *nl = qobject_cast(layer); + if (nl) { + nl->setBaseColour(ColourDatabase::getInstance()-> + getColourIndex(QString("Bright Blue"))); + } + } + + paneStack->setCurrentLayer(m_pane, layer); +} + +Layer * +Analyser::addLayerFor(TransformId id) +{ + TransformFactory *tf = TransformFactory::getInstance(); + + if (!tf->haveTransform(id)) { + std::cerr << "ERROR: Analyser::addLayerFor(" << id << "): Transform unknown" << std::endl; + return 0; + } + + Transform transform = tf->getDefaultTransformFor + (id, m_fileModel->getSampleRate()); + + transform.setStepSize(1024); + transform.setBlockSize(2048); + + ModelTransformer::Input input(m_fileModel, -1); + + Layer *layer; + layer = m_document->createDerivedLayer(transform, m_fileModel); + if (layer) { + m_document->addLayerToView(m_pane, layer); + } + + return layer; +} + diff -r c2a0d8666017 -r ab5b3300ba1a src/Analyser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Analyser.h Fri Nov 16 17:14:46 2012 +0000 @@ -0,0 +1,48 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Tony + An intonation analysis and annotation tool + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006-2012 Chris Cannam and QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef ANALYSER_H +#define ANALYSER_H + +#include + +#include "transform/Transform.h" + +class WaveFileModel; +class Pane; +class PaneStack; +class Document; +class Layer; + +class Analyser : public QObject +{ + Q_OBJECT + +public: + Analyser(); + virtual ~Analyser(); + + void newFileLoaded(Document *newDocument, WaveFileModel *model, + PaneStack *paneStack, Pane *pane); + +protected: + Document *m_document; + WaveFileModel *m_fileModel; + Pane *m_pane; + + Layer *addLayerFor(TransformId); +}; + +#endif diff -r c2a0d8666017 -r ab5b3300ba1a src/MainWindow.cpp --- a/src/MainWindow.cpp Fri Nov 16 13:22:37 2012 +0000 +++ b/src/MainWindow.cpp Fri Nov 16 17:14:46 2012 +0000 @@ -16,6 +16,8 @@ #include "../version.h" #include "MainWindow.h" +#include "Analyser.h" + #include "framework/Document.h" #include "view/Pane.h" @@ -114,28 +116,31 @@ settings.setValue("showstatusbar", false); settings.endGroup(); - m_viewManager->setAlignMode(true); - m_viewManager->setPlaySoloMode(true); + m_viewManager->setAlignMode(false); + m_viewManager->setPlaySoloMode(false); m_viewManager->setToolMode(ViewManager::NavigateMode); m_viewManager->setZoomWheelsEnabled(false); - m_viewManager->setIlluminateLocalFeatures(false); + m_viewManager->setIlluminateLocalFeatures(true); m_viewManager->setShowWorkTitle(true); + m_viewManager->setShowCentreLine(false); + m_viewManager->setOverlayMode(ViewManager::NoOverlays); QFrame *frame = new QFrame; setCentralWidget(frame); QGridLayout *layout = new QGridLayout; - m_descriptionLabel = new QLabel; - QScrollArea *scroll = new QScrollArea(frame); scroll->setWidgetResizable(true); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setFrameShape(QFrame::NoFrame); + // We have a pane stack: it comes with the territory. However, we + // have a fixed and known number of panes in it (e.g. 1) -- it + // isn't variable m_paneStack->setLayoutStyle(PaneStack::NoPropertyStacks); scroll->setWidget(m_paneStack); - + m_overview = new Overview(frame); m_overview->setViewManager(m_viewManager); m_overview->setFixedHeight(40); @@ -147,7 +152,6 @@ #endif connect(m_overview, SIGNAL(contextHelpChanged(const QString &)), this, SLOT(contextHelpChanged(const QString &))); - m_overview->hide(); m_panLayer = new WaveformLayer; m_panLayer->setChannelMode(WaveformLayer::MergeChannels); @@ -184,14 +188,8 @@ connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); layout->setSpacing(4); - layout->addWidget(scroll, 0, 0, 1, 6); - layout->addWidget(m_overview, 1, 1); - layout->addWidget(m_fader, 1, 2); - layout->addWidget(m_playSpeed, 1, 3); - - m_paneStack->setPropertyStackMinWidth - (m_fader->width() + m_playSpeed->width() + - layout->spacing() * 4); + layout->addWidget(m_overview, 0, 1); + layout->addWidget(scroll, 1, 1); layout->setColumnStretch(1, 10); @@ -203,11 +201,14 @@ statusBar(); + m_analyser = new Analyser(); + newSession(); } MainWindow::~MainWindow() { + delete m_analyser; delete m_keyReference; Profiles::getInstance()->dump(); } @@ -369,88 +370,6 @@ connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - - menu->addSeparator(); - - m_keyReference->setCategory(tr("Display Features")); - - QActionGroup *overlayGroup = new QActionGroup(this); - - action = new QAction(tr("Show &No Overlays"), this); - action->setShortcut(tr("0")); - action->setStatusTip(tr("Hide centre indicator, frame times, layer names and scale")); - connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays())); - action->setCheckable(true); - action->setChecked(false); - overlayGroup->addAction(action); - m_keyReference->registerShortcut(action); - menu->addAction(action); - - action = new QAction(tr("Show &Minimal Overlays"), this); - action->setShortcut(tr("9")); - action->setStatusTip(tr("Show centre indicator only")); - connect(action, SIGNAL(triggered()), this, SLOT(showMinimalOverlays())); - action->setCheckable(true); - action->setChecked(false); - overlayGroup->addAction(action); - m_keyReference->registerShortcut(action); - menu->addAction(action); - - action = new QAction(tr("Show &Standard Overlays"), this); - action->setShortcut(tr("8")); - action->setStatusTip(tr("Show centre indicator, frame times and scale")); - connect(action, SIGNAL(triggered()), this, SLOT(showStandardOverlays())); - action->setCheckable(true); - action->setChecked(true); - overlayGroup->addAction(action); - m_keyReference->registerShortcut(action); - menu->addAction(action); - - action = new QAction(tr("Show &All Overlays"), this); - action->setShortcut(tr("7")); - action->setStatusTip(tr("Show all texts and scale")); - connect(action, SIGNAL(triggered()), this, SLOT(showAllOverlays())); - action->setCheckable(true); - action->setChecked(false); - overlayGroup->addAction(action); - m_keyReference->registerShortcut(action); - menu->addAction(action); - - menu->addSeparator(); - - action = new QAction(tr("Show &Zoom Wheels"), this); - action->setShortcut(tr("Z")); - action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically")); - connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels())); - action->setCheckable(true); - action->setChecked(m_viewManager->getZoomWheelsEnabled()); - m_keyReference->registerShortcut(action); - menu->addAction(action); - - action = new QAction(tr("Show Property Bo&xes"), this); - action->setShortcut(tr("X")); - action->setStatusTip(tr("Show the layer property boxes at the side of the main window")); - connect(action, SIGNAL(triggered()), this, SLOT(togglePropertyBoxes())); - action->setCheckable(true); - action->setChecked(false); //!!! - m_keyReference->registerShortcut(action); - menu->addAction(action); - - action = new QAction(tr("Show Status &Bar"), this); - action->setStatusTip(tr("Show context help information in the status bar at the bottom of the window")); - connect(action, SIGNAL(triggered()), this, SLOT(toggleStatusBar())); - action->setCheckable(true); - action->setChecked(true); - menu->addAction(action); - - QSettings settings; - settings.beginGroup("MainWindow"); - bool sb = settings.value("showstatusbar", true).toBool(); - if (!sb) { - action->setChecked(false); - statusBar()->hide(); - } - settings.endGroup(); } void @@ -561,7 +480,7 @@ ffwdEndAction->setStatusTip(tr("Fast-forward to the end")); connect(ffwdEndAction, SIGNAL(triggered()), this, SLOT(ffwdEnd())); connect(this, SIGNAL(canPlay(bool)), ffwdEndAction, SLOT(setEnabled(bool))); -/* + toolbar = addToolBar(tr("Play Mode Toolbar")); QAction *psAction = toolbar->addAction(il.load("playselection"), @@ -586,33 +505,17 @@ connect(plAction, SIGNAL(triggered()), this, SLOT(playLoopToggled())); connect(this, SIGNAL(canPlay(bool)), plAction, SLOT(setEnabled(bool))); - QAction *soAction = toolbar->addAction(il.load("solo"), - tr("Solo Current Pane")); - soAction->setCheckable(true); - soAction->setChecked(m_viewManager->getPlaySoloMode()); - soAction->setShortcut(tr("o")); - soAction->setStatusTip(tr("Solo the current pane during playback")); - connect(m_viewManager, SIGNAL(playSoloModeChanged(bool)), - soAction, SLOT(setChecked(bool))); - connect(soAction, SIGNAL(triggered()), this, SLOT(playSoloToggled())); - connect(this, SIGNAL(canPlay(bool)), soAction, SLOT(setEnabled(bool))); - m_keyReference->registerShortcut(psAction); m_keyReference->registerShortcut(plAction); - m_keyReference->registerShortcut(soAction); -*/ m_keyReference->registerShortcut(playAction); m_keyReference->registerShortcut(m_rwdAction); m_keyReference->registerShortcut(m_ffwdAction); m_keyReference->registerShortcut(rwdStartAction); m_keyReference->registerShortcut(ffwdEndAction); -/* + menu->addAction(playAction); menu->addAction(psAction); menu->addAction(plAction); - menu->addAction(soAction); -*/ - menu->addAction(playAction); menu->addSeparator(); menu->addAction(m_rwdAction); menu->addAction(m_ffwdAction); @@ -622,11 +525,8 @@ menu->addSeparator(); m_rightButtonPlaybackMenu->addAction(playAction); -/* m_rightButtonPlaybackMenu->addAction(psAction); m_rightButtonPlaybackMenu->addAction(plAction); - m_rightButtonPlaybackMenu->addAction(soAction); -*/ m_rightButtonPlaybackMenu->addSeparator(); m_rightButtonPlaybackMenu->addAction(m_rwdAction); m_rightButtonPlaybackMenu->addAction(m_ffwdAction); @@ -660,10 +560,10 @@ m_rightButtonPlaybackMenu->addAction(fastAction); m_rightButtonPlaybackMenu->addAction(slowAction); m_rightButtonPlaybackMenu->addAction(normalAction); -/* - toolbar = addToolBar(tr("Edit Toolbar")); - CommandHistory::getInstance()->registerToolbar(toolbar); -*/ + + toolbar = addToolBar(tr("Playback Controls")); + toolbar->addWidget(m_playSpeed); + toolbar->addWidget(m_fader); Pane::registerShortcuts(*m_keyReference); } @@ -725,29 +625,7 @@ void MainWindow::updateDescriptionLabel() { - if (!getMainModel()) { - m_descriptionLabel->setText(tr("No audio file loaded.")); - return; - } - - QString description; - - size_t ssr = getMainModel()->getSampleRate(); - size_t tsr = ssr; - if (m_playSource) tsr = m_playSource->getTargetSampleRate(); - - if (ssr != tsr) { - description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); - } else { - description = QString("%1Hz").arg(ssr); - } - - description = QString("%1 - %2") - .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) - .toText(false).c_str()) - .arg(description); - - m_descriptionLabel->setText(description); + // Nothing, we don't have one } void @@ -776,8 +654,8 @@ connect(pane, SIGNAL(contextHelpChanged(const QString &)), this, SLOT(contextHelpChanged(const QString &))); - Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform); - m_document->addLayerToView(pane, waveform); +// Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform); +// m_document->addLayerToView(pane, waveform); m_overview->registerView(pane); @@ -918,7 +796,7 @@ void MainWindow::paneAdded(Pane *pane) { - pane->setPlaybackFollow(PlaybackScrollContinuous); + pane->setPlaybackFollow(PlaybackScrollPage); m_paneStack->sizePanesEqually(); if (m_overview) m_overview->registerView(pane); } @@ -980,21 +858,11 @@ { std::cerr << "MainWindow::configureNewPane(" << pane << ")" << std::endl; - if (!pane) return; + if (!pane) { + pane = m_paneStack->addPane(); + } - Layer *waveformLayer = 0; - - for (int i = 0; i < pane->getLayerCount(); ++i) { - Layer *layer = pane->getLayer(i); - if (!layer) continue; - if (qobject_cast(layer)) waveformLayer = layer; - if (qobject_cast(layer)) return; - } - if (!waveformLayer) return; - - waveformLayer->setObjectName(tr("Waveform")); - - zoomToFit(); + m_analyser->newFileLoaded(m_document, getMainModel(), m_paneStack, pane); } void @@ -1349,13 +1217,6 @@ } void -MainWindow::modelReady() -{ - QObject *s = sender(); - std::cerr << "MainWindow::modelReady(" << s << ")" << std::endl; -} - -void MainWindow::modelAboutToBeDeleted(Model *model) { MainWindowBase::modelAboutToBeDeleted(model); diff -r c2a0d8666017 -r ab5b3300ba1a src/MainWindow.h --- a/src/MainWindow.h Fri Nov 16 13:22:37 2012 +0000 +++ b/src/MainWindow.h Fri Nov 16 17:14:46 2012 +0000 @@ -18,6 +18,8 @@ #include "framework/MainWindowBase.h" +class Analyser; + class MainWindow : public MainWindowBase { Q_OBJECT @@ -73,7 +75,6 @@ virtual void mainModelChanged(WaveFileModel *); virtual void modelAdded(Model *); - virtual void modelReady(); virtual void modelAboutToBeDeleted(Model *); virtual void modelGenerationFailed(QString, QString); @@ -97,26 +98,26 @@ virtual void keyReference(); protected: - Overview *m_overview; - Fader *m_fader; - AudioDial *m_playSpeed; - QPushButton *m_playSharpen; - QPushButton *m_playMono; - WaveformLayer *m_panLayer; + Analyser *m_analyser; - bool m_mainMenusCreated; - QMenu *m_playbackMenu; - QMenu *m_recentFilesMenu; - QMenu *m_rightButtonMenu; - QMenu *m_rightButtonPlaybackMenu; + Overview *m_overview; + Fader *m_fader; + AudioDial *m_playSpeed; + QPushButton *m_playSharpen; + QPushButton *m_playMono; + WaveformLayer *m_panLayer; - QAction *m_deleteSelectedAction; - QAction *m_ffwdAction; - QAction *m_rwdAction; + bool m_mainMenusCreated; + QMenu *m_playbackMenu; + QMenu *m_recentFilesMenu; + QMenu *m_rightButtonMenu; + QMenu *m_rightButtonPlaybackMenu; - QLabel *m_descriptionLabel; + QAction *m_deleteSelectedAction; + QAction *m_ffwdAction; + QAction *m_rwdAction; - KeyReference *m_keyReference; + KeyReference *m_keyReference; virtual void setupMenus(); virtual void setupFileMenu(); diff -r c2a0d8666017 -r ab5b3300ba1a tonyapp.pro --- a/tonyapp.pro Fri Nov 16 13:22:37 2012 +0000 +++ b/tonyapp.pro Fri Nov 16 17:14:46 2012 +0000 @@ -33,8 +33,11 @@ RESOURCES += tony.qrc -HEADERS += src/MainWindow.h +HEADERS += src/MainWindow.h \ + src/Analyser.h + SOURCES += src/main.cpp \ + src/Analyser.cpp \ src/MainWindow.cpp QMAKE_INFO_PLIST = deploy/osx/Info.plist