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