Chris@1611
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1611
|
2
|
Chris@1611
|
3 /*
|
Chris@1611
|
4 Sonic Visualiser
|
Chris@1611
|
5 An audio file viewer and annotation editor.
|
Chris@1611
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1611
|
7 This file copyright 2006 Chris Cannam.
|
Chris@1611
|
8
|
Chris@1611
|
9 This program is free software; you can redistribute it and/or
|
Chris@1611
|
10 modify it under the terms of the GNU General Public License as
|
Chris@1611
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@1611
|
12 License, or (at your option) any later version. See the file
|
Chris@1611
|
13 COPYING included with this distribution for more information.
|
Chris@1611
|
14 */
|
Chris@1611
|
15
|
Chris@1611
|
16 #ifndef SV_POINT_H
|
Chris@1611
|
17 #define SV_POINT_H
|
Chris@1611
|
18
|
Chris@1611
|
19 #include <QString>
|
Chris@1612
|
20 #include <vector>
|
Chris@1611
|
21
|
Chris@1611
|
22 #include "BaseTypes.h"
|
Chris@1612
|
23 #include "XmlExportable.h"
|
Chris@1612
|
24
|
Chris@1612
|
25 //!!! given that these can have size (i.e. duration), maybe Point
|
Chris@1612
|
26 //!!! isn't really an ideal name... perhaps I should go back to dull
|
Chris@1612
|
27 //!!! old Event
|
Chris@1611
|
28
|
Chris@1611
|
29 class Point
|
Chris@1611
|
30 {
|
Chris@1611
|
31 public:
|
Chris@1611
|
32 Point(sv_frame_t frame, QString label) :
|
Chris@1612
|
33 m_haveValue(false), m_haveLevel(false), m_haveReferenceFrame(false),
|
Chris@1611
|
34 m_value(0.f), m_level(0.f), m_frame(frame),
|
Chris@1611
|
35 m_duration(0), m_referenceFrame(0), m_label(label) { }
|
Chris@1611
|
36
|
Chris@1611
|
37 Point(sv_frame_t frame, float value, QString label) :
|
Chris@1612
|
38 m_haveValue(true), m_haveLevel(false), m_haveReferenceFrame(false),
|
Chris@1611
|
39 m_value(value), m_level(0.f), m_frame(frame),
|
Chris@1611
|
40 m_duration(0), m_referenceFrame(0), m_label(label) { }
|
Chris@1611
|
41
|
Chris@1611
|
42 Point(sv_frame_t frame, float value, sv_frame_t duration, QString label) :
|
Chris@1612
|
43 m_haveValue(true), m_haveLevel(false), m_haveReferenceFrame(false),
|
Chris@1611
|
44 m_value(value), m_level(0.f), m_frame(frame),
|
Chris@1611
|
45 m_duration(duration), m_referenceFrame(0), m_label(label) { }
|
Chris@1611
|
46
|
Chris@1612
|
47 Point(sv_frame_t frame, float value, sv_frame_t duration,
|
Chris@1612
|
48 float level, QString label) :
|
Chris@1612
|
49 m_haveValue(true), m_haveLevel(true), m_haveReferenceFrame(false),
|
Chris@1611
|
50 m_value(value), m_level(level), m_frame(frame),
|
Chris@1611
|
51 m_duration(duration), m_referenceFrame(0), m_label(label) { }
|
Chris@1611
|
52
|
Chris@1611
|
53 Point(const Point &point) =default;
|
Chris@1611
|
54 Point &operator=(const Point &point) =default;
|
Chris@1611
|
55 Point &operator=(Point &&point) =default;
|
Chris@1611
|
56
|
Chris@1611
|
57 sv_frame_t getFrame() const { return m_frame; }
|
Chris@1611
|
58
|
Chris@1611
|
59 Point withFrame(sv_frame_t frame) const {
|
Chris@1611
|
60 Point p(*this);
|
Chris@1611
|
61 p.m_frame = frame;
|
Chris@1611
|
62 return p;
|
Chris@1611
|
63 }
|
Chris@1611
|
64
|
Chris@1611
|
65 bool haveValue() const { return m_haveValue; }
|
Chris@1611
|
66 float getValue() const { return m_value; }
|
Chris@1611
|
67
|
Chris@1611
|
68 Point withValue(float value) const {
|
Chris@1611
|
69 Point p(*this);
|
Chris@1611
|
70 p.m_haveValue = true;
|
Chris@1611
|
71 p.m_value = value;
|
Chris@1611
|
72 return p;
|
Chris@1611
|
73 }
|
Chris@1611
|
74
|
Chris@1612
|
75 bool haveDuration() const { return m_duration != 0; }
|
Chris@1611
|
76 sv_frame_t getDuration() const { return m_duration; }
|
Chris@1611
|
77
|
Chris@1611
|
78 Point withDuration(sv_frame_t duration) const {
|
Chris@1611
|
79 Point p(*this);
|
Chris@1611
|
80 p.m_duration = duration;
|
Chris@1611
|
81 return p;
|
Chris@1611
|
82 }
|
Chris@1611
|
83
|
Chris@1611
|
84 QString getLabel() const { return m_label; }
|
Chris@1611
|
85
|
Chris@1611
|
86 Point withLabel(QString label) const {
|
Chris@1611
|
87 Point p(*this);
|
Chris@1611
|
88 p.m_label = label;
|
Chris@1611
|
89 return p;
|
Chris@1611
|
90 }
|
Chris@1611
|
91
|
Chris@1611
|
92 bool haveLevel() const { return m_haveLevel; }
|
Chris@1611
|
93 float getLevel() const { return m_level; }
|
Chris@1611
|
94 Point withLevel(float level) const {
|
Chris@1611
|
95 Point p(*this);
|
Chris@1611
|
96 p.m_haveLevel = true;
|
Chris@1611
|
97 p.m_level = level;
|
Chris@1611
|
98 return p;
|
Chris@1611
|
99 }
|
Chris@1611
|
100
|
Chris@1611
|
101 bool haveReferenceFrame() const { return m_haveReferenceFrame; }
|
Chris@1611
|
102 sv_frame_t getReferenceFrame() const { return m_referenceFrame; }
|
Chris@1611
|
103
|
Chris@1611
|
104 bool referenceFrameDiffers() const { // from point frame
|
Chris@1611
|
105 return m_haveReferenceFrame && (m_referenceFrame != m_frame);
|
Chris@1611
|
106 }
|
Chris@1611
|
107
|
Chris@1611
|
108 Point withReferenceFrame(sv_frame_t frame) const {
|
Chris@1611
|
109 Point p(*this);
|
Chris@1611
|
110 p.m_haveReferenceFrame = true;
|
Chris@1611
|
111 p.m_referenceFrame = frame;
|
Chris@1611
|
112 return p;
|
Chris@1611
|
113 }
|
Chris@1612
|
114
|
Chris@1612
|
115 bool operator==(const Point &p) const {
|
Chris@1612
|
116
|
Chris@1612
|
117 if (m_frame != p.m_frame) return false;
|
Chris@1612
|
118
|
Chris@1612
|
119 if (m_haveValue != p.m_haveValue) return false;
|
Chris@1612
|
120 if (m_haveValue && (m_value != p.m_value)) return false;
|
Chris@1612
|
121
|
Chris@1612
|
122 if (m_duration != p.m_duration) return false;
|
Chris@1612
|
123
|
Chris@1612
|
124 if (m_haveLevel != p.m_haveLevel) return false;
|
Chris@1612
|
125 if (m_haveLevel && (m_level != p.m_level)) return false;
|
Chris@1612
|
126
|
Chris@1612
|
127 if (m_haveReferenceFrame != p.m_haveReferenceFrame) return false;
|
Chris@1612
|
128 if (m_haveReferenceFrame &&
|
Chris@1612
|
129 (m_referenceFrame != p.m_referenceFrame)) return false;
|
Chris@1612
|
130
|
Chris@1612
|
131 if (m_label != p.m_label) return false;
|
Chris@1612
|
132
|
Chris@1612
|
133 return true;
|
Chris@1612
|
134 }
|
Chris@1612
|
135
|
Chris@1612
|
136 bool operator<(const Point &p) const {
|
Chris@1612
|
137
|
Chris@1612
|
138 if (m_frame != p.m_frame) return m_frame < p.m_frame;
|
Chris@1612
|
139
|
Chris@1612
|
140 // points without a property sort before points with that property
|
Chris@1612
|
141
|
Chris@1612
|
142 if (m_haveValue != p.m_haveValue) return !m_haveValue;
|
Chris@1612
|
143 if (m_haveValue && (m_value != p.m_value)) return m_value < p.m_value;
|
Chris@1612
|
144
|
Chris@1612
|
145 if (m_duration != p.m_duration) return m_duration < p.m_duration;
|
Chris@1612
|
146
|
Chris@1612
|
147 if (m_haveLevel != p.m_haveLevel) return !m_haveLevel;
|
Chris@1612
|
148 if (m_haveLevel && (m_level != p.m_level)) return m_level < p.m_level;
|
Chris@1612
|
149
|
Chris@1612
|
150 if (m_haveReferenceFrame != p.m_haveReferenceFrame) {
|
Chris@1612
|
151 return !m_haveReferenceFrame;
|
Chris@1612
|
152 }
|
Chris@1612
|
153 if (m_haveReferenceFrame && (m_referenceFrame != p.m_referenceFrame)) {
|
Chris@1612
|
154 return m_referenceFrame < p.m_referenceFrame;
|
Chris@1612
|
155 }
|
Chris@1612
|
156
|
Chris@1612
|
157 return m_label < p.m_label;
|
Chris@1612
|
158 }
|
Chris@1612
|
159
|
Chris@1612
|
160 void toXml(QTextStream &stream,
|
Chris@1612
|
161 QString indent = "",
|
Chris@1612
|
162 QString extraAttributes = "") const {
|
Chris@1612
|
163
|
Chris@1612
|
164 stream << indent << QString("<point frame=\"%1\" ").arg(m_frame);
|
Chris@1612
|
165 if (m_haveValue) stream << QString("value=\"%1\" ").arg(m_value);
|
Chris@1612
|
166 if (m_duration) stream << QString("duration=\"%1\" ").arg(m_duration);
|
Chris@1612
|
167 if (m_haveLevel) stream << QString("level=\"%1\" ").arg(m_level);
|
Chris@1612
|
168 if (m_haveReferenceFrame) stream << QString("referenceFrame=\"%1\" ")
|
Chris@1612
|
169 .arg(m_referenceFrame);
|
Chris@1612
|
170 stream << QString("label=\"%1\" ")
|
Chris@1612
|
171 .arg(XmlExportable::encodeEntities(m_label));
|
Chris@1612
|
172 stream << extraAttributes << ">\n";
|
Chris@1612
|
173 }
|
Chris@1612
|
174
|
Chris@1612
|
175 QString toXmlString(QString indent = "",
|
Chris@1612
|
176 QString extraAttributes = "") const {
|
Chris@1612
|
177 QString s;
|
Chris@1612
|
178 QTextStream out(&s);
|
Chris@1612
|
179 toXml(out, indent, extraAttributes);
|
Chris@1612
|
180 out.flush();
|
Chris@1612
|
181 return s;
|
Chris@1612
|
182 }
|
Chris@1611
|
183
|
Chris@1611
|
184 private:
|
Chris@1611
|
185 // The order of fields here is chosen to minimise overall size of struct.
|
Chris@1612
|
186 // We potentially store very many of these objects.
|
Chris@1611
|
187 // If you change something, check what difference it makes to packing.
|
Chris@1611
|
188 bool m_haveValue : 1;
|
Chris@1611
|
189 bool m_haveLevel : 1;
|
Chris@1611
|
190 bool m_haveReferenceFrame : 1;
|
Chris@1611
|
191 float m_value;
|
Chris@1611
|
192 float m_level;
|
Chris@1611
|
193 sv_frame_t m_frame;
|
Chris@1611
|
194 sv_frame_t m_duration;
|
Chris@1611
|
195 sv_frame_t m_referenceFrame;
|
Chris@1611
|
196 QString m_label;
|
Chris@1611
|
197 };
|
Chris@1611
|
198
|
Chris@1612
|
199 typedef std::vector<Point> PointVector;
|
Chris@1612
|
200
|
Chris@1611
|
201 #endif
|