changeset 6:ab5b3300ba1a

Add analyser, calculate some transforms when a file is loaded
author Chris Cannam
date Fri, 16 Nov 2012 17:14:46 +0000
parents c2a0d8666017
children 25b89208e00c
files .hgsubstate src/Analyser.cpp src/Analyser.h src/MainWindow.cpp src/MainWindow.h tonyapp.pro
diffstat 6 files changed, 214 insertions(+), 189 deletions(-) [+]
line wrap: on
line diff
--- 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
--- /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<TimeValueLayer *>(layer);
+	if (tvl) {
+	    tvl->setPlotStyle(TimeValueLayer::PlotDiscreteCurves);
+	    tvl->setBaseColour(ColourDatabase::getInstance()->
+			       getColourIndex(QString("Black")));
+	}
+    }
+
+    layer = addLayerFor(notes);
+
+    if (layer) {
+	NoteLayer *nl = qobject_cast<NoteLayer *>(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;
+}
+
--- /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 <QObject>
+
+#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
--- 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<WaveformLayer *>(layer)) waveformLayer = layer;
-        if (qobject_cast<TimeValueLayer *>(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);
--- 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();
--- 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