Mercurial > hg > svcore
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 |