comparison data/model/EditableDenseThreeDimensionalModel.cpp @ 152:21792a550ec9 last-cc-copyright

* Move the current DenseThreeDimensionalModel to EditableDenseThreeDimensionalModel (wow!), and make DTDM an abstract base * Move FFTFuzzyAdapter to FFTModel as a new subclass of DTDM
author Chris Cannam
date Mon, 31 Jul 2006 17:05:18 +0000
parents
children 9c652f2c39b1
comparison
equal deleted inserted replaced
151:3c1d5ef43baa 152:21792a550ec9
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 #include "EditableDenseThreeDimensionalModel.h"
17
18 #include <QTextStream>
19
20 EditableDenseThreeDimensionalModel::EditableDenseThreeDimensionalModel(size_t sampleRate,
21 size_t resolution,
22 size_t yBinCount,
23 bool notifyOnAdd) :
24 m_sampleRate(sampleRate),
25 m_resolution(resolution),
26 m_yBinCount(yBinCount),
27 m_minimum(0.0),
28 m_maximum(0.0),
29 m_notifyOnAdd(notifyOnAdd),
30 m_sinceLastNotifyMin(-1),
31 m_sinceLastNotifyMax(-1),
32 m_completion(100)
33 {
34 }
35
36 bool
37 EditableDenseThreeDimensionalModel::isOK() const
38 {
39 return true;
40 }
41
42 size_t
43 EditableDenseThreeDimensionalModel::getSampleRate() const
44 {
45 return m_sampleRate;
46 }
47
48 size_t
49 EditableDenseThreeDimensionalModel::getStartFrame() const
50 {
51 return 0;
52 }
53
54 size_t
55 EditableDenseThreeDimensionalModel::getEndFrame() const
56 {
57 return m_resolution * m_data.size() + (m_resolution - 1);
58 }
59
60 Model *
61 EditableDenseThreeDimensionalModel::clone() const
62 {
63 EditableDenseThreeDimensionalModel *model =
64 new EditableDenseThreeDimensionalModel
65 (m_sampleRate, m_resolution, m_yBinCount);
66
67 model->m_minimum = m_minimum;
68 model->m_maximum = m_maximum;
69
70 for (size_t i = 0; i < m_data.size(); ++i) {
71 model->setBinValues(i * m_resolution, m_data[i]);
72 }
73
74 return model;
75 }
76
77 size_t
78 EditableDenseThreeDimensionalModel::getResolution() const
79 {
80 return m_resolution;
81 }
82
83 void
84 EditableDenseThreeDimensionalModel::setResolution(size_t sz)
85 {
86 m_resolution = sz;
87 }
88
89 size_t
90 EditableDenseThreeDimensionalModel::getYBinCount() const
91 {
92 return m_yBinCount;
93 }
94
95 void
96 EditableDenseThreeDimensionalModel::setYBinCount(size_t sz)
97 {
98 m_yBinCount = sz;
99 }
100
101 float
102 EditableDenseThreeDimensionalModel::getMinimumLevel() const
103 {
104 return m_minimum;
105 }
106
107 void
108 EditableDenseThreeDimensionalModel::setMinimumLevel(float level)
109 {
110 m_minimum = level;
111 }
112
113 float
114 EditableDenseThreeDimensionalModel::getMaximumLevel() const
115 {
116 return m_maximum;
117 }
118
119 void
120 EditableDenseThreeDimensionalModel::setMaximumLevel(float level)
121 {
122 m_maximum = level;
123 }
124
125 void
126 EditableDenseThreeDimensionalModel::getBinValues(long windowStart,
127 BinValueSet &result) const
128 {
129 QMutexLocker locker(&m_mutex);
130
131 long index = windowStart / m_resolution;
132
133 if (index >= 0 && index < long(m_data.size())) {
134 result = m_data[index];
135 } else {
136 result.clear();
137 }
138
139 while (result.size() < m_yBinCount) result.push_back(m_minimum);
140 }
141
142 float
143 EditableDenseThreeDimensionalModel::getBinValue(long windowStart,
144 size_t n) const
145 {
146 QMutexLocker locker(&m_mutex);
147
148 long index = windowStart / m_resolution;
149
150 if (index >= 0 && index < long(m_data.size())) {
151 const BinValueSet &s = m_data[index];
152 if (n < s.size()) return s[n];
153 }
154
155 return m_minimum;
156 }
157
158 void
159 EditableDenseThreeDimensionalModel::setBinValues(long windowStart,
160 const BinValueSet &values)
161 {
162 QMutexLocker locker(&m_mutex);
163
164 long index = windowStart / m_resolution;
165
166 while (index >= long(m_data.size())) {
167 m_data.push_back(BinValueSet());
168 }
169
170 bool newExtents = (m_data.empty() && (m_minimum == m_maximum));
171 bool allChange = false;
172
173 for (size_t i = 0; i < values.size(); ++i) {
174 if (newExtents || values[i] < m_minimum) {
175 m_minimum = values[i];
176 allChange = true;
177 }
178 if (newExtents || values[i] > m_maximum) {
179 m_maximum = values[i];
180 allChange = true;
181 }
182 }
183
184 m_data[index] = values;
185
186 if (m_notifyOnAdd) {
187 if (allChange) {
188 emit modelChanged();
189 } else {
190 emit modelChanged(windowStart, windowStart + m_resolution);
191 }
192 } else {
193 if (allChange) {
194 m_sinceLastNotifyMin = -1;
195 m_sinceLastNotifyMax = -1;
196 emit modelChanged();
197 } else {
198 if (m_sinceLastNotifyMin == -1 ||
199 windowStart < m_sinceLastNotifyMin) {
200 m_sinceLastNotifyMin = windowStart;
201 }
202 if (m_sinceLastNotifyMax == -1 ||
203 windowStart > m_sinceLastNotifyMax) {
204 m_sinceLastNotifyMax = windowStart;
205 }
206 }
207 }
208 }
209
210 QString
211 EditableDenseThreeDimensionalModel::getBinName(size_t n) const
212 {
213 if (m_binNames.size() > n) return m_binNames[n];
214 else return "";
215 }
216
217 void
218 EditableDenseThreeDimensionalModel::setBinName(size_t n, QString name)
219 {
220 while (m_binNames.size() <= n) m_binNames.push_back("");
221 m_binNames[n] = name;
222 emit modelChanged();
223 }
224
225 void
226 EditableDenseThreeDimensionalModel::setBinNames(std::vector<QString> names)
227 {
228 m_binNames = names;
229 emit modelChanged();
230 }
231
232 void
233 EditableDenseThreeDimensionalModel::setCompletion(int completion)
234 {
235 if (m_completion != completion) {
236 m_completion = completion;
237
238 if (completion == 100) {
239
240 m_notifyOnAdd = true; // henceforth
241 emit modelChanged();
242
243 } else if (!m_notifyOnAdd) {
244
245 if (m_sinceLastNotifyMin >= 0 &&
246 m_sinceLastNotifyMax >= 0) {
247 emit modelChanged(m_sinceLastNotifyMin,
248 m_sinceLastNotifyMax + m_resolution);
249 m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1;
250 } else {
251 emit completionChanged();
252 }
253 } else {
254 emit completionChanged();
255 }
256 }
257 }
258
259 void
260 EditableDenseThreeDimensionalModel::toXml(QTextStream &out,
261 QString indent,
262 QString extraAttributes) const
263 {
264 // For historical reasons we read and write "resolution" as "windowSize"
265
266 out << Model::toXmlString
267 (indent, QString("type=\"dense\" dimensions=\"3\" windowSize=\"%1\" yBinCount=\"%2\" minimum=\"%3\" maximum=\"%4\" dataset=\"%5\" %6")
268 .arg(m_resolution)
269 .arg(m_yBinCount)
270 .arg(m_minimum)
271 .arg(m_maximum)
272 .arg(getObjectExportId(&m_data))
273 .arg(extraAttributes));
274
275 out << indent;
276 out << QString("<dataset id=\"%1\" dimensions=\"3\" separator=\" \">\n")
277 .arg(getObjectExportId(&m_data));
278
279 for (size_t i = 0; i < m_binNames.size(); ++i) {
280 if (m_binNames[i] != "") {
281 out << indent + " ";
282 out << QString("<bin number=\"%1\" name=\"%2\"/>\n")
283 .arg(i).arg(m_binNames[i]);
284 }
285 }
286
287 for (size_t i = 0; i < m_data.size(); ++i) {
288 out << indent + " ";
289 out << QString("<row n=\"%1\">").arg(i);
290 for (size_t j = 0; j < m_data[i].size(); ++j) {
291 if (j > 0) out << " ";
292 out << m_data[i][j];
293 }
294 out << QString("</row>\n");
295 }
296
297 out << indent + "</dataset>\n";
298 }
299
300 QString
301 EditableDenseThreeDimensionalModel::toXmlString(QString indent,
302 QString extraAttributes) const
303 {
304 QString s;
305
306 {
307 QTextStream out(&s);
308 toXml(out, indent, extraAttributes);
309 }
310
311 return s;
312 }
313
314 #ifdef INCLUDE_MOCFILES
315 #include "EditableDenseThreeDimensionalModel.moc.cpp"
316 #endif
317