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