Mercurial > hg > easaier-soundaccess
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/LayerFactory.cpp Fri May 11 09:08:14 2007 +0000 @@ -0,0 +1,396 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "LayerFactory.h" + +#include "WaveformLayer.h" +#include "SpectrogramLayer.h" +#include "TimeRulerLayer.h" +#include "TimeInstantLayer.h" +#include "TimeValueLayer.h" +#include "NoteLayer.h" +#include "TextLayer.h" +#include "Colour3DPlotLayer.h" +#include "SpectrumLayer.h" +#include "SliceLayer.h" +#include "SliceableLayer.h" + +#include "data/model/RangeSummarisableTimeValueModel.h" +#include "data/model/DenseTimeValueModel.h" +#include "data/model/SparseOneDimensionalModel.h" +#include "data/model/SparseTimeValueModel.h" +#include "data/model/NoteModel.h" +#include "data/model/TextModel.h" +#include "data/model/DenseThreeDimensionalModel.h" +#include "data/model/WaveFileModel.h" +#include "data/model/WritableWaveFileModel.h" + +LayerFactory * +LayerFactory::m_instance = new LayerFactory; + +LayerFactory * +LayerFactory::getInstance() +{ + return m_instance; +} + +LayerFactory::~LayerFactory() +{ +} + +QString +LayerFactory::getLayerPresentationName(LayerType type) +{ + switch (type) { + case Waveform: return Layer::tr("Waveform"); + case Spectrogram: return Layer::tr("Spectrogram"); + case TimeRuler: return Layer::tr("Ruler"); + case TimeInstants: return Layer::tr("Time Instants"); + case TimeValues: return Layer::tr("Time Values"); + case Notes: return Layer::tr("Notes"); + case Text: return Layer::tr("Text"); + case Colour3DPlot: return Layer::tr("Colour 3D Plot"); + case Spectrum: return Layer::tr("Spectrum"); + case Slice: return Layer::tr("Time Slice"); + + case MelodicRangeSpectrogram: + // The user can change all the parameters of this after the + // fact -- there's nothing permanently melodic-range about it + // that should be encoded in its name + return Layer::tr("Spectrogram"); + + case PeakFrequencySpectrogram: + // likewise + return Layer::tr("Spectrogram"); + + default: break; + } + + return Layer::tr("Layer"); +} + +bool +LayerFactory::isLayerSliceable(const Layer *layer) +{ + if (dynamic_cast<const SliceableLayer *>(layer)) { + if (dynamic_cast<const SpectrogramLayer *>(layer)) { + + //!!! We can create slices of spectrograms, but there's a + // problem managing the models. The source model for the + // slice layer has to be one of the spectrogram's FFT + // models -- that's fine, except that we can't store & + // recall the slice layer with a reference to that model + // because the model is internal to the spectrogram layer + // and the document has no record of it. We would need + // some other way of managing models that are used in this + // way. For the moment we just don't allow slices of + // spectrograms -- and provide a spectrum layer for this + // instead. + // + // This business needs a bit more thought -- either come + // up with a sensible way to deal with that stuff, or + // simplify the existing slice layer logic so that it + // doesn't have to deal with models disappearing on it at + // all (and use the normal Document setModel mechanism to + // set its sliceable model instead of the fancy pants + // nonsense it's doing at the moment). + + return false; + } + return true; + } + return false; +} + +LayerFactory::LayerTypeSet +LayerFactory::getValidLayerTypes(Model *model) +{ + LayerTypeSet types; + + if (dynamic_cast<DenseThreeDimensionalModel *>(model)) { + types.insert(Colour3DPlot); + types.insert(Slice); + } + + if (dynamic_cast<RangeSummarisableTimeValueModel *>(model)) { + types.insert(Waveform); + } + + if (dynamic_cast<DenseTimeValueModel *>(model)) { + types.insert(Spectrogram); + types.insert(MelodicRangeSpectrogram); + types.insert(PeakFrequencySpectrogram); + } + + if (dynamic_cast<SparseOneDimensionalModel *>(model)) { + types.insert(TimeInstants); + } + + if (dynamic_cast<SparseTimeValueModel *>(model)) { + types.insert(TimeValues); + +} + if (dynamic_cast<NoteModel *>(model)) { + types.insert(Notes); + } + + if (dynamic_cast<TextModel *>(model)) { + types.insert(Text); + } + + if (dynamic_cast<DenseTimeValueModel *>(model)) { + types.insert(Spectrum); + } + + // We don't count TimeRuler here as it doesn't actually display + // the data, although it can be backed by any model + + return types; +} + +LayerFactory::LayerTypeSet +LayerFactory::getValidEmptyLayerTypes() +{ + LayerTypeSet types; + types.insert(TimeInstants); + types.insert(TimeValues); + types.insert(Notes); + types.insert(Text); + //!!! and in principle Colour3DPlot -- now that's a challenge + return types; +} + +LayerFactory::LayerType +LayerFactory::getLayerType(const Layer *layer) +{ + if (dynamic_cast<const WaveformLayer *>(layer)) return Waveform; + if (dynamic_cast<const SpectrogramLayer *>(layer)) return Spectrogram; + if (dynamic_cast<const TimeRulerLayer *>(layer)) return TimeRuler; + if (dynamic_cast<const TimeInstantLayer *>(layer)) return TimeInstants; + if (dynamic_cast<const TimeValueLayer *>(layer)) return TimeValues; + if (dynamic_cast<const NoteLayer *>(layer)) return Notes; + if (dynamic_cast<const TextLayer *>(layer)) return Text; + if (dynamic_cast<const Colour3DPlotLayer *>(layer)) return Colour3DPlot; + if (dynamic_cast<const SpectrumLayer *>(layer)) return Spectrum; + if (dynamic_cast<const SliceLayer *>(layer)) return Slice; + return UnknownLayer; +} + +QString +LayerFactory::getLayerIconName(LayerType type) +{ + switch (type) { + case Waveform: return "waveform"; + case Spectrogram: return "spectrogram"; + case TimeRuler: return "timeruler"; + case TimeInstants: return "instants"; + case TimeValues: return "values"; + case Notes: return "notes"; + case Text: return "text"; + case Colour3DPlot: return "colour3d"; + case Spectrum: return "spectrum"; + case Slice: return "spectrum"; + default: return "unknown"; + } +} + +QString +LayerFactory::getLayerTypeName(LayerType type) +{ + switch (type) { + case Waveform: return "waveform"; + case Spectrogram: return "spectrogram"; + case TimeRuler: return "timeruler"; + case TimeInstants: return "timeinstants"; + case TimeValues: return "timevalues"; + case Notes: return "notes"; + case Text: return "text"; + case Colour3DPlot: return "colour3dplot"; + case Spectrum: return "spectrum"; + case Slice: return "slice"; + default: return "unknown"; + } +} + +LayerFactory::LayerType +LayerFactory::getLayerTypeForName(QString name) +{ + if (name == "waveform") return Waveform; + if (name == "spectrogram") return Spectrogram; + if (name == "timeruler") return TimeRuler; + if (name == "timeinstants") return TimeInstants; + if (name == "timevalues") return TimeValues; + if (name == "notes") return Notes; + if (name == "text") return Text; + if (name == "colour3dplot") return Colour3DPlot; + if (name == "spectrum") return Spectrum; + if (name == "slice") return Slice; + return UnknownLayer; +} + +void +LayerFactory::setModel(Layer *layer, Model *model) +{ +// if (trySetModel<WaveformLayer, RangeSummarisableTimeValueModel>(layer, model)) +// return; + + if (trySetModel<WaveformLayer, WaveFileModel>(layer, model)) + return; + + if (trySetModel<WaveformLayer, WritableWaveFileModel>(layer, model)) + return; + + if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model)) + return; + + if (trySetModel<TimeRulerLayer, Model>(layer, model)) + return; + + if (trySetModel<TimeInstantLayer, SparseOneDimensionalModel>(layer, model)) + return; + + if (trySetModel<TimeValueLayer, SparseTimeValueModel>(layer, model)) + return; + + if (trySetModel<NoteLayer, NoteModel>(layer, model)) + return; + + if (trySetModel<TextLayer, TextModel>(layer, model)) + return; + + if (trySetModel<Colour3DPlotLayer, DenseThreeDimensionalModel>(layer, model)) + return; + + if (trySetModel<SpectrogramLayer, DenseTimeValueModel>(layer, model)) + return; + + if (trySetModel<SpectrumLayer, DenseTimeValueModel>(layer, model)) + return; + +// if (trySetModel<SliceLayer, DenseThreeDimensionalModel>(layer, model)) +// return; +} + +Model * +LayerFactory::createEmptyModel(LayerType layerType, Model *baseModel) +{ + if (layerType == TimeInstants) { + return new SparseOneDimensionalModel(baseModel->getSampleRate(), 1); + } else if (layerType == TimeValues) { + return new SparseTimeValueModel(baseModel->getSampleRate(), 1, true); + } else if (layerType == Notes) { + return new NoteModel(baseModel->getSampleRate(), 1, true); + } else if (layerType == Text) { + return new TextModel(baseModel->getSampleRate(), 1, true); + } else { + return 0; + } +} + +int +LayerFactory::getChannel(Layer *layer) +{ + if (dynamic_cast<WaveformLayer *>(layer)) { + return dynamic_cast<WaveformLayer *>(layer)->getChannel(); + } + if (dynamic_cast<SpectrogramLayer *>(layer)) { + return dynamic_cast<SpectrogramLayer *>(layer)->getChannel(); + } + return -1; +} + +void +LayerFactory::setChannel(Layer *layer, int channel) +{ + if (dynamic_cast<WaveformLayer *>(layer)) { + dynamic_cast<WaveformLayer *>(layer)->setChannel(channel); + return; + } + if (dynamic_cast<SpectrogramLayer *>(layer)) { + dynamic_cast<SpectrogramLayer *>(layer)->setChannel(channel); + return; + } +} + +Layer * +LayerFactory::createLayer(LayerType type) +{ + Layer *layer = 0; + + switch (type) { + + case Waveform: + layer = new WaveformLayer; + break; + + case Spectrogram: + layer = new SpectrogramLayer; + break; + + case TimeRuler: + layer = new TimeRulerLayer; + break; + + case TimeInstants: + layer = new TimeInstantLayer; + break; + + case TimeValues: + layer = new TimeValueLayer; + break; + + case Notes: + layer = new NoteLayer; + break; + + case Text: + layer = new TextLayer; + break; + + case Colour3DPlot: + layer = new Colour3DPlotLayer; + break; + + case Spectrum: + layer = new SpectrumLayer; + break; + + case Slice: + layer = new SliceLayer; + break; + + case MelodicRangeSpectrogram: + layer = new SpectrogramLayer(SpectrogramLayer::MelodicRange); + break; + + case PeakFrequencySpectrogram: + layer = new SpectrogramLayer(SpectrogramLayer::MelodicPeaks); + break; + + default: break; + } + + if (!layer) { + std::cerr << "LayerFactory::createLayer: Unknown layer type " + << type << std::endl; + } else { +// std::cerr << "LayerFactory::createLayer: Setting object name " +// << getLayerPresentationName(type).toStdString() << " on " << layer << std::endl; + layer->setObjectName(getLayerPresentationName(type)); + } + + return layer; +} +