annotate data/model/RegionModel.h @ 458:f60360209e5c

* Fix race condition in FFTFileCache when reading from the same FFT model from multiple threads (e.g. when applying more than one plugin at once)
author Chris Cannam
date Wed, 15 Oct 2008 12:08:02 +0000
parents 325112751f0e
children 6441b31b37ac
rev   line source
Chris@441 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@441 2
Chris@441 3 /*
Chris@441 4 Sonic Visualiser
Chris@441 5 An audio file viewer and annotation editor.
Chris@441 6 Centre for Digital Music, Queen Mary, University of London.
Chris@441 7 This file copyright 2006 Chris Cannam.
Chris@441 8
Chris@441 9 This program is free software; you can redistribute it and/or
Chris@441 10 modify it under the terms of the GNU General Public License as
Chris@441 11 published by the Free Software Foundation; either version 2 of the
Chris@441 12 License, or (at your option) any later version. See the file
Chris@441 13 COPYING included with this distribution for more information.
Chris@441 14 */
Chris@441 15
Chris@441 16 #ifndef _REGION_MODEL_H_
Chris@441 17 #define _REGION_MODEL_H_
Chris@441 18
Chris@441 19 #include "IntervalModel.h"
Chris@441 20 #include "base/RealTime.h"
Chris@441 21
Chris@441 22 /**
Chris@441 23 * RegionModel -- a concrete IntervalModel for intervals associated
Chris@441 24 * with a value, which we call regions for no very compelling reason.
Chris@441 25 */
Chris@441 26
Chris@441 27 /**
Chris@441 28 * Region "point" type. A region is something that has an onset time,
Chris@441 29 * a single value, and a duration. Like other points, it can also
Chris@441 30 * have a label.
Chris@441 31 *
Chris@441 32 * This is called RegionRec instead of Region to avoid name collisions
Chris@441 33 * with the X11 Region struct. Bah.
Chris@441 34 */
Chris@441 35
Chris@441 36 struct RegionRec
Chris@441 37 {
Chris@441 38 public:
Chris@441 39 RegionRec(long _frame) : frame(_frame), value(0.0f), duration(0) { }
Chris@441 40 RegionRec(long _frame, float _value, size_t _duration, QString _label) :
Chris@441 41 frame(_frame), value(_value), duration(_duration), label(_label) { }
Chris@441 42
Chris@441 43 int getDimensions() const { return 3; }
Chris@441 44
Chris@441 45 long frame;
Chris@441 46 float value;
Chris@441 47 size_t duration;
Chris@441 48 QString label;
Chris@441 49
Chris@441 50 QString getLabel() const { return label; }
Chris@441 51
Chris@441 52 void toXml(QTextStream &stream,
Chris@441 53 QString indent = "",
Chris@441 54 QString extraAttributes = "") const
Chris@441 55 {
Chris@441 56 stream <<
Chris@441 57 QString("%1<point frame=\"%2\" value=\"%3\" duration=\"%4\" label=\"%5\" %6/>\n")
Chris@441 58 .arg(indent).arg(frame).arg(value).arg(duration).arg(label).arg(extraAttributes);
Chris@441 59 }
Chris@441 60
Chris@441 61 QString toDelimitedDataString(QString delimiter, size_t sampleRate) const
Chris@441 62 {
Chris@441 63 QStringList list;
Chris@441 64 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@441 65 list << QString("%1").arg(value);
Chris@441 66 list << RealTime::frame2RealTime(duration, sampleRate).toString().c_str();
Chris@441 67 if (label != "") list << label;
Chris@441 68 return list.join(delimiter);
Chris@441 69 }
Chris@441 70
Chris@441 71 struct Comparator {
Chris@441 72 bool operator()(const RegionRec &p1,
Chris@441 73 const RegionRec &p2) const {
Chris@441 74 if (p1.frame != p2.frame) return p1.frame < p2.frame;
Chris@441 75 if (p1.value != p2.value) return p1.value < p2.value;
Chris@441 76 if (p1.duration != p2.duration) return p1.duration < p2.duration;
Chris@441 77 return p1.label < p2.label;
Chris@441 78 }
Chris@441 79 };
Chris@441 80
Chris@441 81 struct OrderComparator {
Chris@441 82 bool operator()(const RegionRec &p1,
Chris@441 83 const RegionRec &p2) const {
Chris@441 84 return p1.frame < p2.frame;
Chris@441 85 }
Chris@441 86 };
Chris@441 87 };
Chris@441 88
Chris@441 89
Chris@441 90 class RegionModel : public IntervalModel<RegionRec>
Chris@441 91 {
Chris@441 92 Q_OBJECT
Chris@441 93
Chris@441 94 public:
Chris@441 95 RegionModel(size_t sampleRate, size_t resolution,
Chris@441 96 bool notifyOnAdd = true) :
Chris@441 97 IntervalModel<RegionRec>(sampleRate, resolution, notifyOnAdd),
Chris@442 98 m_valueQuantization(0),
Chris@442 99 m_haveDistinctValues(false)
Chris@441 100 {
Chris@441 101 }
Chris@441 102
Chris@441 103 RegionModel(size_t sampleRate, size_t resolution,
Chris@441 104 float valueMinimum, float valueMaximum,
Chris@441 105 bool notifyOnAdd = true) :
Chris@441 106 IntervalModel<RegionRec>(sampleRate, resolution,
Chris@441 107 valueMinimum, valueMaximum,
Chris@441 108 notifyOnAdd),
Chris@442 109 m_valueQuantization(0),
Chris@442 110 m_haveDistinctValues(false)
Chris@441 111 {
Chris@441 112 }
Chris@441 113
Chris@441 114 virtual ~RegionModel()
Chris@441 115 {
Chris@441 116 }
Chris@441 117
Chris@441 118 float getValueQuantization() const { return m_valueQuantization; }
Chris@441 119 void setValueQuantization(float q) { m_valueQuantization = q; }
Chris@441 120
Chris@442 121 bool haveDistinctValues() const { return m_haveDistinctValues; }
Chris@442 122
Chris@441 123 QString getTypeName() const { return tr("Region"); }
Chris@441 124
Chris@441 125 virtual void toXml(QTextStream &out,
Chris@441 126 QString indent = "",
Chris@441 127 QString extraAttributes = "") const
Chris@441 128 {
Chris@441 129 std::cerr << "RegionModel::toXml: extraAttributes = \""
Chris@441 130 << extraAttributes.toStdString() << std::endl;
Chris@441 131
Chris@441 132 IntervalModel<RegionRec>::toXml
Chris@441 133 (out,
Chris@441 134 indent,
Chris@452 135 QString("%1 subtype=\"region\" valueQuantization=\"%2\"")
Chris@441 136 .arg(extraAttributes).arg(m_valueQuantization));
Chris@441 137 }
Chris@441 138
Chris@441 139 /**
Chris@441 140 * TabularModel methods.
Chris@441 141 */
Chris@441 142
Chris@441 143 virtual int getColumnCount() const
Chris@441 144 {
Chris@441 145 return 6;
Chris@441 146 }
Chris@441 147
Chris@441 148 virtual QString getHeading(int column) const
Chris@441 149 {
Chris@441 150 switch (column) {
Chris@441 151 case 0: return tr("Time");
Chris@441 152 case 1: return tr("Frame");
Chris@441 153 case 2: return tr("Value");
Chris@441 154 case 3: return tr("Duration");
Chris@441 155 case 4: return tr("Label");
Chris@441 156 default: return tr("Unknown");
Chris@441 157 }
Chris@441 158 }
Chris@441 159
Chris@441 160 virtual QVariant getData(int row, int column, int role) const
Chris@441 161 {
Chris@441 162 if (column < 4) {
Chris@441 163 return IntervalModel<RegionRec>::getData(row, column, role);
Chris@441 164 }
Chris@441 165
Chris@441 166 PointListIterator i = getPointListIteratorForRow(row);
Chris@441 167 if (i == m_points.end()) return QVariant();
Chris@441 168
Chris@441 169 switch (column) {
Chris@441 170 case 4: return i->label;
Chris@441 171 default: return QVariant();
Chris@441 172 }
Chris@441 173 }
Chris@441 174
Chris@441 175 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
Chris@441 176 {
Chris@441 177 if (column < 4) {
Chris@441 178 return IntervalModel<RegionRec>::getSetDataCommand
Chris@441 179 (row, column, value, role);
Chris@441 180 }
Chris@441 181
Chris@441 182 if (role != Qt::EditRole) return false;
Chris@441 183 PointListIterator i = getPointListIteratorForRow(row);
Chris@441 184 if (i == m_points.end()) return false;
Chris@441 185 EditCommand *command = new EditCommand(this, tr("Edit Data"));
Chris@441 186
Chris@441 187 Point point(*i);
Chris@441 188 command->deletePoint(point);
Chris@441 189
Chris@441 190 switch (column) {
Chris@441 191 case 4: point.label = value.toString(); break;
Chris@441 192 }
Chris@441 193
Chris@441 194 command->addPoint(point);
Chris@441 195 return command->finish();
Chris@441 196 }
Chris@441 197
Chris@441 198 virtual SortType getSortType(int column) const
Chris@441 199 {
Chris@441 200 if (column == 5) return SortAlphabetical;
Chris@441 201 return SortNumeric;
Chris@441 202 }
Chris@441 203
Chris@442 204 virtual void addPoint(const Point &point)
Chris@442 205 {
Chris@442 206 if (point.value != 0.f) m_haveDistinctValues = true;
Chris@442 207 IntervalModel<RegionRec>::addPoint(point);
Chris@442 208 }
Chris@442 209
Chris@441 210 protected:
Chris@441 211 float m_valueQuantization;
Chris@442 212 bool m_haveDistinctValues;
Chris@441 213 };
Chris@441 214
Chris@441 215 #endif