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