comparison data/model/EditableDenseThreeDimensionalModel.cpp @ 0:fc9323a41f5a

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