# HG changeset patch # User Chris Cannam # Date 1391524637 0 # Node ID 5350581c3bcb494ef0a58a3704b8d235f3000471 # Parent 23aa4b7612a962f49c47d543954bd5d32a6da975# Parent 096d668d010d1c6bf1e563812f8bb8c8db6c9517 Merge diff -r 096d668d010d -r 5350581c3bcb .hgsubstate --- a/.hgsubstate Tue Feb 04 13:59:57 2014 +0000 +++ b/.hgsubstate Tue Feb 04 14:37:17 2014 +0000 @@ -1,5 +1,5 @@ 236814e07bd07473958c1ff89103124536a0c3c8 dataquay 27d4e7152c954bf3c4387319db088fb3cd02436b sv-dependency-builds f72d58d1ccb0736f4ab40853986d5952e0dd8321 svapp -a2689db084f49daf0dcac1bea13d33c51f600266 svcore -15b5c679b90924f4bdfc0afac2c97355d841bfbe svgui +d81c16e47e22b1c1a6600d3e9a8e0559fad8b539 svcore +d1c0abfb11bef9bf9af010a8468f6c2a717d36bb svgui diff -r 096d668d010d -r 5350581c3bcb src/Analyser.cpp --- a/src/Analyser.cpp Tue Feb 04 13:59:57 2014 +0000 +++ b/src/Analyser.cpp Tue Feb 04 14:37:17 2014 +0000 @@ -74,6 +74,7 @@ m_reAnalysingSelection = Selection(); m_reAnalysisCandidates.clear(); + m_currentCandidate = -1; // Note that we need at least one main-model layer (time ruler, // waveform or what have you). It could be hidden if we don't want @@ -136,6 +137,7 @@ spectrogram->setNormalizeHybrid(true); // spectrogram->setSmooth(true); // spectrogram->setGain(0.5); //!!! arbitrary at this point + spectrogram->setMinFrequency(15); spectrogram->setGain(100); m_document->addLayerToView(m_pane, spectrogram); spectrogram->setLayerDormant(m_pane, true); @@ -250,12 +252,8 @@ { if (sel == m_reAnalysingSelection) return ""; - foreach (Layer *layer, m_reAnalysisCandidates) { - cerr << "deleting previous candidate layer " << layer << endl; - m_pane->removeLayer(layer); - m_document->deleteLayer(layer); // also releases its model - } - m_reAnalysisCandidates.clear(); + clearReAnalysis(); + m_reAnalysingSelection = sel; TransformFactory *tf = TransformFactory::getInstance(); @@ -305,17 +303,23 @@ //!!! how do we know these came from the right selection? user //!!! might have made another one since this request was issued + vector all; for (int i = 0; i < (int)primary.size(); ++i) { - TimeValueLayer *t = qobject_cast(primary[i]); - if (t) { - m_document->addLayerToView(m_pane, t); - m_reAnalysisCandidates.push_back(t); - } + all.push_back(primary[i]); + } + for (int i = 0; i < (int)additional.size(); ++i) { + all.push_back(additional[i]); } - for (int i = 0; i < (int)additional.size(); ++i) { - TimeValueLayer *t = qobject_cast(additional[i]); + for (int i = 0; i < (int)all.size(); ++i) { + TimeValueLayer *t = qobject_cast(all[i]); if (t) { + PlayParameters *params = t->getPlayParameters(); + if (params) { + params->setPlayAudible(false); + } + t->setBaseColour + (ColourDatabase::getInstance()->getColourIndex(tr("Bright Orange"))); m_document->addLayerToView(m_pane, t); m_reAnalysisCandidates.push_back(t); } @@ -323,6 +327,93 @@ } void +Analyser::switchPitchCandidate(Selection sel, bool up) +{ + if (m_reAnalysisCandidates.empty()) return; + + if (up) { + m_currentCandidate = m_currentCandidate + 1; + if (m_currentCandidate >= (int)m_reAnalysisCandidates.size()) { + m_currentCandidate = 0; + } + } else { + m_currentCandidate = m_currentCandidate - 1; + if (m_currentCandidate < 0) { + m_currentCandidate = (int)m_reAnalysisCandidates.size() - 1; + } + } + + Layer *pitchTrack = m_layers[PitchTrack]; + if (!pitchTrack) return; + + Clipboard clip; + pitchTrack->deleteSelection(sel); + m_reAnalysisCandidates[m_currentCandidate]->copy(m_pane, sel, clip); + pitchTrack->paste(m_pane, clip, 0, false); + + // raise the pitch track, then notes on top (if present) + m_paneStack->setCurrentLayer(m_pane, m_layers[PitchTrack]); + if (m_layers[Notes] && !m_layers[Notes]->isLayerDormant(m_pane)) { + m_paneStack->setCurrentLayer(m_pane, m_layers[Notes]); + } +} + +void +Analyser::shiftOctave(Selection sel, bool up) +{ + float factor = (up ? 2.f : 0.5f); + + vector actOn; + + Layer *pitchTrack = m_layers[PitchTrack]; + if (pitchTrack) actOn.push_back(pitchTrack); + + foreach (Layer *c, m_reAnalysisCandidates) { + actOn.push_back(c); + } + + foreach (Layer *layer, actOn) { + + Clipboard clip; + layer->copy(m_pane, sel, clip); + layer->deleteSelection(sel); + + Clipboard shifted; + foreach (Clipboard::Point p, clip.getPoints()) { + if (p.haveValue()) { + Clipboard::Point sp = p.withValue(p.getValue() * factor); + shifted.addPoint(sp); + } else { + shifted.addPoint(p); + } + } + + layer->paste(m_pane, shifted, 0, false); + } +} + +void +Analyser::clearPitches(Selection sel) +{ + Layer *pitchTrack = m_layers[PitchTrack]; + if (!pitchTrack) return; + + pitchTrack->deleteSelection(sel); +} + +void +Analyser::clearReAnalysis() +{ + foreach (Layer *layer, m_reAnalysisCandidates) { + m_document->removeLayerFromView(m_pane, layer); + m_document->deleteLayer(layer); // also releases its model + } + m_reAnalysisCandidates.clear(); + m_reAnalysingSelection = Selection(); + m_currentCandidate = -1; +} + +void Analyser::getEnclosingSelectionScope(size_t f, size_t &f0, size_t &f1) { FlexiNoteLayer *flexiNoteLayer = @@ -396,8 +487,17 @@ if (m_layers[c]) { m_layers[c]->setLayerDormant(m_pane, !v); - if (v && (c == Notes)) { - m_paneStack->setCurrentLayer(m_pane, m_layers[c]); + if (v) { + if (c == Notes) { + m_paneStack->setCurrentLayer(m_pane, m_layers[c]); + } else if (c == PitchTrack) { + // raise the pitch track, then notes on top (if present) + m_paneStack->setCurrentLayer(m_pane, m_layers[c]); + if (m_layers[Notes] && + !m_layers[Notes]->isLayerDormant(m_pane)) { + m_paneStack->setCurrentLayer(m_pane, m_layers[Notes]); + } + } } m_pane->layerParametersChanged(); diff -r 096d668d010d -r 5350581c3bcb src/Analyser.h --- a/src/Analyser.h Tue Feb 04 13:59:57 2014 +0000 +++ b/src/Analyser.h Tue Feb 04 14:37:17 2014 +0000 @@ -90,6 +90,30 @@ */ QString reAnalyseSelection(Selection sel); + /** + * If a re-analysis has been activated, switch the selected area + * of the main pitch track to a different candidate from the + * analysis results. + */ + void switchPitchCandidate(Selection sel, bool up); + + /** + * Remove the pitch estimates from the selected area of the main + * pitch track. + */ + void clearPitches(Selection sel); + + /** + * Move the main pitch track and any active analysis candidate + * tracks up or down an octave in the selected area. + */ + void shiftOctave(Selection sel, bool up); + + /** + * Remove any re-analysis layers. + */ + void clearReAnalysis(); + signals: void layersChanged(); @@ -103,6 +127,7 @@ Selection m_reAnalysingSelection; std::vector m_reAnalysisCandidates; + int m_currentCandidate; QString addVisualisations(); QString addWaveform(); diff -r 096d668d010d -r 5350581c3bcb src/MainWindow.cpp --- a/src/MainWindow.cpp Tue Feb 04 13:59:57 2014 +0000 +++ b/src/MainWindow.cpp Tue Feb 04 14:37:17 2014 +0000 @@ -85,7 +85,6 @@ MainWindowBase(withAudioOutput, withOSCSupport, false), m_overview(0), m_mainMenusCreated(false), - m_intelligentActionOn(true), //GF: !!! temporary m_playbackMenu(0), m_recentFilesMenu(0), m_rightButtonMenu(0), @@ -93,6 +92,7 @@ m_deleteSelectedAction(0), m_ffwdAction(0), m_rwdAction(0), + m_intelligentActionOn(true), //GF: !!! temporary m_keyReference(new KeyReference()) { setWindowTitle(QApplication::applicationName()); @@ -525,6 +525,13 @@ menu->addSeparator(); //!!! shortcuts, status tip, key reference etc + action = new QAction(tr("Clear Pitches"), this); + action->setShortcut(tr("Backspace")); + connect(action, SIGNAL(triggered()), this, SLOT(clearPitches())); + connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool))); + menu->addAction(action); + + //!!! shortcuts, status tip, key reference etc action = new QAction(tr("Octave Shift Up"), this); action->setShortcut(tr("PgUp")); connect(action, SIGNAL(triggered()), this, SLOT(octaveShiftUp())); @@ -536,6 +543,13 @@ connect(action, SIGNAL(triggered()), this, SLOT(octaveShiftDown())); connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool))); menu->addAction(action); + + //!!! shortcuts, status tip, key reference etc + action = new QAction(tr("Switch Pitch Candidate"), this); + action->setShortcut(tr("Return")); + connect(action, SIGNAL(triggered()), this, SLOT(switchPitch())); + connect(this, SIGNAL(canClearSelection(bool)), action, SLOT(setEnabled(bool))); + menu->addAction(action); } void @@ -1119,29 +1133,29 @@ while (m_paneStack->getPaneCount() > 0) { - Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); + Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); - while (pane->getLayerCount() > 0) { - m_document->removeLayerFromView - (pane, pane->getLayer(pane->getLayerCount() - 1)); - } - - m_overview->unregisterView(pane); - m_paneStack->deletePane(pane); + while (pane->getLayerCount() > 0) { + m_document->removeLayerFromView + (pane, pane->getLayer(pane->getLayerCount() - 1)); + } + + m_overview->unregisterView(pane); + m_paneStack->deletePane(pane); } while (m_paneStack->getHiddenPaneCount() > 0) { - Pane *pane = m_paneStack->getHiddenPane - (m_paneStack->getHiddenPaneCount() - 1); - - while (pane->getLayerCount() > 0) { - m_document->removeLayerFromView - (pane, pane->getLayer(pane->getLayerCount() - 1)); - } - - m_overview->unregisterView(pane); - m_paneStack->deletePane(pane); + Pane *pane = m_paneStack->getHiddenPane + (m_paneStack->getHiddenPaneCount() - 1); + + while (pane->getLayerCount() > 0) { + m_document->removeLayerFromView + (pane, pane->getLayer(pane->getLayerCount() - 1)); + } + + m_overview->unregisterView(pane); + m_paneStack->deletePane(pane); } delete m_document; @@ -1631,6 +1645,19 @@ } void +MainWindow::clearSelection() +{ + cerr << "MainWindow::clearSelection()" << endl; + + CommandHistory::getInstance()->startCompoundOperation(tr("Clear Selection"), true); + + m_analyser->clearReAnalysis(); + MainWindowBase::clearSelection(); + + CommandHistory::getInstance()->endCompoundOperation(); +} + +void MainWindow::selectionChanged() { MultiSelection::SelectionList selections = m_viewManager->getSelections(); @@ -1650,6 +1677,21 @@ } void +MainWindow::clearPitches() +{ + MultiSelection::SelectionList selections = m_viewManager->getSelections(); + + CommandHistory::getInstance()->startCompoundOperation(tr("Clear Pitches"), true); + + for (MultiSelection::SelectionList::iterator k = selections.begin(); + k != selections.end(); ++k) { + m_analyser->clearPitches(*k); + } + + CommandHistory::getInstance()->endCompoundOperation(); +} + +void MainWindow::octaveShiftUp() { octaveShift(true); @@ -1664,43 +1706,30 @@ void MainWindow::octaveShift(bool up) { - float factor = (up ? 2.f : 0.5f); - MultiSelection::SelectionList selections = m_viewManager->getSelections(); CommandHistory::getInstance()->startCompoundOperation(tr("Octave Shift"), true); - for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { + for (MultiSelection::SelectionList::iterator k = selections.begin(); + k != selections.end(); ++k) { - Pane *pane = m_paneStack->getPane(i); - if (!pane) continue; + m_analyser->shiftOctave(*k, up); + } - for (int j = 0; j < pane->getLayerCount(); ++j) { + CommandHistory::getInstance()->endCompoundOperation(); +} - Layer *layer = pane->getLayer(j); - if (!layer) continue; +void +MainWindow::switchPitch() +{ + CommandHistory::getInstance()->startCompoundOperation + (tr("Switch Pitch Candidate"), true); - for (MultiSelection::SelectionList::iterator k = selections.begin(); - k != selections.end(); ++k) { + MultiSelection::SelectionList selections = m_viewManager->getSelections(); - Clipboard clip; - layer->copy(pane, *k, clip); - layer->deleteSelection(*k); - - Clipboard shifted; - foreach (Clipboard::Point p, clip.getPoints()) { - if (p.haveValue()) { - Clipboard::Point sp = - p.withValue(p.getValue() * factor); - shifted.addPoint(sp); - } else { - shifted.addPoint(p); - } - } - - layer->paste(pane, shifted, 0, false); - } - } + for (MultiSelection::SelectionList::iterator k = selections.begin(); + k != selections.end(); ++k) { + m_analyser->switchPitchCandidate(*k, true); } CommandHistory::getInstance()->endCompoundOperation(); diff -r 096d668d010d -r 5350581c3bcb src/MainWindow.h --- a/src/MainWindow.h Tue Feb 04 13:59:57 2014 +0000 +++ b/src/MainWindow.h Tue Feb 04 14:37:17 2014 +0000 @@ -50,8 +50,10 @@ virtual void toolEditSelected(); virtual void toolFreeEditSelected(); + virtual void clearPitches(); virtual void octaveShiftUp(); virtual void octaveShiftDown(); + virtual void switchPitch(); virtual void showAudioToggled(); virtual void showSpectToggled(); @@ -63,6 +65,7 @@ virtual void playNotesToggled(); virtual void doubleClickSelectInvoked(size_t); + virtual void clearSelection(); virtual void paneAdded(Pane *); virtual void paneHidden(Pane *);