# HG changeset patch # User Chris Cannam # Date 1552317752 0 # Node ID abc188026a48d8e2296f0d2f052d4260ded6d569 # Parent 6db21df9f376eb30b1422a0dec00a27b2485d373 Add toDelimitedDataString; also requires reinstating m_haveDuration diff -r 6db21df9f376 -r abc188026a48 base/Event.h --- a/base/Event.h Mon Mar 11 14:59:11 2019 +0000 +++ b/base/Event.h Mon Mar 11 15:22:32 2019 +0000 @@ -19,6 +19,7 @@ #include "BaseTypes.h" #include "NoteData.h" #include "XmlExportable.h" +#include "DataExportOptions.h" #include #include @@ -41,27 +42,32 @@ { public: Event() : - m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false), + m_haveValue(false), m_haveLevel(false), + m_haveDuration(false), m_haveReferenceFrame(false), m_value(0.f), m_level(0.f), m_frame(0), m_duration(0), m_referenceFrame(0), m_label() { } Event(sv_frame_t frame) : - m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false), + m_haveValue(false), m_haveLevel(false), + m_haveDuration(false), m_haveReferenceFrame(false), m_value(0.f), m_level(0.f), m_frame(frame), m_duration(0), m_referenceFrame(0), m_label() { } Event(sv_frame_t frame, QString label) : - m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false), + m_haveValue(false), m_haveLevel(false), + m_haveDuration(false), m_haveReferenceFrame(false), m_value(0.f), m_level(0.f), m_frame(frame), m_duration(0), m_referenceFrame(0), m_label(label) { } Event(sv_frame_t frame, float value, QString label) : - m_haveValue(true), m_haveLevel(false), m_haveReferenceFrame(false), + m_haveValue(true), m_haveLevel(false), + m_haveDuration(false), m_haveReferenceFrame(false), m_value(value), m_level(0.f), m_frame(frame), m_duration(0), m_referenceFrame(0), m_label(label) { } Event(sv_frame_t frame, float value, sv_frame_t duration, QString label) : - m_haveValue(true), m_haveLevel(false), m_haveReferenceFrame(false), + m_haveValue(true), m_haveLevel(false), + m_haveDuration(true), m_haveReferenceFrame(false), m_value(value), m_level(0.f), m_frame(frame), m_duration(duration), m_referenceFrame(0), m_label(label) { if (m_duration < 0) throw std::logic_error("duration must be >= 0"); @@ -69,7 +75,8 @@ Event(sv_frame_t frame, float value, sv_frame_t duration, float level, QString label) : - m_haveValue(true), m_haveLevel(true), m_haveReferenceFrame(false), + m_haveValue(true), m_haveLevel(true), + m_haveDuration(true), m_haveReferenceFrame(false), m_value(value), m_level(level), m_frame(frame), m_duration(duration), m_referenceFrame(0), m_label(label) { if (m_duration < 0) throw std::logic_error("duration must be >= 0"); @@ -103,17 +110,19 @@ return p; } - bool hasDuration() const { return m_duration != 0; } + bool hasDuration() const { return m_haveDuration; } sv_frame_t getDuration() const { return m_duration; } Event withDuration(sv_frame_t duration) const { Event p(*this); p.m_duration = duration; + p.m_haveDuration = true; if (duration < 0) throw std::logic_error("duration must be >= 0"); return p; } Event withoutDuration() const { Event p(*this); + p.m_haveDuration = false; p.m_duration = 0; return p; } @@ -166,7 +175,9 @@ bool operator==(const Event &p) const { if (m_frame != p.m_frame) return false; - if (m_duration != p.m_duration) return false; + + if (m_haveDuration != p.m_haveDuration) return false; + if (m_haveDuration && (m_duration != p.m_duration)) return false; if (m_haveValue != p.m_haveValue) return false; if (m_haveValue && (m_value != p.m_value)) return false; @@ -185,16 +196,32 @@ bool operator<(const Event &p) const { - if (m_frame != p.m_frame) return m_frame < p.m_frame; - if (m_duration != p.m_duration) return m_duration < p.m_duration; + if (m_frame != p.m_frame) { + return m_frame < p.m_frame; + } // events without a property sort before events with that property - if (m_haveValue != p.m_haveValue) return !m_haveValue; - if (m_haveValue && (m_value != p.m_value)) return m_value < p.m_value; + if (m_haveDuration != p.m_haveDuration) { + return !m_haveDuration; + } + if (m_haveDuration && (m_duration != p.m_duration)) { + return m_duration < p.m_duration; + } + + if (m_haveValue != p.m_haveValue) { + return !m_haveValue; + } + if (m_haveValue && (m_value != p.m_value)) { + return m_value < p.m_value; + } - if (m_haveLevel != p.m_haveLevel) return !m_haveLevel; - if (m_haveLevel && (m_level != p.m_level)) return m_level < p.m_level; + if (m_haveLevel != p.m_haveLevel) { + return !m_haveLevel; + } + if (m_haveLevel && (m_level != p.m_level)) { + return m_level < p.m_level; + } if (m_haveReferenceFrame != p.m_haveReferenceFrame) { return !m_haveReferenceFrame; @@ -213,7 +240,7 @@ // For I/O purposes these are points, not events stream << indent << QString(" 0) { + if (m_haveDuration && m_duration > 0) { duration = m_duration; } else { duration = sv_frame_t(sampleRate / 6); // arbitrary short duration @@ -270,12 +298,40 @@ return n; } + QString toDelimitedDataString(QString delimiter, + DataExportOptions opts, + sv_samplerate_t sampleRate) const { + QStringList list; + + list << RealTime::frame2RealTime(m_frame, sampleRate) + .toString().c_str(); + + if (m_haveValue) { + list << QString("%1").arg(m_value); + } + + if (m_haveDuration) { + list << RealTime::frame2RealTime(m_duration, sampleRate) + .toString().c_str(); + } + + if (m_haveLevel) { + if (!(opts & DataExportOmitLevels)) { + list << QString("%1").arg(m_level); + } + } + + if (m_label != "") list << m_label; + + return list.join(delimiter); + } + uint hash(uint seed = 0) const { uint h = qHash(m_label, seed); if (m_haveValue) h ^= qHash(m_value); if (m_haveLevel) h ^= qHash(m_level); h ^= qHash(m_frame); - h ^= qHash(m_duration); + if (m_haveDuration) h ^= qHash(m_duration); if (m_haveReferenceFrame) h ^= qHash(m_referenceFrame); return h; } @@ -286,6 +342,7 @@ // If you change something, check what difference it makes to packing. bool m_haveValue : 1; bool m_haveLevel : 1; + bool m_haveDuration : 1; bool m_haveReferenceFrame : 1; float m_value; float m_level;