annotate data/model/ImageModel.h @ 363:0e30c8ec15a0

* Add wave file model method for reading more than one channel at once, avoiding ludicrously expensive backward seeks and double-reads when playing multi-channel files or using them as inputs to feature extraction plugins
author Chris Cannam
date Thu, 24 Jan 2008 14:35:43 +0000
parents 700cd3350391
children 6a96bff0bd59
rev   line source
Chris@302 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@302 2
Chris@302 3 /*
Chris@302 4 Sonic Visualiser
Chris@302 5 An audio file viewer and annotation editor.
Chris@302 6 Centre for Digital Music, Queen Mary, University of London.
Chris@302 7 This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@302 8
Chris@302 9 This program is free software; you can redistribute it and/or
Chris@302 10 modify it under the terms of the GNU General Public License as
Chris@302 11 published by the Free Software Foundation; either version 2 of the
Chris@302 12 License, or (at your option) any later version. See the file
Chris@302 13 COPYING included with this distribution for more information.
Chris@302 14 */
Chris@302 15
Chris@302 16 #ifndef _IMAGE_MODEL_H_
Chris@302 17 #define _IMAGE_MODEL_H_
Chris@302 18
Chris@302 19 #include "SparseModel.h"
Chris@302 20 #include "base/XmlExportable.h"
Chris@302 21 #include "base/RealTime.h"
Chris@302 22
Chris@302 23 /**
Chris@302 24 * Image point type for use in a SparseModel. This represents an
Chris@302 25 * image, identified by filename, at a given time. The filename can
Chris@302 26 * be empty, in which case we instead have a space to put an image in.
Chris@302 27 */
Chris@302 28
Chris@302 29 struct ImagePoint : public XmlExportable
Chris@302 30 {
Chris@302 31 public:
Chris@302 32 ImagePoint(long _frame) : frame(_frame) { }
Chris@302 33 ImagePoint(long _frame, QString _image, QString _label) :
Chris@302 34 frame(_frame), image(_image), label(_label) { }
Chris@302 35
Chris@302 36 int getDimensions() const { return 1; }
Chris@302 37
Chris@302 38 long frame;
Chris@302 39 QString image;
Chris@302 40 QString label;
Chris@338 41
Chris@338 42 QString getLabel() const { return label; }
Chris@302 43
Chris@314 44 void toXml(QTextStream &stream,
Chris@314 45 QString indent = "",
Chris@314 46 QString extraAttributes = "") const
Chris@302 47 {
Chris@314 48 stream <<
Chris@314 49 QString("%1<point frame=\"%2\" image=\"%3\" label=\"%4\" %5/>\n")
Chris@302 50 .arg(indent).arg(frame)
Chris@302 51 .arg(encodeEntities(image))
Chris@302 52 .arg(encodeEntities(label))
Chris@302 53 .arg(extraAttributes);
Chris@302 54 }
Chris@302 55
Chris@302 56 QString toDelimitedDataString(QString delimiter, size_t sampleRate) const
Chris@302 57 {
Chris@302 58 QStringList list;
Chris@302 59 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@302 60 list << image;
Chris@318 61 if (label != "") list << label;
Chris@302 62 return list.join(delimiter);
Chris@302 63 }
Chris@302 64
Chris@302 65 struct Comparator {
Chris@302 66 bool operator()(const ImagePoint &p1,
Chris@302 67 const ImagePoint &p2) const {
Chris@302 68 if (p1.frame != p2.frame) return p1.frame < p2.frame;
Chris@302 69 if (p1.label != p2.label) return p1.label < p2.label;
Chris@302 70 return p1.image < p2.image;
Chris@302 71 }
Chris@302 72 };
Chris@302 73
Chris@302 74 struct OrderComparator {
Chris@302 75 bool operator()(const ImagePoint &p1,
Chris@302 76 const ImagePoint &p2) const {
Chris@302 77 return p1.frame < p2.frame;
Chris@302 78 }
Chris@302 79 };
Chris@302 80 };
Chris@302 81
Chris@302 82
Chris@302 83 // Make this a class rather than a typedef so it can be predeclared.
Chris@302 84
Chris@302 85 class ImageModel : public SparseModel<ImagePoint>
Chris@302 86 {
Chris@302 87 public:
Chris@302 88 ImageModel(size_t sampleRate, size_t resolution, bool notifyOnAdd = true) :
Chris@302 89 SparseModel<ImagePoint>(sampleRate, resolution, notifyOnAdd)
Chris@302 90 { }
Chris@302 91
Chris@345 92 QString getTypeName() const { return tr("Image"); }
Chris@345 93
Chris@302 94 virtual void toXml(QTextStream &out,
Chris@302 95 QString indent = "",
Chris@302 96 QString extraAttributes = "") const
Chris@302 97 {
Chris@302 98 SparseModel<ImagePoint>::toXml
Chris@302 99 (out,
Chris@302 100 indent,
Chris@302 101 QString("%1 subtype=\"image\"")
Chris@302 102 .arg(extraAttributes));
Chris@302 103 }
Chris@302 104
Chris@302 105 /**
Chris@302 106 * Command to change the image for a point.
Chris@302 107 */
Chris@302 108 class ChangeImageCommand : public Command
Chris@302 109 {
Chris@302 110 public:
Chris@302 111 ChangeImageCommand(ImageModel *model,
Chris@302 112 const ImagePoint &point,
Chris@302 113 QString newImage,
Chris@302 114 QString newLabel) :
Chris@302 115 m_model(model), m_oldPoint(point), m_newPoint(point) {
Chris@302 116 m_newPoint.image = newImage;
Chris@302 117 m_newPoint.label = newLabel;
Chris@302 118 }
Chris@302 119
Chris@302 120 virtual QString getName() const { return tr("Edit Image"); }
Chris@302 121
Chris@302 122 virtual void execute() {
Chris@302 123 m_model->deletePoint(m_oldPoint);
Chris@302 124 m_model->addPoint(m_newPoint);
Chris@302 125 std::swap(m_oldPoint, m_newPoint);
Chris@302 126 }
Chris@302 127
Chris@302 128 virtual void unexecute() { execute(); }
Chris@302 129
Chris@302 130 private:
Chris@302 131 ImageModel *m_model;
Chris@302 132 ImagePoint m_oldPoint;
Chris@302 133 ImagePoint m_newPoint;
Chris@302 134 };
Chris@302 135 };
Chris@302 136
Chris@302 137
Chris@302 138 #endif
Chris@302 139
Chris@302 140
Chris@302 141