Mercurial > hg > easaier-soundaccess
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 |