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 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 void Initialize(int numPoints);
83
84 virtual ~Envelope();
85
86 bool IsTrivial() const;
87
88 // Return true if violations of point ordering invariants were detected
89 // and repaired
90 bool ConsistencyCheck();
91
92 double GetOffset() const { return mOffset; }
93 double GetTrackLen() const { return mTrackLen; }
94
95 bool GetExponential() const { return mDB; }
96 void SetExponential(bool db) { mDB = db; }
97
98 void Flatten(double value);
99
100 double GetMinValue() const { return mMinValue; }
101 double GetMaxValue() const { return mMaxValue; }
102 void SetRange(double minValue, double maxValue);
103
104 double ClampValue(double value) { return std::max(mMinValue, std::min(mMaxValue, value)); }
105
106 // Newfangled XML file I/O
107 bool HandleXMLTag(const std::string_view& tag, const AttributesList& attrs) override;
108 XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
109 void WriteXML(XMLWriter &xmlFile) const /* not override */;
110
111 // Handling Cut/Copy/Paste events
112 // sampleDur determines when the endpoint of the collapse is near enough
113 // to an endpoint of the domain, that an extra control point is not needed.
114 void CollapseRegion(double t0, double t1, double sampleDur);
115
116 // Envelope has no notion of rate and control point times are not quantized;
117 // but a tolerance is needed in the Paste routine, and better to inform it
118 // of an appropriate number, than use hidden arbitrary constants.
119 // The function is called 'PasteEnvelope' rather than 'Paste' to make it
120 // easier to find where it is used in source code.
121 void PasteEnvelope(double t0, const Envelope *e, double sampleDur);
122
123 void InsertSpace(double t0, double tlen);
124
125 // Control
126 void SetOffset(double newOffset);
127 void SetTrackLen( double trackLen, double sampleDur = 0.0 );
128 void RescaleValues(double minValue, double maxValue);
129 void RescaleTimes( double newLength );
130 void RescaleTimesBy(double ratio);
131
132 // Accessors
134 double GetValue( double t, double sampleDur = 0 ) const;
135
140 void GetValues(double *buffer, int len, double t0, double tstep) const;
141
142 // Guarantee an envelope point at the end of the domain.
143 void Cap( double sampleDur );
144
145private:
146 std::pair< int, int > ExpandRegion
147 ( double t0, double tlen, double *pLeftVal, double *pRightVal );
148
149 void RemoveUnneededPoints
150 ( size_t startAt, bool rightward, bool testNeighbors = true );
151
152 double GetValueRelative(double t, bool leftLimit = false) const;
153 void GetValuesRelative
154 (double *buffer, int len, double t0, double tstep, bool leftLimit = false)
155 const;
156 // relative time
157 int NumberOfPointsAfter(double t) const;
158 // relative time
159 double NextPointAfter(double t) const;
160
161public:
162 double Average( double t0, double t1 ) const;
163 double AverageOfInverse( double t0, double t1 ) const;
164 double Integral( double t0, double t1 ) const;
165 double IntegralOfInverse( double t0, double t1 ) const;
166 double SolveIntegralOfInverse( double t0, double area) const;
167
168 void print() const;
169 void testMe();
170
171 bool IsDirty() const;
172
173 void Clear() { mEnv.clear(); }
174
176 int InsertOrReplace(double when, double value)
177 { return InsertOrReplaceRelative( when - mOffset, value ); }
178
182 int Reassign(double when, double value);
183
185 void Delete(int point);
186
188 void Insert(int point, const EnvPoint &p);
189
190 // Insert a point (without replacement)
191 // for now assumed sequential.
192 void Insert(double when, double value);
193
195 size_t GetNumberOfPoints() const;
196
198 const EnvPoint &operator[] (int index) const
199 {
200 return mEnv[index];
201 }
202
203private:
204 int InsertOrReplaceRelative(double when, double value);
205
206 std::pair<int, int> EqualRange( double when, double sampleDur ) const;
207
208public:
210 void GetPoints(double *bufferWhen,
211 double *bufferValue,
212 int bufferLen) const;
213
214 // UI-related
215 // The drag point needs to display differently.
216 int GetDragPoint() const { return mDragPoint; }
217 // Choose the drag point.
218 void SetDragPoint(int dragPoint);
219 // Mark or unmark the drag point for deletion.
220 void SetDragPointValid(bool valid);
221 bool GetDragPointValid() const { return mDragPointValid; }
222 // Modify the dragged point and change its value.
223 // But consistency constraints may move it less then you ask for.
224 void MoveDragPoint(double newWhen, double value);
225 // May delete the drag point. Restores envelope consistency.
226 void ClearDragPoint();
227
228private:
229 void AddPointAtEnd( double t, double val );
230 void CopyRange(const Envelope &orig, size_t begin, size_t end);
231 // relative time
232 void BinarySearchForTime( int &Lo, int &Hi, double t ) const;
233 void BinarySearchForTime_LeftLimit( int &Lo, int &Hi, double t ) const;
234 double GetInterpolationStartValueAtPoint( int iPoint ) const;
235
236 // The list of envelope control points.
238
240 double mOffset { 0.0 };
243 double mTrackLen { 0.0 };
244
245 // TODO: mTrackEpsilon based on assumption of 200KHz. Needs review if/when
246 // we support higher sample rates.
249 double mTrackEpsilon { 1.0 / 200000.0 };
250 bool mDB;
251 double mMinValue, mMaxValue;
253
254 // UI stuff
255 bool mDragPointValid { false };
256 int mDragPoint { -1 };
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
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: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:92
void Clear()
Definition: Envelope.h:173
bool mDB
Definition: Envelope.h:250
int InsertOrReplace(double when, double value)
Add a point at a particular absolute time coordinate.
Definition: Envelope.h:176
bool GetExponential() const
Definition: Envelope.h:95
double ClampValue(double value)
Definition: Envelope.h:104
bool IsDirty() const
double mDefaultValue
Definition: Envelope.h:252
void Initialize(int numPoints)
double GetTrackLen() const
Definition: Envelope.h:93
double GetMaxValue() const
Definition: Envelope.h:101
void SetExponential(bool db)
Definition: Envelope.h:96
double mMaxValue
Definition: Envelope.h:251
int GetDragPoint() const
Definition: Envelope.h:216
EnvArray mEnv
Definition: Envelope.h:237
bool GetDragPointValid() const
Definition: Envelope.h:221
double GetMinValue() const
Definition: Envelope.h:100
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
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