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