Mercurial > hg > svcore
comparison base/Event.h @ 1629:abc188026a48 single-point
Add toDelimitedDataString; also requires reinstating m_haveDuration
author | Chris Cannam |
---|---|
date | Mon, 11 Mar 2019 15:22:32 +0000 |
parents | 1c21ddac220e |
children | 73bda079567a |
comparison
equal
deleted
inserted
replaced
1628:6db21df9f376 | 1629:abc188026a48 |
---|---|
17 #define SV_EVENT_H | 17 #define SV_EVENT_H |
18 | 18 |
19 #include "BaseTypes.h" | 19 #include "BaseTypes.h" |
20 #include "NoteData.h" | 20 #include "NoteData.h" |
21 #include "XmlExportable.h" | 21 #include "XmlExportable.h" |
22 #include "DataExportOptions.h" | |
22 | 23 |
23 #include <vector> | 24 #include <vector> |
24 #include <stdexcept> | 25 #include <stdexcept> |
25 | 26 |
26 #include <QString> | 27 #include <QString> |
39 */ | 40 */ |
40 class Event | 41 class Event |
41 { | 42 { |
42 public: | 43 public: |
43 Event() : | 44 Event() : |
44 m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false), | 45 m_haveValue(false), m_haveLevel(false), |
46 m_haveDuration(false), m_haveReferenceFrame(false), | |
45 m_value(0.f), m_level(0.f), m_frame(0), | 47 m_value(0.f), m_level(0.f), m_frame(0), |
46 m_duration(0), m_referenceFrame(0), m_label() { } | 48 m_duration(0), m_referenceFrame(0), m_label() { } |
47 | 49 |
48 Event(sv_frame_t frame) : | 50 Event(sv_frame_t frame) : |
49 m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false), | 51 m_haveValue(false), m_haveLevel(false), |
52 m_haveDuration(false), m_haveReferenceFrame(false), | |
50 m_value(0.f), m_level(0.f), m_frame(frame), | 53 m_value(0.f), m_level(0.f), m_frame(frame), |
51 m_duration(0), m_referenceFrame(0), m_label() { } | 54 m_duration(0), m_referenceFrame(0), m_label() { } |
52 | 55 |
53 Event(sv_frame_t frame, QString label) : | 56 Event(sv_frame_t frame, QString label) : |
54 m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false), | 57 m_haveValue(false), m_haveLevel(false), |
58 m_haveDuration(false), m_haveReferenceFrame(false), | |
55 m_value(0.f), m_level(0.f), m_frame(frame), | 59 m_value(0.f), m_level(0.f), m_frame(frame), |
56 m_duration(0), m_referenceFrame(0), m_label(label) { } | 60 m_duration(0), m_referenceFrame(0), m_label(label) { } |
57 | 61 |
58 Event(sv_frame_t frame, float value, QString label) : | 62 Event(sv_frame_t frame, float value, QString label) : |
59 m_haveValue(true), m_haveLevel(false), m_haveReferenceFrame(false), | 63 m_haveValue(true), m_haveLevel(false), |
64 m_haveDuration(false), m_haveReferenceFrame(false), | |
60 m_value(value), m_level(0.f), m_frame(frame), | 65 m_value(value), m_level(0.f), m_frame(frame), |
61 m_duration(0), m_referenceFrame(0), m_label(label) { } | 66 m_duration(0), m_referenceFrame(0), m_label(label) { } |
62 | 67 |
63 Event(sv_frame_t frame, float value, sv_frame_t duration, QString label) : | 68 Event(sv_frame_t frame, float value, sv_frame_t duration, QString label) : |
64 m_haveValue(true), m_haveLevel(false), m_haveReferenceFrame(false), | 69 m_haveValue(true), m_haveLevel(false), |
70 m_haveDuration(true), m_haveReferenceFrame(false), | |
65 m_value(value), m_level(0.f), m_frame(frame), | 71 m_value(value), m_level(0.f), m_frame(frame), |
66 m_duration(duration), m_referenceFrame(0), m_label(label) { | 72 m_duration(duration), m_referenceFrame(0), m_label(label) { |
67 if (m_duration < 0) throw std::logic_error("duration must be >= 0"); | 73 if (m_duration < 0) throw std::logic_error("duration must be >= 0"); |
68 } | 74 } |
69 | 75 |
70 Event(sv_frame_t frame, float value, sv_frame_t duration, | 76 Event(sv_frame_t frame, float value, sv_frame_t duration, |
71 float level, QString label) : | 77 float level, QString label) : |
72 m_haveValue(true), m_haveLevel(true), m_haveReferenceFrame(false), | 78 m_haveValue(true), m_haveLevel(true), |
79 m_haveDuration(true), m_haveReferenceFrame(false), | |
73 m_value(value), m_level(level), m_frame(frame), | 80 m_value(value), m_level(level), m_frame(frame), |
74 m_duration(duration), m_referenceFrame(0), m_label(label) { | 81 m_duration(duration), m_referenceFrame(0), m_label(label) { |
75 if (m_duration < 0) throw std::logic_error("duration must be >= 0"); | 82 if (m_duration < 0) throw std::logic_error("duration must be >= 0"); |
76 } | 83 } |
77 | 84 |
101 p.m_haveValue = false; | 108 p.m_haveValue = false; |
102 p.m_value = 0.f; | 109 p.m_value = 0.f; |
103 return p; | 110 return p; |
104 } | 111 } |
105 | 112 |
106 bool hasDuration() const { return m_duration != 0; } | 113 bool hasDuration() const { return m_haveDuration; } |
107 sv_frame_t getDuration() const { return m_duration; } | 114 sv_frame_t getDuration() const { return m_duration; } |
108 | 115 |
109 Event withDuration(sv_frame_t duration) const { | 116 Event withDuration(sv_frame_t duration) const { |
110 Event p(*this); | 117 Event p(*this); |
111 p.m_duration = duration; | 118 p.m_duration = duration; |
119 p.m_haveDuration = true; | |
112 if (duration < 0) throw std::logic_error("duration must be >= 0"); | 120 if (duration < 0) throw std::logic_error("duration must be >= 0"); |
113 return p; | 121 return p; |
114 } | 122 } |
115 Event withoutDuration() const { | 123 Event withoutDuration() const { |
116 Event p(*this); | 124 Event p(*this); |
125 p.m_haveDuration = false; | |
117 p.m_duration = 0; | 126 p.m_duration = 0; |
118 return p; | 127 return p; |
119 } | 128 } |
120 | 129 |
121 bool hasLabel() const { return m_label != QString(); } | 130 bool hasLabel() const { return m_label != QString(); } |
164 } | 173 } |
165 | 174 |
166 bool operator==(const Event &p) const { | 175 bool operator==(const Event &p) const { |
167 | 176 |
168 if (m_frame != p.m_frame) return false; | 177 if (m_frame != p.m_frame) return false; |
169 if (m_duration != p.m_duration) return false; | 178 |
179 if (m_haveDuration != p.m_haveDuration) return false; | |
180 if (m_haveDuration && (m_duration != p.m_duration)) return false; | |
170 | 181 |
171 if (m_haveValue != p.m_haveValue) return false; | 182 if (m_haveValue != p.m_haveValue) return false; |
172 if (m_haveValue && (m_value != p.m_value)) return false; | 183 if (m_haveValue && (m_value != p.m_value)) return false; |
173 | 184 |
174 if (m_haveLevel != p.m_haveLevel) return false; | 185 if (m_haveLevel != p.m_haveLevel) return false; |
183 return true; | 194 return true; |
184 } | 195 } |
185 | 196 |
186 bool operator<(const Event &p) const { | 197 bool operator<(const Event &p) const { |
187 | 198 |
188 if (m_frame != p.m_frame) return m_frame < p.m_frame; | 199 if (m_frame != p.m_frame) { |
189 if (m_duration != p.m_duration) return m_duration < p.m_duration; | 200 return m_frame < p.m_frame; |
201 } | |
190 | 202 |
191 // events without a property sort before events with that property | 203 // events without a property sort before events with that property |
192 | 204 |
193 if (m_haveValue != p.m_haveValue) return !m_haveValue; | 205 if (m_haveDuration != p.m_haveDuration) { |
194 if (m_haveValue && (m_value != p.m_value)) return m_value < p.m_value; | 206 return !m_haveDuration; |
195 | 207 } |
196 if (m_haveLevel != p.m_haveLevel) return !m_haveLevel; | 208 if (m_haveDuration && (m_duration != p.m_duration)) { |
197 if (m_haveLevel && (m_level != p.m_level)) return m_level < p.m_level; | 209 return m_duration < p.m_duration; |
210 } | |
211 | |
212 if (m_haveValue != p.m_haveValue) { | |
213 return !m_haveValue; | |
214 } | |
215 if (m_haveValue && (m_value != p.m_value)) { | |
216 return m_value < p.m_value; | |
217 } | |
218 | |
219 if (m_haveLevel != p.m_haveLevel) { | |
220 return !m_haveLevel; | |
221 } | |
222 if (m_haveLevel && (m_level != p.m_level)) { | |
223 return m_level < p.m_level; | |
224 } | |
198 | 225 |
199 if (m_haveReferenceFrame != p.m_haveReferenceFrame) { | 226 if (m_haveReferenceFrame != p.m_haveReferenceFrame) { |
200 return !m_haveReferenceFrame; | 227 return !m_haveReferenceFrame; |
201 } | 228 } |
202 if (m_haveReferenceFrame && (m_referenceFrame != p.m_referenceFrame)) { | 229 if (m_haveReferenceFrame && (m_referenceFrame != p.m_referenceFrame)) { |
211 QString extraAttributes = "") const { | 238 QString extraAttributes = "") const { |
212 | 239 |
213 // For I/O purposes these are points, not events | 240 // For I/O purposes these are points, not events |
214 stream << indent << QString("<point frame=\"%1\" ").arg(m_frame); | 241 stream << indent << QString("<point frame=\"%1\" ").arg(m_frame); |
215 if (m_haveValue) stream << QString("value=\"%1\" ").arg(m_value); | 242 if (m_haveValue) stream << QString("value=\"%1\" ").arg(m_value); |
216 if (m_duration) stream << QString("duration=\"%1\" ").arg(m_duration); | 243 if (m_haveDuration) stream << QString("duration=\"%1\" ").arg(m_duration); |
217 if (m_haveLevel) stream << QString("level=\"%1\" ").arg(m_level); | 244 if (m_haveLevel) stream << QString("level=\"%1\" ").arg(m_level); |
218 if (m_haveReferenceFrame) stream << QString("referenceFrame=\"%1\" ") | 245 if (m_haveReferenceFrame) stream << QString("referenceFrame=\"%1\" ") |
219 .arg(m_referenceFrame); | 246 .arg(m_referenceFrame); |
220 stream << QString("label=\"%1\" ") | 247 stream << QString("label=\"%1\" ") |
221 .arg(XmlExportable::encodeEntities(m_label)); | 248 .arg(XmlExportable::encodeEntities(m_label)); |
229 toXml(out, indent, extraAttributes); | 256 toXml(out, indent, extraAttributes); |
230 out.flush(); | 257 out.flush(); |
231 return s; | 258 return s; |
232 } | 259 } |
233 | 260 |
234 NoteData toNoteData(sv_samplerate_t sampleRate, bool valueIsMidiPitch) { | 261 NoteData toNoteData(sv_samplerate_t sampleRate, |
262 bool valueIsMidiPitch) { | |
235 | 263 |
236 sv_frame_t duration; | 264 sv_frame_t duration; |
237 if (m_duration > 0) { | 265 if (m_haveDuration && m_duration > 0) { |
238 duration = m_duration; | 266 duration = m_duration; |
239 } else { | 267 } else { |
240 duration = sv_frame_t(sampleRate / 6); // arbitrary short duration | 268 duration = sv_frame_t(sampleRate / 6); // arbitrary short duration |
241 } | 269 } |
242 | 270 |
268 } | 296 } |
269 | 297 |
270 return n; | 298 return n; |
271 } | 299 } |
272 | 300 |
301 QString toDelimitedDataString(QString delimiter, | |
302 DataExportOptions opts, | |
303 sv_samplerate_t sampleRate) const { | |
304 QStringList list; | |
305 | |
306 list << RealTime::frame2RealTime(m_frame, sampleRate) | |
307 .toString().c_str(); | |
308 | |
309 if (m_haveValue) { | |
310 list << QString("%1").arg(m_value); | |
311 } | |
312 | |
313 if (m_haveDuration) { | |
314 list << RealTime::frame2RealTime(m_duration, sampleRate) | |
315 .toString().c_str(); | |
316 } | |
317 | |
318 if (m_haveLevel) { | |
319 if (!(opts & DataExportOmitLevels)) { | |
320 list << QString("%1").arg(m_level); | |
321 } | |
322 } | |
323 | |
324 if (m_label != "") list << m_label; | |
325 | |
326 return list.join(delimiter); | |
327 } | |
328 | |
273 uint hash(uint seed = 0) const { | 329 uint hash(uint seed = 0) const { |
274 uint h = qHash(m_label, seed); | 330 uint h = qHash(m_label, seed); |
275 if (m_haveValue) h ^= qHash(m_value); | 331 if (m_haveValue) h ^= qHash(m_value); |
276 if (m_haveLevel) h ^= qHash(m_level); | 332 if (m_haveLevel) h ^= qHash(m_level); |
277 h ^= qHash(m_frame); | 333 h ^= qHash(m_frame); |
278 h ^= qHash(m_duration); | 334 if (m_haveDuration) h ^= qHash(m_duration); |
279 if (m_haveReferenceFrame) h ^= qHash(m_referenceFrame); | 335 if (m_haveReferenceFrame) h ^= qHash(m_referenceFrame); |
280 return h; | 336 return h; |
281 } | 337 } |
282 | 338 |
283 private: | 339 private: |
284 // The order of fields here is chosen to minimise overall size of struct. | 340 // The order of fields here is chosen to minimise overall size of struct. |
285 // We potentially store very many of these objects. | 341 // We potentially store very many of these objects. |
286 // If you change something, check what difference it makes to packing. | 342 // If you change something, check what difference it makes to packing. |
287 bool m_haveValue : 1; | 343 bool m_haveValue : 1; |
288 bool m_haveLevel : 1; | 344 bool m_haveLevel : 1; |
345 bool m_haveDuration : 1; | |
289 bool m_haveReferenceFrame : 1; | 346 bool m_haveReferenceFrame : 1; |
290 float m_value; | 347 float m_value; |
291 float m_level; | 348 float m_level; |
292 sv_frame_t m_frame; | 349 sv_frame_t m_frame; |
293 sv_frame_t m_duration; | 350 sv_frame_t m_duration; |