Audacity 3.2.0
SelectedRegion.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 SelectedRegion.h
6
7 Dominic Mazzoni
8
9*******************************************************************//****************************************************************/
25#ifndef __AUDACITY_SELECTEDREGION__
26#define __AUDACITY_SELECTEDREGION__
27
28#include <wx/defs.h>
29#include <wx/chartype.h> // for wxChar, a typedef
30#include <math.h>
31#include <string_view>
32
33#include "XMLMethodRegistry.h"
34
35class XMLWriter;
37
38class SCREEN_GEOMETRY_API SelectedRegion {
39
40 // Maintains the invariant: t1() >= t0()
41
42public:
43
44 static const int UndefinedFrequency = -1;
45
47 : mT0(0.0)
48 , mT1(0.0)
49#ifdef EXPERIMENTAL_SPECTRAL_EDITING
50 , mF0(UndefinedFrequency)
51 , mF1(UndefinedFrequency)
52#endif
53 {}
54
55 SelectedRegion(double t0, double t1)
56 : mT0(t0)
57 , mT1(t1)
58#ifdef EXPERIMENTAL_SPECTRAL_EDITING
59 , mF0(UndefinedFrequency)
60 , mF1(UndefinedFrequency)
61#endif
62 { ensureOrdering(); }
63
64
65 // LLL: 2014/10/6
66 // Removed "explicit" until we drop OSX PPC support and upgrade to a newer
67 // compiler.
68 //
69 // explicit
71 : mT0(x.mT0)
72 , mT1(x.mT1)
73#ifdef EXPERIMENTAL_SPECTRAL_EDITING
74 , mF0(x.mF0)
75 , mF1(x.mF1)
76#endif
77 {}
78
80 {
81 if (this != &x) {
82 mT0 = x.mT0;
83 mT1 = x.mT1;
84#ifdef EXPERIMENTAL_SPECTRAL_EDITING
85 mF0 = x.mF0;
86 mF1 = x.mF1;
87#endif
88 }
89 return *this;
90 }
91
92 // Accessors
93
94 double t0() const { return mT0; }
95 double t1() const { return mT1; }
96 double duration() const { return mT1 - mT0; }
97 bool isPoint() const { return mT1 <= mT0; }
98
99#ifdef EXPERIMENTAL_SPECTRAL_EDITING
100 double f0() const { return mF0; }
101 double f1() const { return mF1; }
102 double fc() const {
103 if (mF0 == UndefinedFrequency ||
104 mF1 == UndefinedFrequency)
105 return UndefinedFrequency;
106 else
107 return sqrt(mF0 * mF1);
108 };
109#endif
110
111 // Mutators
112 // PRL: to do: more integrity checks
113
114 // Returns true iff the bounds got swapped
115 bool setT0(double t, bool maySwap = true) {
116 mT0 = t;
117 if (maySwap)
118 return ensureOrdering();
119 else {
120 if (mT1 < mT0)
121 mT1 = mT0;
122 return false;
123 }
124 }
125
126 // Returns true iff the bounds got swapped
127 bool setT1(double t, bool maySwap = true) {
128 mT1 = t;
129 if (maySwap)
130 return ensureOrdering();
131 else {
132 if (mT1 < mT0)
133 mT0 = mT1;
134 return false;
135 }
136 }
137
138 // Returns true iff the bounds got swapped
139 bool setTimes(double t0, double t1) {
140 mT0 = t0;
141 mT1 = t1;
142 return ensureOrdering();
143 }
144
145 // Returns true iff the bounds got swapped
146 bool moveT0(double delta, bool maySwap = true) {
147 return setT0(mT0 + delta, maySwap);
148 }
149
150 // Returns true iff the bounds got swapped
151 bool moveT1(double delta, bool maySwap = true) {
152 return setT1(mT1 + delta, maySwap);
153 }
154
155 void move(double delta) {
156 mT0 += delta;
157 mT1 += delta;
158 }
159
160 void collapseToT0() { mT1 = mT0; }
161
162 void collapseToT1() { mT0 = mT1; }
163
164#ifdef EXPERIMENTAL_SPECTRAL_EDITING
165 // Returns true iff the bounds got swapped
166 bool setF0(double f, bool maySwap = true) {
167 if (f < 0)
168 f = UndefinedFrequency;
169 mF0 = f;
170 if (maySwap)
171 return ensureFrequencyOrdering();
172 else {
173 if (mF1 >= 0 && mF1 < mF0)
174 mF1 = mF0;
175 return false;
176 }
177 }
178
179 // Returns true iff the bounds got swapped
180 bool setF1(double f, bool maySwap = true) {
181 if (f < 0)
182 f = UndefinedFrequency;
183 mF1 = f;
184 if (maySwap)
185 return ensureFrequencyOrdering();
186 else {
187 if (mF0 >= 0 && mF1 < mF0)
188 mF0 = mF1;
189 return false;
190 }
191 }
192
193 // Returns true iff the bounds got swapped
194 bool setFrequencies(double f0, double f1)
195 {
196 mF0 = f0;
197 mF1 = f1;
198 return ensureFrequencyOrdering();
199 }
200#endif
201
202 // Serialization: historically, selections were written to file
203 // in two places (project, and each label) but only as attributes
204 // in the tags, and different names were used in the two places.
205 // For compatibility, continue that, but possibly add attributes
206 // as SelectedRegion is extended. Therefore, this is not an
207 // XMLTagHandler.
208
209 static const char* sDefaultT0Name;
210 static const char* sDefaultT1Name;
211
212 // Serialize, not with tags of its own, but as attributes within a tag.
213 // Don't add more legacy arguments as the structure grows.
214 void WriteXMLAttributes
215 (XMLWriter &xmlFile,
216 const char *legacyT0Name = sDefaultT0Name,
217 const char *legacyT1Name = sDefaultT1Name) const;
218
219 // Return true iff the attribute is recognized.
220 // Don't add more legacy arguments as the structure grows.
221 bool HandleXMLAttribute
222 (const std::string_view &attr, const XMLAttributeValueView &value,
223 const char *legacyT0Name = sDefaultT0Name,
224 const char* legacyT1Name = sDefaultT1Name);
225
226 /*
227 This function encapsulates details of serialization of
228 SelectedRegion. It was serialized with differing attribute values in
229 different contexts, for reasons of history.
230 */
232 Mutators(
233 const char *legacyT0Name, const char* legacyT1Name);
234
236 {
237 if (mT1 < mT0) {
238 const double t = mT1;
239 mT1 = mT0;
240 mT0 = t;
241 return true;
242 }
243 else
244 return false;
245 }
246
247private:
248
249#ifdef EXPERIMENTAL_SPECTRAL_EDITING
250 bool ensureFrequencyOrdering()
251 {
252 if (mF1 < 0)
253 mF1 = UndefinedFrequency;
254 if (mF0 < 0)
255 mF0 = UndefinedFrequency;
256
257 if (mF0 != UndefinedFrequency &&
258 mF1 != UndefinedFrequency &&
259 mF1 < mF0) {
260 const double t = mF1;
261 mF1 = mF0;
262 mF0 = t;
263 return true;
264 }
265 else
266 return false;
267 }
268#endif
269
270 friend inline bool operator ==
271 (const SelectedRegion &lhs, const SelectedRegion &rhs)
272 {
273 return
274 lhs.mT0 == rhs.mT0
275 && lhs.mT1 == rhs.mT1
276#ifdef EXPERIMENTAL_SPECTRAL_EDITING
277 && lhs.mF0 == rhs.mF0
278 && lhs.mF1 == rhs.mF1
279#endif
280 ;
281 }
282
283 double mT0;
284 double mT1;
285#ifdef EXPERIMENTAL_SPECTRAL_EDITING
286 double mF0; // low frequency
287 double mF1; // high frequency
288#endif
289
290};
291
292inline bool operator != (const SelectedRegion &lhs, const SelectedRegion &rhs)
293{
294 return !(lhs == rhs);
295}
296
297#endif
bool operator!=(const SelectedRegion &lhs, const SelectedRegion &rhs)
Defines a selected portion of a project.
double t1() const
SelectedRegion & operator=(const SelectedRegion &x)
bool moveT0(double delta, bool maySwap=true)
bool setTimes(double t0, double t1)
SelectedRegion(double t0, double t1)
SelectedRegion(const SelectedRegion &x)
bool isPoint() const
static const char * sDefaultT1Name
static const char * sDefaultT0Name
double t0() const
double duration() const
bool moveT1(double delta, bool maySwap=true)
bool setT0(double t, bool maySwap=true)
bool setT1(double t, bool maySwap=true)
void move(double delta)
A view into an attribute value. The class does not take the ownership of the data.
std::vector< std::pair< std::string, Mutator< Substructure > > > Mutators
A helper type alias for a list of mutators, associated with tag strings.
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:26