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;