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:
33 inline EnvPoint( double t, double val ) : mT{ t }, mVal{ val } {}
34
35 double GetT() const { return mT; }
36 void SetT(double t) { mT = t; }
37 double GetVal() const { 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 TRACK_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 void Initialize(int numPoints);
83
84 virtual ~Envelope();
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);
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
129 // Accessors
131 double GetValue( double t, double sampleDur = 0 ) const;
132
137 void GetValues(double *buffer, int len, double t0, double tstep) const;
138
139 // Guarantee an envelope point at the end of the domain.
140 void Cap( double sampleDur );
141
142private:
143 std::pair< int, int > ExpandRegion
144 ( double t0, double tlen, double *pLeftVal, double *pRightVal );
145
146 void RemoveUnneededPoints
147 ( size_t startAt, bool rightward, bool testNeighbors = true );
148
149 double GetValueRelative(double t, bool leftLimit = false) const;
150 void GetValuesRelative
151 (double *buffer, int len, double t0, double tstep, bool leftLimit = false)
152 const;
153 // relative time
154 int NumberOfPointsAfter(double t) const;
155 // relative time
156 double NextPointAfter(double t) const;
157
158public:
159 double Average( double t0, double t1 ) const;
160 double AverageOfInverse( double t0, double t1 ) const;
161 double Integral( double t0, double t1 ) const;
162 double IntegralOfInverse( double t0, double t1 ) const;
163 double SolveIntegralOfInverse( double t0, double area) const;
164
165 void print() const;
166 void testMe();
167
168 bool IsDirty() const;
169
170 void Clear() { mEnv.clear(); }
171
173 int InsertOrReplace(double when, double value)
174 { return InsertOrReplaceRelative( when - mOffset, value ); }
175
179 int Reassign(double when, double value);
180
182 void Delete(int point);
183
185 void Insert(int point, const EnvPoint &p);
186
187 // Insert a point (without replacement)
188 // for now assumed sequential.
189 void Insert(double when, double value);
190
192 size_t GetNumberOfPoints() const;
193
195 const EnvPoint &operator[] (int index) const
196 {
197 return mEnv[index];
198 }
199
200private:
201 int InsertOrReplaceRelative(double when, double value);
202
203 std::pair<int, int> EqualRange( double when, double sampleDur ) const;
204
205public:
207 void GetPoints(double *bufferWhen,
208 double *bufferValue,
209 int bufferLen) const;
210
211 // UI-related
212 // The drag point needs to display differently.
213 int GetDragPoint() const { return mDragPoint; }
214 // Choose the drag point.
215 void SetDragPoint(int dragPoint);
216 // Mark or unmark the drag point for deletion.
217 void SetDragPointValid(bool valid);
218 bool GetDragPointValid() const { return mDragPointValid; }
219 // Modify the dragged point and change its value.
220 // But consistency constraints may move it less then you ask for.
221 void MoveDragPoint(double newWhen, double value);
222 // May delete the drag point. Restores envelope consistency.
223 void ClearDragPoint();
224
225private:
226 void AddPointAtEnd( double t, double val );
227 void CopyRange(const Envelope &orig, size_t begin, size_t end);
228 // relative time
229 void BinarySearchForTime( int &Lo, int &Hi, double t ) const;
230 void BinarySearchForTime_LeftLimit( int &Lo, int &Hi, double t ) const;
231 double GetInterpolationStartValueAtPoint( int iPoint ) const;
232
233 // The list of envelope control points.
235
237 double mOffset { 0.0 };
240 double mTrackLen { 0.0 };
241
242 // TODO: mTrackEpsilon based on assumption of 200KHz. Needs review if/when
243 // we support higher sample rates.
246 double mTrackEpsilon { 1.0 / 200000.0 };
247 bool mDB;
248 double mMinValue, mMaxValue;
250
251 // UI stuff
252 bool mDragPointValid { false };
253 int mDragPoint { -1 };
254
255 mutable int mSearchGuess { -2 };
256};
257
258inline void EnvPoint::SetVal( Envelope *pEnvelope, double val )
259{
260 if ( pEnvelope )
261 val = pEnvelope->ClampValue(val);
262 mVal = val;
263}
264
265/*
266PRL: This class gives access to all the important numerical data in a TimeTrack,
267without need for the entire TimeTrack.
268
269Confusingly, Envelope already carried its own limiting values, but those
270in the TimeTrack were not guaranteed to be the same.
271
272I'm just preserving behavior as I break file dependencies and won't try to fix
273that confusion now.
274*/
275class BoundedEnvelope final : public Envelope
276{
277public:
278 using Envelope::Envelope;
279
280 double GetRangeLower() const { return mRangeLower; }
281 double GetRangeUpper() const { return mRangeUpper; }
282
283 void SetRangeLower(double lower) { mRangeLower = lower; }
284 void SetRangeUpper(double upper) { mRangeUpper = upper; }
285
286private:
288};
289
290#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:287
double GetRangeUpper() const
Definition: Envelope.h:281
void SetRangeUpper(double upper)
Definition: Envelope.h:284
double mRangeUpper
Definition: Envelope.h:287
double GetRangeLower() const
Definition: Envelope.h:280
void SetRangeLower(double lower)
Definition: Envelope.h:283
EnvPoint, derived from XMLTagHandler, provides Envelope with a draggable point type.
Definition: Envelope.h:29
double mT
Definition: Envelope.h:64
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
Definition: Envelope.h:40
EnvPoint()
Definition: Envelope.h:32
double GetVal() const
Definition: Envelope.h:37
XMLTagHandler * HandleXMLChild(const std::string_view &WXUNUSED(tag)) override
Definition: Envelope.h:58
double GetT() const
Definition: Envelope.h:35
EnvPoint(double t, double val)
Definition: Envelope.h:33
double mVal
Definition: Envelope.h:65
void SetT(double t)
Definition: Envelope.h:36
void SetVal(Envelope *pEnvelope, double val)
Definition: Envelope.h:258
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:43
double GetOffset() const
Definition: Envelope.h:90
void Clear()
Definition: Envelope.h:170
bool mDB
Definition: Envelope.h:247
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:173
bool GetExponential() const
Definition: Envelope.h:93
double ClampValue(double value)
Definition: Envelope.h:102
bool IsDirty() const
double mDefaultValue
Definition: Envelope.h:249
void Initialize(int numPoints)
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:248
int GetDragPoint() const
Definition: Envelope.h:213
EnvArray mEnv
Definition: Envelope.h:234
bool GetDragPointValid() const
Definition: Envelope.h:218
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:26
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150