annotate src/Analyser.h @ 576:335fd9b439a0

Fix failure to use the FlexiNoteLayer for the note layer
author Chris Cannam
date Thu, 18 Jul 2019 14:43:41 +0100
parents 3f0b44418a19
children
rev   line source
Chris@6 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@6 2
Chris@6 3 /*
Chris@6 4 Tony
Chris@6 5 An intonation analysis and annotation tool
Chris@6 6 Centre for Digital Music, Queen Mary, University of London.
Chris@6 7 This file copyright 2006-2012 Chris Cannam and QMUL.
Chris@6 8
Chris@6 9 This program is free software; you can redistribute it and/or
Chris@6 10 modify it under the terms of the GNU General Public License as
Chris@6 11 published by the Free Software Foundation; either version 2 of the
Chris@6 12 License, or (at your option) any later version. See the file
Chris@6 13 COPYING included with this distribution for more information.
Chris@6 14 */
Chris@6 15
Chris@6 16 #ifndef ANALYSER_H
Chris@6 17 #define ANALYSER_H
Chris@6 18
Chris@6 19 #include <QObject>
Chris@191 20 #include <QRect>
Chris@341 21 #include <QMutex>
Chris@6 22
Chris@128 23 #include <map>
Chris@163 24 #include <vector>
Chris@163 25
Chris@163 26 #include "framework/Document.h"
Chris@164 27 #include "base/Selection.h"
Chris@194 28 #include "base/Clipboard.h"
Chris@572 29 #include "data/model/WaveFileModel.h"
Chris@6 30
Chris@6 31 class Pane;
Chris@6 32 class PaneStack;
Chris@6 33 class Layer;
Chris@128 34 class TimeValueLayer;
Chris@128 35 class Layer;
Chris@6 36
Chris@163 37 class Analyser : public QObject,
Chris@163 38 public Document::LayerCreationHandler
Chris@6 39 {
Chris@6 40 Q_OBJECT
Chris@6 41
Chris@6 42 public:
Chris@6 43 Analyser();
Chris@6 44 virtual ~Analyser();
Chris@6 45
Chris@572 46 // Process new main model, add derived layers; return "" on
Chris@572 47 // success or error string on failure
Chris@572 48 QString newFileLoaded(Document *newDocument,
Chris@572 49 ModelId model,
Chris@572 50 PaneStack *paneStack,
Chris@572 51 Pane *pane);
Chris@226 52
Chris@572 53 // Remove any derived layers, process the main model, add derived
Chris@572 54 // layers; return "" on success or error string on failure
Chris@325 55 QString analyseExistingFile();
Chris@325 56
Chris@226 57 // Discard any layers etc associated with the current document
Chris@226 58 void fileClosed();
gyorgyf@45 59
gyorgyf@45 60 void setIntelligentActions(bool);
Chris@6 61
Chris@399 62 bool getDisplayFrequencyExtents(double &min, double &max);
Chris@399 63 bool setDisplayFrequencyExtents(double min, double max);
Chris@227 64
Chris@314 65 // Return completion %age for initial analysis -- 100 means it's done
Chris@314 66 int getInitialAnalysisCompletion();
Chris@314 67
Chris@128 68 enum Component {
Chris@242 69 Audio = 0,
Chris@242 70 PitchTrack = 1,
Chris@242 71 Notes = 2,
Chris@242 72 Spectrogram = 3,
Chris@128 73 };
Chris@128 74
Chris@128 75 bool isVisible(Component c) const;
Chris@128 76 void setVisible(Component c, bool v);
Chris@144 77 void toggleVisible(Component c) { setVisible(c, !isVisible(c)); }
Chris@128 78
Chris@128 79 bool isAudible(Component c) const;
Chris@128 80 void setAudible(Component c, bool v);
Chris@144 81 void toggleAudible(Component c) { setAudible(c, !isAudible(c)); }
Chris@128 82
Chris@128 83 void cycleStatus(Component c) {
Chris@128 84 if (isVisible(c)) {
Chris@128 85 if (isAudible(c)) {
Chris@128 86 setVisible(c, false);
Chris@128 87 setAudible(c, false);
Chris@128 88 } else {
Chris@128 89 setAudible(c, true);
Chris@128 90 }
Chris@128 91 } else {
Chris@128 92 setVisible(c, true);
Chris@128 93 setAudible(c, false);
Chris@128 94 }
Chris@128 95 }
Chris@128 96
Chris@572 97 ModelId getMainModelId() const {
Chris@260 98 return m_fileModel;
Chris@260 99 }
Chris@572 100 std::shared_ptr<WaveFileModel> getMainModel() const {
Chris@572 101 return ModelById::getAs<WaveFileModel>(m_fileModel);
Chris@572 102 }
Chris@260 103
Chris@158 104 float getGain(Component c) const;
Chris@158 105 void setGain(Component c, float gain);
Chris@158 106
Chris@158 107 float getPan(Component c) const;
Chris@158 108 void setPan(Component c, float pan);
Chris@158 109
Chris@399 110 void getEnclosingSelectionScope(sv_frame_t f, sv_frame_t &f0, sv_frame_t &f1);
Chris@139 111
Chris@192 112 struct FrequencyRange {
Chris@192 113 FrequencyRange() : min(0), max(0) { }
Chris@399 114 FrequencyRange(double min_, double max_) : min(min_), max(max_) { }
Chris@192 115 bool isConstrained() const { return min != max; }
Chris@399 116 double min;
Chris@399 117 double max;
Chris@396 118 bool operator==(const FrequencyRange &r) {
Chris@396 119 return min == r.min && max == r.max;
Chris@396 120 }
Chris@192 121 };
Chris@192 122
Chris@164 123 /**
Chris@165 124 * Analyse the selection and schedule asynchronous adds of
Chris@165 125 * candidate layers for the region it contains. Returns "" on
Chris@192 126 * success or a user-readable error string on failure. If the
Chris@192 127 * frequency range isConstrained(), analysis will be constrained
Chris@192 128 * to that range.
Chris@164 129 */
Chris@192 130 QString reAnalyseSelection(Selection sel, FrequencyRange range);
Chris@164 131
Chris@167 132 /**
Chris@184 133 * Return true if the analysed pitch candidates are currently
Chris@199 134 * visible (they are hidden from the call to reAnalyseSelection
Chris@199 135 * until they are requested through showPitchCandidates()). Note
Chris@199 136 * that this may return true even when no pitch candidate layers
Chris@199 137 * actually exist yet, because they are constructed
Chris@199 138 * asynchronously. If that is the case, then the layers will
Chris@199 139 * appear when they are created (otherwise they will remain hidden
Chris@199 140 * after creation).
Chris@184 141 */
Chris@184 142 bool arePitchCandidatesShown() const;
Chris@184 143
Chris@184 144 /**
Chris@199 145 * Show or hide the analysed pitch candidate layers. This is reset
Chris@199 146 * (to "hide") with each new call to reAnalyseSelection. Because
Chris@199 147 * the layers are created asynchronously, setting this to true
Chris@199 148 * does not guarantee that they appear immediately, only that they
Chris@199 149 * will appear once they have been created.
Chris@184 150 */
Chris@184 151 void showPitchCandidates(bool shown);
Chris@184 152
Chris@184 153 /**
Chris@167 154 * If a re-analysis has been activated, switch the selected area
Chris@167 155 * of the main pitch track to a different candidate from the
Chris@167 156 * analysis results.
Chris@167 157 */
Chris@167 158 void switchPitchCandidate(Selection sel, bool up);
Chris@167 159
Chris@167 160 /**
Chris@199 161 * Return true if it is possible to switch up to another pitch
Chris@199 162 * candidate. This may mean that the currently selected pitch
Chris@199 163 * candidate is not the highest, or it may mean that no alternate
Chris@199 164 * pitch candidate has been selected at all yet (but some are
Chris@199 165 * available).
Chris@199 166 */
Chris@199 167 bool haveHigherPitchCandidate() const;
Chris@199 168
Chris@199 169 /**
Chris@199 170 * Return true if it is possible to switch down to another pitch
Chris@199 171 * candidate. This may mean that the currently selected pitch
Chris@199 172 * candidate is not the lowest, or it may mean that no alternate
Chris@199 173 * pitch candidate has been selected at all yet (but some are
Chris@199 174 * available).
Chris@199 175 */
Chris@199 176 bool haveLowerPitchCandidate() const;
Chris@199 177
Chris@199 178 /**
Chris@184 179 * Delete the pitch estimates from the selected area of the main
Chris@168 180 * pitch track.
Chris@168 181 */
Chris@184 182 void deletePitches(Selection sel);
Chris@168 183
Chris@168 184 /**
Chris@168 185 * Move the main pitch track and any active analysis candidate
Chris@168 186 * tracks up or down an octave in the selected area.
Chris@168 187 */
Chris@168 188 void shiftOctave(Selection sel, bool up);
Chris@168 189
Chris@168 190 /**
Chris@199 191 * Remove any re-analysis layers and also reset the pitch track in
Chris@194 192 * the given selection to its state prior to the last re-analysis,
Chris@199 193 * abandoning any changes made since then. No re-analysis layers
Chris@199 194 * will be available until after the next call to
Chris@199 195 * reAnalyseSelection.
Chris@167 196 */
Chris@199 197 void abandonReAnalysis(Selection sel);
Chris@167 198
Chris@174 199 /**
Chris@269 200 * Remove any re-analysis layers, without any expectation of
Chris@269 201 * adding them later, unlike showPitchCandidates(false), and
Chris@269 202 * without changing the current pitch track, unlike
Chris@269 203 * abandonReAnalysis().
Chris@269 204 */
Chris@269 205 void clearReAnalysis();
Chris@269 206
Chris@269 207 /**
Chris@174 208 * Import the pitch track from the given layer into our
Chris@174 209 * pitch-track layer.
Chris@174 210 */
Chris@174 211 void takePitchTrackFrom(Layer *layer);
Chris@174 212
Chris@174 213 Pane *getPane() {
Chris@174 214 return m_pane;
Chris@174 215 }
Chris@174 216
Chris@174 217 Layer *getLayer(Component type) {
Chris@174 218 return m_layers[type];
Chris@174 219 }
Chris@174 220
Chris@128 221 signals:
Chris@128 222 void layersChanged();
Chris@314 223 void initialAnalysisCompleted();
Chris@128 224
Chris@242 225 protected slots:
Chris@242 226 void layerAboutToBeDeleted(Layer *);
Chris@576 227 void layerCompletionChanged(ModelId);
Chris@403 228 void reAnalyseRegion(sv_frame_t, sv_frame_t, float, float);
Chris@398 229 void materialiseReAnalysis();
Chris@242 230
Chris@6 231 protected:
Chris@6 232 Document *m_document;
Chris@572 233 ModelId m_fileModel;
Chris@133 234 PaneStack *m_paneStack;
Chris@6 235 Pane *m_pane;
Chris@165 236
Chris@128 237 mutable std::map<Component, Layer *> m_layers;
Chris@132 238
Chris@194 239 Clipboard m_preAnalysis;
Chris@165 240 Selection m_reAnalysingSelection;
Chris@396 241 FrequencyRange m_reAnalysingRange;
Chris@165 242 std::vector<Layer *> m_reAnalysisCandidates;
Chris@167 243 int m_currentCandidate;
Chris@184 244 bool m_candidatesVisible;
Chris@341 245 Document::LayerCreationAsyncHandle m_currentAsyncHandle;
Chris@341 246 QMutex m_asyncMutex;
Chris@165 247
Chris@326 248 QString doAllAnalyses(bool withPitchTrack);
Chris@325 249
Chris@161 250 QString addVisualisations();
Chris@161 251 QString addWaveform();
Chris@161 252 QString addAnalyses();
Chris@161 253
Chris@199 254 void discardPitchCandidates();
Chris@260 255
Chris@260 256 void stackLayers();
Chris@199 257
Chris@163 258 // Document::LayerCreationHandler method
Chris@341 259 void layersCreated(Document::LayerCreationAsyncHandle,
Chris@341 260 std::vector<Layer *>, std::vector<Layer *>);
Chris@163 261
Chris@132 262 void saveState(Component c) const;
Chris@132 263 void loadState(Component c);
Chris@6 264 };
Chris@6 265
Chris@6 266 #endif