Audacity 3.2.0
Envelope.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Envelope.h
6
7 Dominic Mazzoni
8
9**********************************************************************/
10
11#ifndef __AUDACITY_ENVELOPE__
12#define __AUDACITY_ENVELOPE__
13
14#include <stdlib.h>
15#include <algorithm>
16#include <vector>
17
18#include "XMLTagHandler.h"
19
20class wxRect;
21class wxMouseEvent;
22class wxTextFile;
23
24class Envelope;
25class EnvPoint;
26
27class ZoomInfo;
28
29class EnvPoint final : public XMLTagHandler {
30
31public:
32 EnvPoint() noexcept {}
33 inline EnvPoint( double t, double val ) noexcept : mT{ t }, mVal{ val } {}
34
35 double GetT() const noexcept { return mT; }
36 void SetT(double t) noexcept { mT = t; }
37 double GetVal() const noexcept { return mVal; }
38 inline void SetVal( Envelope *pEnvelope, double val );
39
40 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override
41 {
42 if (tag == "controlpoint") {
43 for(auto pair : attrs) {
44 auto attr = pair.first;
45 auto value = pair.second;
46
47 if (attr == "t")
48 SetT(value.Get(GetT()));
49 else if (attr == "val")
50 SetVal(nullptr, value.Get(GetVal()));
51 }
52 return true;
53 }
54 else
55 return false;
56 }
57
58 XMLTagHandler *HandleXMLChild(const std::string_view& WXUNUSED(tag)) override
59 {
60 return NULL;
61 }
62
63private:
64 double mT {};
65 double mVal {};
66
67};
68
69typedef std::vector<EnvPoint> EnvArray;
71
72class MIXER_API Envelope /* not final */ : public XMLTagHandler {
73public:
74 // Envelope can define a piecewise linear function, or piecewise exponential.
75 Envelope(bool exponential, double minValue, double maxValue, double defaultValue);
76
77 Envelope(const Envelope &orig);
78
79 // Create from a subrange of another envelope.
80 Envelope(const Envelope &orig, double t0, double t1);
81
82 virtual ~Envelope();
83
84 bool IsTrivial() const;
85
86 // Return true if violations of point ordering invariants were detected
87 // and repaired
88 bool ConsistencyCheck();
89
90 double GetOffset() const { return mOffset; }
91 double GetTrackLen() const { return mTrackLen; }
92
93 bool GetExponential() const { return mDB; }
94 void SetExponential(bool db) { mDB = db; }
95
96 void Flatten(double value);
97
98 double GetMinValue() const { return mMinValue; }
99 double GetMaxValue() const { return mMaxValue; }
100 void SetRange(double minValue, double maxValue);
101
102 double ClampValue(double value) { return std::max(mMinValue, std::min(mMaxValue, value)); }
103
104 // Newfangled XML file I/O
105 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
106 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
107 void WriteXML(XMLWriter &xmlFile) const /* not override */;
108
109 // Handling Cut/Copy/Paste events
110 // sampleDur determines when the endpoint of the collapse is near enough
111 // to an endpoint of the domain, that an extra control point is not needed.
112 void CollapseRegion(double t0, double t1, double sampleDur) noexcept;
113
114 // Envelope has no notion of rate and control point times are not quantized;
115 // but a tolerance is needed in the Paste routine, and better to inform it
116 // of an appropriate number, than use hidden arbitrary constants.
117 // The function is called 'PasteEnvelope' rather than 'Paste' to make it
118 // easier to find where it is used in source code.
119 void PasteEnvelope(double t0, const Envelope *e, double sampleDur);
120
121 void InsertSpace(double t0, double tlen);
122
123 // Control
124 void SetOffset(double newOffset);
125 void SetTrackLen( double trackLen, double sampleDur = 0.0 );
126 void RescaleValues(double minValue, double maxValue);
127 void RescaleTimes( double newLength );
128 void RescaleTimesBy(double ratio);
129
130 // Accessors
132 double GetValue( double t, double sampleDur = 0 ) const;
133
138 void GetValues(double *buffer, int len, double t0, double tstep) const;
139
140 // Guarantee an envelope point at the end of the domain.
141 void Cap( double sampleDur );
142
143private:
144 std::pair< int, int > ExpandRegion
145 ( double t0, double tlen, double *pLeftVal, double *pRightVal );
146
147 void RemoveUnneededPoints
148 ( size_t startAt, bool rightward, bool testNeighbors = true ) noexcept;
149
150 double GetValueRelative(double t, bool leftLimit = false) const noexcept;
151 void GetValuesRelative
152 (double *buffer, int len, double t0, double tstep, bool leftLimit = false)
153 const noexcept;
154 // relative time
155 int NumberOfPointsAfter(double t) const;
156 // relative time
157 double NextPointAfter(double t) const;
158
159public:
160 double Average( double t0, double t1 ) const;
161 double AverageOfInverse( double t0, double t1 ) const;
162 double Integral( double t0, double t1 ) const;
163 double IntegralOfInverse( double t0, double t1 ) const;
164 double SolveIntegralOfInverse( double t0, double area) const;
165
166 void Clear() { mEnv.clear(); }
167
169 int InsertOrReplace(double when, double value)
170 { return InsertOrReplaceRelative( when - mOffset, value ); }
171
175 int Reassign(double when, double value);
176
178 void Delete(int point);
179
181 void Insert(int point, const EnvPoint &p) noexcept;
182
183 // Insert a point (without replacement)
184 // for now assumed sequential.
185 void Insert(double when, double value);
186
188 size_t GetNumberOfPoints() const;
189
191 const EnvPoint &operator[] (int index) const
192 {
193 return mEnv[index];
194 }
195
196 double GetDefaultValue() const;
197
198 size_t GetVersion() const;
199
200
201private:
202 int InsertOrReplaceRelative(double when, double value) noexcept;
203
204 std::pair<int, int> EqualRange(double when, double sampleDur) const noexcept;
205
206public:
208 void GetPoints(double *bufferWhen,
209 double *bufferValue,
210 int bufferLen) const;
211
212 // UI-related
213 // The drag point needs to display differently.
214 int GetDragPoint() const { return mDragPoint; }
215 // Choose the drag point.
216 void SetDragPoint(int dragPoint);
217 // Mark or unmark the drag point for deletion.
218 void SetDragPointValid(bool valid);
219 bool GetDragPointValid() const { return mDragPointValid; }
220 // Modify the dragged point and change its value.
221 // But consistency constraints may move it less then you ask for.
222 void MoveDragPoint(double newWhen, double value);
223 // May delete the drag point. Restores envelope consistency.
224 void ClearDragPoint();
225
226private:
227 void AddPointAtEnd( double t, double val );
228 void CopyRange(const Envelope &orig, size_t begin, size_t end);
229 // relative time
230 void BinarySearchForTime(int &Lo, int &Hi, double t) const noexcept;
231 void BinarySearchForTime_LeftLimit(int &Lo, int &Hi, double t)
232 const noexcept;
233 double GetInterpolationStartValueAtPoint(int iPoint) const noexcept;
234
235 // The list of envelope control points.
237
239 double mOffset { 0.0 };
242 double mTrackLen { 0.0 };
243
244 // TODO: mTrackEpsilon based on assumption of 200KHz. Needs review if/when
245 // we support higher sample rates.
248 double mTrackEpsilon { 1.0 / 200000.0 };
249 bool mDB;
250 double mMinValue, mMaxValue;
252
253 // UI stuff
254 bool mDragPointValid { false };
255 int mDragPoint { -1 };
256 size_t mVersion { 0 };
257
258 mutable int mSearchGuess { -2 };
259};
260
261inline void EnvPoint::SetVal( Envelope *pEnvelope, double val )
262{
263 if ( pEnvelope )
264 val = pEnvelope->ClampValue(val);
265 mVal = val;
266}
267
268/*
269PRL: This class gives access to all the important numerical data in a TimeTrack,
270without need for the entire TimeTrack.
271
272Confusingly, Envelope already carried its own limiting values, but those
273in the TimeTrack were not guaranteed to be the same.
274
275I'm just preserving behavior as I break file dependencies and won't try to fix
276that confusion now.
277*/
278class BoundedEnvelope final : public Envelope
279{
280public:
281 using Envelope::Envelope;
282
283 double GetRangeLower() const { return mRangeLower; }
284 double GetRangeUpper() const { return mRangeUpper; }
285
286 void SetRangeLower(double lower) { mRangeLower = lower; }
287 void SetRangeUpper(double upper) { mRangeUpper = upper; }
288
289private:
291};
292
293#endif
int min(int a, int b)
std::vector< EnvPoint > EnvArray
Definition: Envelope.h:69
std::vector< Attribute > AttributesList
Definition: XMLTagHandler.h:40
double mRangeLower
Definition: Envelope.h:290
double GetRangeUpper() const
Definition: Envelope.h:284
void SetRangeUpper(double upper)
Definition: Envelope.h:287
double mRangeUpper
Definition: Envelope.h:290
double GetRangeLower() const
Definition: Envelope.h:283
void SetRangeLower(double lower)
Definition: Envelope.h:286
EnvPoint, derived from XMLTagHandler, provides Envelope with a draggable point type.
Definition: Envelope.h:29
EnvPoint(double t, double val) noexcept
Definition: Envelope.h:33
double mT
Definition: Envelope.h:64
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: Envelope.h:40
XMLTagHandler * HandleXMLChild(const std::string_view &WXUNUSED(tag)) override
Definition: Envelope.h:58
double GetT() const noexcept
Definition: Envelope.h:35
double mVal
Definition: Envelope.h:65
void SetT(double t) noexcept
Definition: Envelope.h:36
EnvPoint() noexcept
Definition: Envelope.h:32
double GetVal() const noexcept
Definition: Envelope.h:37
void SetVal(Envelope *pEnvelope, double val)
Definition: Envelope.h:261
Piecewise linear or piecewise exponential function from double to double.
Definition: Envelope.h:72
Envelope(bool exponential, double minValue, double maxValue, double defaultValue)
Definition: Envelope.cpp:44
double GetOffset() const
Definition: Envelope.h:90
bool mDB
Definition: Envelope.h:249
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:169
bool GetExponential() const
Definition: Envelope.h:93
double ClampValue(double value)
Definition: Envelope.h:102
double mDefaultValue
Definition: Envelope.h:251
double GetTrackLen() const
Definition: Envelope.h:91
double GetMaxValue() const
Definition: Envelope.h:99
void SetExponential(bool db)
Definition: Envelope.h:94
double mMaxValue
Definition: Envelope.h:250
int GetDragPoint() const
Definition: Envelope.h:214
EnvArray mEnv
Definition: Envelope.h:236
bool GetDragPointValid() const
Definition: Envelope.h:219
double GetMinValue() const
Definition: Envelope.h:98
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42
virtual XMLTagHandler * HandleXMLChild(const std::string_view &tag)=0
virtual bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs)=0
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101