Mercurial > hg > easaier-soundaccess
comparison layer/LayerFactory.cpp @ 0:fc9323a41f5a
start base : Sonic Visualiser sv1-1.0rc1
author | lbajardsilogic |
---|---|
date | Fri, 11 May 2007 09:08:14 +0000 |
parents | |
children | d8e6709e9075 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fc9323a41f5a |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2006 Chris Cannam. | |
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 #include "LayerFactory.h" | |
17 | |
18 #include "WaveformLayer.h" | |
19 #include "SpectrogramLayer.h" | |
20 #include "TimeRulerLayer.h" | |
21 #include "TimeInstantLayer.h" | |
22 #include "TimeValueLayer.h" | |
23 #include "NoteLayer.h" | |
24 #include "TextLayer.h" | |
25 #include "Colour3DPlotLayer.h" | |
26 #include "SpectrumLayer.h" | |
27 #include "SliceLayer.h" | |
28 #include "SliceableLayer.h" | |
29 | |
30 #include "data/model/RangeSummarisableTimeValueModel.h" | |
31 #include "data/model/DenseTimeValueModel.h" | |
32 #include "data/model/SparseOneDimensionalModel.h" | |
33 #include "data/model/SparseTimeValueModel.h" | |
34 #include "data/model/NoteModel.h" | |
35 #include "data/model/TextModel.h" | |
36 #include "data/model/DenseThreeDimensionalModel.h" | |
37 #include "data/model/WaveFileModel.h" | |
38 #include "data/model/WritableWaveFileModel.h" | |
39 | |
40 LayerFactory * | |
41 LayerFactory::m_instance = new LayerFactory; | |
42 | |
43 LayerFactory * | |
44 LayerFactory::getInstance() | |
45 { | |
46 return m_instance; | |
47 } | |
48 | |
49 LayerFactory::~LayerFactory() | |
50 { | |
51 } | |
52 | |
53 QString | |
54 LayerFactory::getLayerPresentationName(LayerType type) | |
55 { | |
56 switch (type) { | |
57 case Waveform: return Layer::tr("Waveform"); | |
58 case Spectrogram: return Layer::tr("Spectrogram"); | |
59 case TimeRuler: return Layer::tr("Ruler"); | |
60 case TimeInstants: return Layer::tr("Time Instants"); | |
61 case TimeValues: return Layer::tr("Time Values"); | |
62 case Notes: return Layer::tr("Notes"); | |
63 case Text: return Layer::tr("Text"); | |
64 case Colour3DPlot: return Layer::tr("Colour 3D Plot"); | |
65 case Spectrum: return Layer::tr("Spectrum"); | |
66 case Slice: return Layer::tr("Time Slice"); | |
67 | |
68 case MelodicRangeSpectrogram: | |
69 // The user can change all the parameters of this after the | |
70 // fact -- there's nothing permanently melodic-range about it | |
71 // that should be encoded in its name | |
72 return Layer::tr("Spectrogram"); | |
73 | |
74 case PeakFrequencySpectrogram: | |
75 // likewise | |
76 return Layer::tr("Spectrogram"); | |
77 | |
78 default: break; | |
79 } | |
80 | |
81 return Layer::tr("Layer"); | |
82 } | |
83 | |
84 bool | |
85 LayerFactory::isLayerSliceable(const Layer *layer) | |
86 { | |
87 if (dynamic_cast<const SliceableLayer *>(layer)) { | |
88 if (dynamic_cast<const SpectrogramLayer *>(layer)) { | |
89 | |
90 //!!! We can create slices of spectrograms, but there's a | |
91 // problem managing the models. The source model for the | |
92 // slice layer has to be one of the spectrogram's FFT | |
93 // models -- that's fine, except that we can't store & | |
94 // recall the slice layer with a reference to that model | |
95 // because the model is internal to the spectrogram layer | |
96 // and the document has no record of it. We would need | |
97 // some other way of managing models that are used in this | |
98 // way. For the moment we just don't allow slices of | |
99 // spectrograms -- and provide a spectrum layer for this | |
100 // instead. | |
101 // | |
102 // This business needs a bit more thought -- either come | |
103 // up with a sensible way to deal with that stuff, or | |
104 // simplify the existing slice layer logic so that it | |
105 // doesn't have to deal with models disappearing on it at | |
106 // all (and use the normal Document setModel mechanism to | |
107 // set its sliceable model instead of the fancy pants | |
108 // nonsense it's doing at the moment). | |
109 | |
110 return false; | |
111 } | |
112 return true; | |
113 } | |
114 return false; | |
115 } | |
116 | |
117 LayerFactory::LayerTypeSet | |
118 LayerFactory::getValidLayerTypes(Model *model) | |
119 { | |
120 LayerTypeSet types; | |
121 | |
122 if (dynamic_cast<DenseThreeDimensionalModel *>(model)) { | |
123 types.insert(Colour3DPlot); | |
124 types.insert(Slice); | |
125 } | |
126 | |
127 if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) { | |
128 types.insert(Waveform); | |
129 } | |
130 | |
131 if (dynamic_cast<DenseTimeValueModel *>(model)) { | |
132 types.insert(Spectrogram); | |
133 types.insert(MelodicRangeSpectrogram); | |
134 types.insert(PeakFrequencySpectrogram); | |
135 } | |
136 | |
137 if (dynamic_cast<SparseOneDimensionalModel *>(model)) { | |
138 types.insert(TimeInstants); | |
139 } | |
140 | |
141 if (dynamic_cast<SparseTimeValueModel *>(model)) { | |
142 types.insert(TimeValues); | |
143 | |
144 } | |
145 if (dynamic_cast<NoteModel *>(model)) { | |
146 types.insert(Notes); | |
147 } | |
148 | |
149 if (dynamic_cast<TextModel *>(model)) { | |
150 types.insert(Text); | |
151 } | |
152 | |
153 if (dynamic_cast<DenseTimeValueModel *>(model)) { | |
154 types.insert(Spectrum); | |
155 } | |
156 | |
157 // We don't count TimeRuler here as it doesn't actually display | |
158 // the data, although it can be backed by any model | |
159 | |
160 return types; | |
161 } | |
162 | |
163 LayerFactory::LayerTypeSet | |
164 LayerFactory::getValidEmptyLayerTypes() | |
165 { | |
166 LayerTypeSet types; | |
167 types.insert(TimeInstants); | |
168 types.insert(TimeValues); | |
169 types.insert(Notes); | |
170 types.insert(Text); | |
171 //!!! and in principle Colour3DPlot -- now that's a challenge | |
172 return types; | |
173 } | |
174 | |
175 LayerFactory::LayerType | |
176 LayerFactory::getLayerType(const Layer *layer) | |
177 { | |
178 if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform; | |
179 if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram; | |
180 if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler; | |
181 if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants; | |
182 if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues; | |
183 if (dynamic_cast<const NoteLayer *>(layer)) return Notes; | |
184 if (dynamic_cast<const TextLayer *>(layer)) return Text; | |
185 if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot; | |
186 if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum; | |
187 if (dynamic_cast<const SliceLayer *>(layer)) return Slice; | |
188 return UnknownLayer; | |
189 } | |
190 | |
191 QString | |
192 LayerFactory::getLayerIconName(LayerType type) | |
193 { | |
194 switch (type) { | |
195 case Waveform: return "waveform"; | |
196 case Spectrogram: return "spectrogram"; | |
197 case TimeRuler: return "timeruler"; | |
198 case TimeInstants: return "instants"; | |
199 case TimeValues: return "values"; | |
200 case Notes: return "notes"; | |
201 case Text: return "text"; | |
202 case Colour3DPlot: return "colour3d"; | |
203 case Spectrum: return "spectrum"; | |
204 case Slice: return "spectrum"; | |
205 default: return "unknown"; | |
206 } | |
207 } | |
208 | |
209 QString | |
210 LayerFactory::getLayerTypeName(LayerType type) | |
211 { | |
212 switch (type) { | |
213 case Waveform: return "waveform"; | |
214 case Spectrogram: return "spectrogram"; | |
215 case TimeRuler: return "timeruler"; | |
216 case TimeInstants: return "timeinstants"; | |
217 case TimeValues: return "timevalues"; | |
218 case Notes: return "notes"; | |
219 case Text: return "text"; | |
220 case Colour3DPlot: return "colour3dplot"; | |
221 case Spectrum: return "spectrum"; | |
222 case Slice: return "slice"; | |
223 default: return "unknown"; | |
224 } | |
225 } | |
226 | |
227 LayerFactory::LayerType | |
228 LayerFactory::getLayerTypeForName(QString name) | |
229 { | |
230 if (name == "waveform") return Waveform; | |
231 if (name == "spectrogram") return Spectrogram; | |
232 if (name == "timeruler") return TimeRuler; | |
233 if (name == "timeinstants") return TimeInstants; | |
234 if (name == "timevalues") return TimeValues; | |
235 if (name == "notes") return Notes; | |
236 if (name == "text") return Text; | |
237 if (name == "colour3dplot") return Colour3DPlot; | |
238 if (name == "spectrum") return Spectrum; | |
239 if (name == "slice") return Slice; | |
240 return UnknownLayer; | |
241 } | |
242 | |
243 void | |
244 LayerFactory::setModel(Layer *layer, Model *model) | |
245 { | |
246 // if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model)) | |
247 // return; | |
248 | |
249 if (trySetModel<WaveformLayer, WaveFileModel>(layer, model)) | |
250 return; | |
251 | |
252 if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model)) | |
253 return; | |
254 | |
255 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model)) | |
256 return; | |
257 | |
258 if (trySetModel<TimeRulerLayer, Model>(layer, model)) | |
259 return; | |
260 | |
261 if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model)) | |
262 return; | |
263 | |
264 if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model)) | |
265 return; | |
266 | |
267 if (trySetModel<NoteLayer, NoteModel>(layer, model)) | |
268 return; | |
269 | |
270 if (trySetModel<TextLayer, TextModel>(layer, model)) | |
271 return; | |
272 | |
273 if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model)) | |
274 return; | |
275 | |
276 if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model)) | |
277 return; | |
278 | |
279 if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model)) | |
280 return; | |
281 | |
282 // if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model)) | |
283 // return; | |
284 } | |
285 | |
286 Model * | |
287 LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel) | |
288 { | |
289 if (layerType == TimeInstants) { | |
290 return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1); | |
291 } else if (layerType == TimeValues) { | |
292 return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true); | |
293 } else if (layerType == Notes) { | |
294 return new NoteModel(baseModel->getSampleRate(), 1, true); | |
295 } else if (layerType == Text) { | |
296 return new TextModel(baseModel->getSampleRate(), 1, true); | |
297 } else { | |
298 return 0; | |
299 } | |
300 } | |
301 | |
302 int | |
303 LayerFactory::getChannel(Layer *layer) | |
304 { | |
305 if (dynamic_cast<WaveformLayer *>(layer)) { | |
306 return dynamic_cast<WaveformLayer *>(layer)->getChannel(); | |
307 } | |
308 if (dynamic_cast<SpectrogramLayer *>(layer)) { | |
309 return dynamic_cast<SpectrogramLayer *>(layer)->getChannel(); | |
310 } | |
311 return -1; | |
312 } | |
313 | |
314 void | |
315 LayerFactory::setChannel(Layer *layer, int channel) | |
316 { | |
317 if (dynamic_cast<WaveformLayer *>(layer)) { | |
318 dynamic_cast<WaveformLayer *>(layer)->setChannel(channel); | |
319 return; | |
320 } | |
321 if (dynamic_cast<SpectrogramLayer *>(layer)) { | |
322 dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel); | |
323 return; | |
324 } | |
325 } | |
326 | |
327 Layer * | |
328 LayerFactory::createLayer(LayerType type) | |
329 { | |
330 Layer *layer = 0; | |
331 | |
332 switch (type) { | |
333 | |
334 case Waveform: | |
335 layer = new WaveformLayer; | |
336 break; | |
337 | |
338 case Spectrogram: | |
339 layer = new SpectrogramLayer; | |
340 break; | |
341 | |
342 case TimeRuler: | |
343 layer = new TimeRulerLayer; | |
344 break; | |
345 | |
346 case TimeInstants: | |
347 layer = new TimeInstantLayer; | |
348 break; | |
349 | |
350 case TimeValues: | |
351 layer = new TimeValueLayer; | |
352 break; | |
353 | |
354 case Notes: | |
355 layer = new NoteLayer; | |
356 break; | |
357 | |
358 case Text: | |
359 layer = new TextLayer; | |
360 break; | |
361 | |
362 case Colour3DPlot: | |
363 layer = new Colour3DPlotLayer; | |
364 break; | |
365 | |
366 case Spectrum: | |
367 layer = new SpectrumLayer; | |
368 break; | |
369 | |
370 case Slice: | |
371 layer = new SliceLayer; | |
372 break; | |
373 | |
374 case MelodicRangeSpectrogram: | |
375 layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange); | |
376 break; | |
377 | |
378 case PeakFrequencySpectrogram: | |
379 layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks); | |
380 break; | |
381 | |
382 default: break; | |
383 } | |
384 | |
385 if (!layer) { | |
386 std::cerr << "LayerFactory::createLayer: Unknown layer type " | |
387 << type << std::endl; | |
388 } else { | |
389 // std::cerr << "LayerFactory::createLayer: Setting object name " | |
390 // << getLayerPresentationName(type).toStdString() << " on " << layer << std::endl; | |
391 layer->setObjectName(getLayerPresentationName(type)); | |
392 } | |
393 | |
394 return layer; | |
395 } | |
396 |