comparison data/model/RegionModel.h @ 441:288f45533041

* Add region model and layer; improve assignment of model types to feature extraction transforms with duration
author Chris Cannam
date Thu, 18 Sep 2008 16:08:14 +0000
parents
children 04b7fd31e1c6
comparison
equal deleted inserted replaced
440:5746c559af15 441:288f45533041
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 #ifndef _REGION_MODEL_H_
17 #define _REGION_MODEL_H_
18
19 #include "IntervalModel.h"
20 #include "base/RealTime.h"
21
22 /**
23 * RegionModel -- a concrete IntervalModel for intervals associated
24 * with a value, which we call regions for no very compelling reason.
25 */
26
27 /**
28 * Region "point" type. A region is something that has an onset time,
29 * a single value, and a duration. Like other points, it can also
30 * have a label.
31 *
32 * This is called RegionRec instead of Region to avoid name collisions
33 * with the X11 Region struct. Bah.
34 */
35
36 struct RegionRec
37 {
38 public:
39 RegionRec(long _frame) : frame(_frame), value(0.0f), duration(0) { }
40 RegionRec(long _frame, float _value, size_t _duration, QString _label) :
41 frame(_frame), value(_value), duration(_duration), label(_label) { }
42
43 int getDimensions() const { return 3; }
44
45 long frame;
46 float value;
47 size_t duration;
48 QString label;
49
50 QString getLabel() const { return label; }
51
52 void toXml(QTextStream &stream,
53 QString indent = "",
54 QString extraAttributes = "") const
55 {
56 stream <<
57 QString("%1<point frame=\"%2\" value=\"%3\" duration=\"%4\" label=\"%5\" %6/>\n")
58 .arg(indent).arg(frame).arg(value).arg(duration).arg(label).arg(extraAttributes);
59 }
60
61 QString toDelimitedDataString(QString delimiter, size_t sampleRate) const
62 {
63 QStringList list;
64 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
65 list << QString("%1").arg(value);
66 list << RealTime::frame2RealTime(duration, sampleRate).toString().c_str();
67 if (label != "") list << label;
68 return list.join(delimiter);
69 }
70
71 struct Comparator {
72 bool operator()(const RegionRec &p1,
73 const RegionRec &p2) const {
74 if (p1.frame != p2.frame) return p1.frame < p2.frame;
75 if (p1.value != p2.value) return p1.value < p2.value;
76 if (p1.duration != p2.duration) return p1.duration < p2.duration;
77 return p1.label < p2.label;
78 }
79 };
80
81 struct OrderComparator {
82 bool operator()(const RegionRec &p1,
83 const RegionRec &p2) const {
84 return p1.frame < p2.frame;
85 }
86 };
87 };
88
89
90 class RegionModel : public IntervalModel<RegionRec>
91 {
92 Q_OBJECT
93
94 public:
95 RegionModel(size_t sampleRate, size_t resolution,
96 bool notifyOnAdd = true) :
97 IntervalModel<RegionRec>(sampleRate, resolution, notifyOnAdd),
98 m_valueQuantization(0)
99 {
100 }
101
102 RegionModel(size_t sampleRate, size_t resolution,
103 float valueMinimum, float valueMaximum,
104 bool notifyOnAdd = true) :
105 IntervalModel<RegionRec>(sampleRate, resolution,
106 valueMinimum, valueMaximum,
107 notifyOnAdd),
108 m_valueQuantization(0)
109 {
110 }
111
112 virtual ~RegionModel()
113 {
114 }
115
116 float getValueQuantization() const { return m_valueQuantization; }
117 void setValueQuantization(float q) { m_valueQuantization = q; }
118
119 QString getTypeName() const { return tr("Region"); }
120
121 virtual void toXml(QTextStream &out,
122 QString indent = "",
123 QString extraAttributes = "") const
124 {
125 std::cerr << "RegionModel::toXml: extraAttributes = \""
126 << extraAttributes.toStdString() << std::endl;
127
128 IntervalModel<RegionRec>::toXml
129 (out,
130 indent,
131 QString("%1 valueQuantization=\"%2\"")
132 .arg(extraAttributes).arg(m_valueQuantization));
133 }
134
135 /**
136 * TabularModel methods.
137 */
138
139 virtual int getColumnCount() const
140 {
141 return 6;
142 }
143
144 virtual QString getHeading(int column) const
145 {
146 switch (column) {
147 case 0: return tr("Time");
148 case 1: return tr("Frame");
149 case 2: return tr("Value");
150 case 3: return tr("Duration");
151 case 4: return tr("Label");
152 default: return tr("Unknown");
153 }
154 }
155
156 virtual QVariant getData(int row, int column, int role) const
157 {
158 if (column < 4) {
159 return IntervalModel<RegionRec>::getData(row, column, role);
160 }
161
162 PointListIterator i = getPointListIteratorForRow(row);
163 if (i == m_points.end()) return QVariant();
164
165 switch (column) {
166 case 4: return i->label;
167 default: return QVariant();
168 }
169 }
170
171 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
172 {
173 if (column < 4) {
174 return IntervalModel<RegionRec>::getSetDataCommand
175 (row, column, value, role);
176 }
177
178 if (role != Qt::EditRole) return false;
179 PointListIterator i = getPointListIteratorForRow(row);
180 if (i == m_points.end()) return false;
181 EditCommand *command = new EditCommand(this, tr("Edit Data"));
182
183 Point point(*i);
184 command->deletePoint(point);
185
186 switch (column) {
187 case 4: point.label = value.toString(); break;
188 }
189
190 command->addPoint(point);
191 return command->finish();
192 }
193
194 virtual SortType getSortType(int column) const
195 {
196 if (column == 5) return SortAlphabetical;
197 return SortNumeric;
198 }
199
200 protected:
201 float m_valueQuantization;
202 };
203
204 #endif