annotate layer/LayerFactory.cpp @ 312:6de6f78b13a1

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