Audacity 3.2.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
Envelope Class Reference

Piecewise linear or piecewise exponential function from double to double. More...

#include <Envelope.h>

Inheritance diagram for Envelope:
[legend]
Collaboration diagram for Envelope:
[legend]

Public Member Functions

 Envelope (bool exponential, double minValue, double maxValue, double defaultValue)
 
 Envelope (const Envelope &orig)
 
 Envelope (const Envelope &orig, double t0, double t1)
 
void Initialize (int numPoints)
 
virtual ~Envelope ()
 
bool IsTrivial () const
 
bool ConsistencyCheck ()
 
double GetOffset () const
 
double GetTrackLen () const
 
bool GetExponential () const
 
void SetExponential (bool db)
 
void Flatten (double value)
 
double GetMinValue () const
 
double GetMaxValue () const
 
void SetRange (double minValue, double maxValue)
 
double ClampValue (double value)
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void WriteXML (XMLWriter &xmlFile) const
 
void CollapseRegion (double t0, double t1, double sampleDur)
 
void PasteEnvelope (double t0, const Envelope *e, double sampleDur)
 
void InsertSpace (double t0, double tlen)
 
void SetOffset (double newOffset)
 
void SetTrackLen (double trackLen, double sampleDur=0.0)
 
void RescaleValues (double minValue, double maxValue)
 
void RescaleTimes (double newLength)
 
void RescaleTimesBy (double ratio)
 
double GetValue (double t, double sampleDur=0) const
 Get envelope value at time t. More...
 
void GetValues (double *buffer, int len, double t0, double tstep) const
 Get many envelope points at once. More...
 
void Cap (double sampleDur)
 
double Average (double t0, double t1) const
 
double AverageOfInverse (double t0, double t1) const
 
double Integral (double t0, double t1) const
 
double IntegralOfInverse (double t0, double t1) const
 
double SolveIntegralOfInverse (double t0, double area) const
 
void print () const
 
void testMe ()
 
bool IsDirty () const
 
void Clear ()
 
int InsertOrReplace (double when, double value)
 Add a point at a particular absolute time coordinate. More...
 
int Reassign (double when, double value)
 Move a point at when to value. More...
 
void Delete (int point)
 DELETE a point by its position in array. More...
 
void Insert (int point, const EnvPoint &p)
 insert a point More...
 
void Insert (double when, double value)
 
size_t GetNumberOfPoints () const
 Return number of points. More...
 
const EnvPointoperator[] (int index) const
 Accessor for points. More...
 
void GetPoints (double *bufferWhen, double *bufferValue, int bufferLen) const
 Returns the sets of when and value pairs. More...
 
int GetDragPoint () const
 
void SetDragPoint (int dragPoint)
 
void SetDragPointValid (bool valid)
 
bool GetDragPointValid () const
 
void MoveDragPoint (double newWhen, double value)
 
void ClearDragPoint ()
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 

Private Member Functions

std::pair< int, int > ExpandRegion (double t0, double tlen, double *pLeftVal, double *pRightVal)
 
void RemoveUnneededPoints (size_t startAt, bool rightward, bool testNeighbors=true)
 
double GetValueRelative (double t, bool leftLimit=false) const
 
void GetValuesRelative (double *buffer, int len, double t0, double tstep, bool leftLimit=false) const
 
int NumberOfPointsAfter (double t) const
 
double NextPointAfter (double t) const
 
int InsertOrReplaceRelative (double when, double value)
 Add a control point to the envelope. More...
 
std::pair< int, int > EqualRange (double when, double sampleDur) const
 
void AddPointAtEnd (double t, double val)
 
void CopyRange (const Envelope &orig, size_t begin, size_t end)
 
void BinarySearchForTime (int &Lo, int &Hi, double t) const
 
void BinarySearchForTime_LeftLimit (int &Lo, int &Hi, double t) const
 
double GetInterpolationStartValueAtPoint (int iPoint) const
 

Private Attributes

EnvArray mEnv
 
double mOffset { 0.0 }
 The time at which the envelope starts, i.e. the start offset. More...
 
double mTrackLen { 0.0 }
 The length of the envelope, which is the same as the length of the underlying track (normally) More...
 
double mTrackEpsilon { 1.0 / 200000.0 }
 The shortest distance apart that points on an envelope can be before being considered the same point. More...
 
bool mDB
 
double mMinValue
 
double mMaxValue
 
double mDefaultValue
 
bool mDragPointValid { false }
 
int mDragPoint { -1 }
 
int mSearchGuess { -2 }
 

Detailed Description

Piecewise linear or piecewise exponential function from double to double.

This class manages an envelope - i.e. a function that the user can edit by dragging control points around. The envelope is most commonly used to control the amplitude of a waveform, but it is also used to shape the Equalization curve, and in TimeTrack to determine a time warp.

Definition at line 72 of file Envelope.h.

Constructor & Destructor Documentation

◆ Envelope() [1/3]

Envelope::Envelope ( bool  exponential,
double  minValue,
double  maxValue,
double  defaultValue 
)

Definition at line 44 of file Envelope.cpp.

45 : mDB(exponential)
46 , mMinValue(minValue)
47 , mMaxValue(maxValue)
48 , mDefaultValue { ClampValue(defaultValue) }
49{
50}
double mMinValue
Definition: Envelope.h:251
bool mDB
Definition: Envelope.h:250
double ClampValue(double value)
Definition: Envelope.h:104
double mDefaultValue
Definition: Envelope.h:252
double mMaxValue
Definition: Envelope.h:251

◆ Envelope() [2/3]

Envelope::Envelope ( const Envelope orig)

Definition at line 263 of file Envelope.cpp.

264 : mDB(orig.mDB)
265 , mMinValue(orig.mMinValue)
266 , mMaxValue(orig.mMaxValue)
268{
269 mOffset = orig.mOffset;
270 mTrackLen = orig.mTrackLen;
271 CopyRange(orig, 0, orig.GetNumberOfPoints());
272}
double mOffset
The time at which the envelope starts, i.e. the start offset.
Definition: Envelope.h:240
size_t GetNumberOfPoints() const
Return number of points.
Definition: Envelope.cpp:695
double mTrackLen
The length of the envelope, which is the same as the length of the underlying track (normally)
Definition: Envelope.h:243
void CopyRange(const Envelope &orig, size_t begin, size_t end)
Definition: Envelope.cpp:274

References CopyRange(), GetNumberOfPoints(), mOffset, and mTrackLen.

Here is the call graph for this function:

◆ Envelope() [3/3]

Envelope::Envelope ( const Envelope orig,
double  t0,
double  t1 
)

Definition at line 249 of file Envelope.cpp.

250 : mDB(orig.mDB)
251 , mMinValue(orig.mMinValue)
252 , mMaxValue(orig.mMaxValue)
254{
255 mOffset = wxMax(t0, orig.mOffset);
256 mTrackLen = wxMin(t1, orig.mOffset + orig.mTrackLen) - mOffset;
257
258 auto range1 = orig.EqualRange( t0 - orig.mOffset, 0 );
259 auto range2 = orig.EqualRange( t1 - orig.mOffset, 0 );
260 CopyRange(orig, range1.first, range2.second);
261}
std::pair< int, int > EqualRange(double when, double sampleDur) const
Definition: Envelope.cpp:763

References CopyRange(), EqualRange(), mOffset, and mTrackLen.

Here is the call graph for this function:

◆ ~Envelope()

Envelope::~Envelope ( )
virtual

Definition at line 52 of file Envelope.cpp.

53{
54}

Member Function Documentation

◆ AddPointAtEnd()

void Envelope::AddPointAtEnd ( double  t,
double  val 
)
private

Definition at line 232 of file Envelope.cpp.

233{
234 mEnv.push_back( EnvPoint{ t, val } );
235
236 // Assume copied points were stored by nondecreasing time.
237 // Allow no more than two points at exactly the same time.
238 // Maybe that happened, because extra points were inserted at the boundary
239 // of the copied range, which were not in the source envelope.
240 auto nn = mEnv.size() - 1;
241 while ( nn >= 2 && mEnv[ nn - 2 ].GetT() == t ) {
242 // Of three or more points at the same time, erase one in the middle,
243 // not the one newly added.
244 mEnv.erase( mEnv.begin() + nn - 1 );
245 --nn;
246 }
247}
EnvPoint, derived from XMLTagHandler, provides Envelope with a draggable point type.
Definition: Envelope.h:29
EnvArray mEnv
Definition: Envelope.h:237

References mEnv.

Referenced by CopyRange(), and SetTrackLen().

Here is the caller graph for this function:

◆ Average()

double Envelope::Average ( double  t0,
double  t1 
) const

Definition at line 1081 of file Envelope.cpp.

1082{
1083 if( t0 == t1 )
1084 return GetValue( t0 );
1085 else
1086 return Integral( t0, t1 ) / (t1 - t0);
1087}
double GetValue(double t, double sampleDur=0) const
Get envelope value at time t.
Definition: Envelope.cpp:837
double Integral(double t0, double t1) const
Definition: Envelope.cpp:1180

References GetValue(), and Integral().

Here is the call graph for this function:

◆ AverageOfInverse()

double Envelope::AverageOfInverse ( double  t0,
double  t1 
) const

Definition at line 1089 of file Envelope.cpp.

1090{
1091 if( t0 == t1 )
1092 return 1.0 / GetValue( t0 );
1093 else
1094 return IntegralOfInverse( t0, t1 ) / (t1 - t0);
1095}
double IntegralOfInverse(double t0, double t1) const
Definition: Envelope.cpp:1243

References GetValue(), and IntegralOfInverse().

Referenced by anonymous_namespace{MixerSource.cpp}::ComputeWarpFactor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ BinarySearchForTime()

void Envelope::BinarySearchForTime ( int &  Lo,
int &  Hi,
double  t 
) const
private
Parameters
Loreturns last index at or before this time, maybe -1
Hireturns first index after this time, maybe past the end

Definition at line 857 of file Envelope.cpp.

858{
859 // Optimizations for the usual pattern of repeated calls with
860 // small increases of t.
861 {
862 if (mSearchGuess >= 0 && mSearchGuess < (int)mEnv.size()) {
863 if (t >= mEnv[mSearchGuess].GetT() &&
864 (1 + mSearchGuess == (int)mEnv.size() ||
865 t < mEnv[1 + mSearchGuess].GetT())) {
866 Lo = mSearchGuess;
867 Hi = 1 + mSearchGuess;
868 return;
869 }
870 }
871
872 ++mSearchGuess;
873 if (mSearchGuess >= 0 && mSearchGuess < (int)mEnv.size()) {
874 if (t >= mEnv[mSearchGuess].GetT() &&
875 (1 + mSearchGuess == (int)mEnv.size() ||
876 t < mEnv[1 + mSearchGuess].GetT())) {
877 Lo = mSearchGuess;
878 Hi = 1 + mSearchGuess;
879 return;
880 }
881 }
882 }
883
884 Lo = -1;
885 Hi = mEnv.size();
886
887 // Invariants: Lo is not less than -1, Hi not more than size
888 while (Hi > (Lo + 1)) {
889 int mid = (Lo + Hi) / 2;
890 // mid must be strictly between Lo and Hi, therefore a valid index
891 if (t < mEnv[mid].GetT())
892 Hi = mid;
893 else
894 Lo = mid;
895 }
896 wxASSERT( Hi == ( Lo+1 ));
897
898 mSearchGuess = Lo;
899}
int mSearchGuess
Definition: Envelope.h:258

References mEnv, and mSearchGuess.

Referenced by GetValuesRelative(), Integral(), IntegralOfInverse(), NextPointAfter(), NumberOfPointsAfter(), and SolveIntegralOfInverse().

Here is the caller graph for this function:

◆ BinarySearchForTime_LeftLimit()

void Envelope::BinarySearchForTime_LeftLimit ( int &  Lo,
int &  Hi,
double  t 
) const
private
Parameters
Loreturns last index before this time, maybe -1
Hireturns first index at or after this time, maybe past the end

Definition at line 904 of file Envelope.cpp.

905{
906 Lo = -1;
907 Hi = mEnv.size();
908
909 // Invariants: Lo is not less than -1, Hi not more than size
910 while (Hi > (Lo + 1)) {
911 int mid = (Lo + Hi) / 2;
912 // mid must be strictly between Lo and Hi, therefore a valid index
913 if (t <= mEnv[mid].GetT())
914 Hi = mid;
915 else
916 Lo = mid;
917 }
918 wxASSERT( Hi == ( Lo+1 ));
919
920 mSearchGuess = Lo;
921}

References mEnv, and mSearchGuess.

Referenced by GetValuesRelative().

Here is the caller graph for this function:

◆ Cap()

void Envelope::Cap ( double  sampleDur)

Definition at line 714 of file Envelope.cpp.

715{
716 auto range = EqualRange( mTrackLen, sampleDur );
717 if ( range.first == range.second )
719}
int InsertOrReplaceRelative(double when, double value)
Add a control point to the envelope.
Definition: Envelope.cpp:729
double GetValueRelative(double t, bool leftLimit=false) const
Definition: Envelope.cpp:846

References EqualRange(), GetValueRelative(), InsertOrReplaceRelative(), and mTrackLen.

Here is the call graph for this function:

◆ ClampValue()

double Envelope::ClampValue ( double  value)
inline

Definition at line 104 of file Envelope.h.

104{ return std::max(mMinValue, std::min(mMaxValue, value)); }
int min(int a, int b)

References min().

Referenced by Flatten(), RescaleValues(), SetRange(), EnvPoint::SetVal(), and EnvelopeEditor::ValueOfPixel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Clear()

void Envelope::Clear ( )
inline

Definition at line 173 of file Envelope.h.

173{ mEnv.clear(); }

◆ ClearDragPoint()

void Envelope::ClearDragPoint ( )

Definition at line 213 of file Envelope.cpp.

214{
215 if (!mDragPointValid && mDragPoint >= 0)
217
218 mDragPoint = -1;
219 mDragPointValid = false;
220}
int mDragPoint
Definition: Envelope.h:256
void Delete(int point)
DELETE a point by its position in array.
Definition: Envelope.cpp:362
bool mDragPointValid
Definition: Envelope.h:255

References Delete(), mDragPoint, and mDragPointValid.

Referenced by EnvelopeEditor::HandleMouseButtonUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CollapseRegion()

void Envelope::CollapseRegion ( double  t0,
double  t1,
double  sampleDur 
)
Exception safety guarantee:
No-fail

Definition at line 378 of file Envelope.cpp.

379{
380 if ( t1 <= t0 )
381 return;
382
383 // This gets called when somebody clears samples.
384
385 // Snip points in the interval (t0, t1), shift values left at times after t1.
386 // For the boundaries of the interval, preserve the left-side limit at the
387 // start and right-side limit at the end.
388
389 const auto epsilon = sampleDur / 2;
390 t0 = std::max( 0.0, std::min( mTrackLen, t0 - mOffset ) );
391 t1 = std::max( 0.0, std::min( mTrackLen, t1 - mOffset ) );
392 bool leftPoint = true, rightPoint = true;
393
394 // Determine the start of the range of points to remove from the array.
395 auto range0 = EqualRange( t0, 0 );
396 auto begin = range0.first;
397 if ( begin == range0.second ) {
398 if ( t0 > epsilon ) {
399 // There was no point exactly at t0;
400 // insert a point to preserve the value.
401 auto val = GetValueRelative( t0 );
402 InsertOrReplaceRelative( t0, val );
403 ++begin;
404 }
405 else
406 leftPoint = false;
407 }
408 else
409 // We will keep the first (or only) point that was at t0.
410 ++begin;
411
412 // We want end to be the index one past the range of points to remove from
413 // the array.
414 // At first, find index of the first point after t1:
415 auto range1 = EqualRange( t1, 0 );
416 auto end = range1.second;
417 if ( range1.first == end ) {
418 if ( mTrackLen - t1 > epsilon ) {
419 // There was no point exactly at t1; insert a point to preserve the value.
420 auto val = GetValueRelative( t1 );
421 InsertOrReplaceRelative( t1, val );
422 // end is now the index of this NEW point and that is correct.
423 }
424 else
425 rightPoint = false;
426 }
427 else
428 // We will keep the last (or only) point that was at t1.
429 --end;
430
431 if ( end < begin ) {
432 if ( leftPoint )
433 rightPoint = false;
434 }
435 else
436 mEnv.erase( mEnv.begin() + begin, mEnv.begin() + end );
437
438 // Shift points left after deleted region.
439 auto len = mEnv.size();
440 for ( size_t i = begin; i < len; ++i ) {
441 auto &point = mEnv[i];
442 if (rightPoint && (int)i == begin)
443 // Avoid roundoff error.
444 // Make exactly equal times of neighboring points so that we have
445 // a real discontinuity.
446 point.SetT( t0 );
447 else
448 point.SetT( point.GetT() - (t1 - t0) );
449 }
450
451 // See if the discontinuity is removable.
452 if ( rightPoint )
454 if ( leftPoint )
455 RemoveUnneededPoints( begin - 1, false );
456
457 mTrackLen -= ( t1 - t0 );
458}
void RemoveUnneededPoints(size_t startAt, bool rightward, bool testNeighbors=true)
Definition: Envelope.cpp:550
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

References PackedArray::begin(), PackedArray::end(), EqualRange(), GetValueRelative(), InsertOrReplaceRelative(), mEnv, min(), mOffset, mTrackLen, and RemoveUnneededPoints().

Referenced by WaveClip::ClearAndAddCutLine(), WaveClip::ClearSequence(), and WaveTrack::Interval::GetStretchRenderedCopy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ConsistencyCheck()

bool Envelope::ConsistencyCheck ( )

Definition at line 61 of file Envelope.cpp.

62{
63 bool consistent = true;
64
65 bool disorder;
66 do {
67 disorder = false;
68 for ( size_t ii = 0, count = mEnv.size(); ii < count; ) {
69 // Find range of points with equal T
70 const double thisT = mEnv[ii].GetT();
71 double nextT = 0.0f;
72 auto nextI = ii + 1;
73 while ( nextI < count && thisT == ( nextT = mEnv[nextI].GetT() ) )
74 ++nextI;
75
76 if ( nextI < count && nextT < thisT )
77 disorder = true;
78
79 while ( nextI - ii > 2 ) {
80 // too many coincident time values
81 if ((int)ii == mDragPoint || (int)nextI - 1 == mDragPoint)
82 // forgivable
83 ;
84 else {
85 consistent = false;
86 // repair it
87 Delete( nextI - 2 );
88 if (mDragPoint >= (int)nextI - 2)
89 --mDragPoint;
90 --nextI, --count;
91 // wxLogError
92 }
93 }
94
95 ii = nextI;
96 }
97
98 if (disorder) {
99 consistent = false;
100 // repair it
101 std::stable_sort( mEnv.begin(), mEnv.end(),
102 []( const EnvPoint &a, const EnvPoint &b )
103 { return a.GetT() < b.GetT(); } );
104 }
105 } while ( disorder );
106
107 return consistent;
108}

References mEnv.

Referenced by PasteEnvelope().

Here is the caller graph for this function:

◆ CopyRange()

void Envelope::CopyRange ( const Envelope orig,
size_t  begin,
size_t  end 
)
private

Definition at line 274 of file Envelope.cpp.

275{
276 size_t len = orig.mEnv.size();
277 size_t i = begin;
278
279 // Create the point at 0 if it needs interpolated representation
280 if ( i > 0 )
282
283 // Copy points from inside the copied region
284 for (; i < end; ++i) {
285 const EnvPoint &point = orig[i];
286 const double when = point.GetT() + (orig.mOffset - mOffset);
287 AddPointAtEnd(when, point.GetVal());
288 }
289
290 // Create the final point if it needs interpolated representation
291 // If the last point of e was exactly at t1, this effectively copies it too.
292 if (mTrackLen > 0 && i < len)
294}
double GetVal() const
Definition: Envelope.h:37
double GetT() const
Definition: Envelope.h:35
void AddPointAtEnd(double t, double val)
Definition: Envelope.cpp:232

References AddPointAtEnd(), PackedArray::begin(), PackedArray::end(), EnvPoint::GetT(), EnvPoint::GetVal(), GetValue(), mEnv, mOffset, and mTrackLen.

Referenced by Envelope().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Delete()

void Envelope::Delete ( int  point)

DELETE a point by its position in array.

Definition at line 362 of file Envelope.cpp.

363{
364 mEnv.erase(mEnv.begin() + point);
365}

References mEnv.

Referenced by ClearDragPoint(), BoundedEnvelope::Envelope(), and RemoveUnneededPoints().

Here is the caller graph for this function:

◆ EqualRange()

std::pair< int, int > Envelope::EqualRange ( double  when,
double  sampleDur 
) const
private

Definition at line 763 of file Envelope.cpp.

764{
765 // Find range of envelope points matching the given time coordinate
766 // (within an interval of length sampleDur)
767 // by binary search; if empty, it still indicates where to
768 // insert.
769 const auto tolerance = sampleDur / 2;
770 auto begin = mEnv.begin();
771 auto end = mEnv.end();
772 auto first = std::lower_bound(
773 begin, end,
774 EnvPoint{ when - tolerance, 0.0 },
775 []( const EnvPoint &point1, const EnvPoint &point2 )
776 { return point1.GetT() < point2.GetT(); }
777 );
778 auto after = first;
779 while ( after != end && after->GetT() <= when + tolerance )
780 ++after;
781 return { first - begin, after - begin };
782}

References PackedArray::begin(), PackedArray::end(), EnvPoint::GetT(), and mEnv.

Referenced by Cap(), CollapseRegion(), Envelope(), ExpandRegion(), InsertOrReplaceRelative(), PasteEnvelope(), and SetTrackLen().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ExpandRegion()

std::pair< int, int > Envelope::ExpandRegion ( double  t0,
double  tlen,
double *  pLeftVal,
double *  pRightVal 
)
private
Exception safety guarantee:
No-fail

Definition at line 615 of file Envelope.cpp.

617{
618 // t0 is relative time
619
620 double val = GetValueRelative( t0 );
621 const auto range = EqualRange( t0, 0 );
622
623 // Preserve the left-side limit.
624 int index = 1 + range.first;
625 if ( index <= range.second )
626 // There is already a control point.
627 ;
628 else {
629 // Make a control point.
630 Insert( range.first, EnvPoint{ t0, val } );
631 }
632
633 // Shift points.
634 auto len = mEnv.size();
635 for ( unsigned int ii = index; ii < len; ++ii ) {
636 auto &point = mEnv[ ii ];
637 point.SetT( point.GetT() + tlen );
638 }
639
640 mTrackLen += tlen;
641
642 // Preserve the right-side limit.
643 if ( index < range.second )
644 // There was a control point already.
645 ;
646 else
647 // Make a control point.
648 Insert( index, EnvPoint{ t0 + tlen, val } );
649
650 // Make discontinuities at ends, maybe:
651
652 if ( pLeftVal )
653 // Make a discontinuity at the left side of the expansion
654 Insert( index++, EnvPoint{ t0, *pLeftVal } );
655
656 if ( pRightVal )
657 // Make a discontinuity at the right side of the expansion
658 Insert( index++, EnvPoint{ t0 + tlen, *pRightVal } );
659
660 // Return the range of indices that includes the inside limiting points,
661 // none, one, or two
662 return { 1 + range.first, index };
663}
void Insert(int point, const EnvPoint &p)
insert a point
Definition: Envelope.cpp:367

References EqualRange(), GetValueRelative(), Insert(), mEnv, and mTrackLen.

Referenced by InsertSpace(), and PasteEnvelope().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Flatten()

void Envelope::Flatten ( double  value)

Flatten removes all points from the envelope to make it horizontal at a chosen y-value. @value - the y-value for the flat envelope.

Definition at line 138 of file Envelope.cpp.

139{
140 mEnv.clear();
141 mDefaultValue = ClampValue(value);
142}

References ClampValue(), mDefaultValue, and mEnv.

Referenced by EqualizationBandSliders::GraphicEQ(), testMe(), and TimeTrack::testMe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDragPoint()

int Envelope::GetDragPoint ( ) const
inline

Definition at line 216 of file Envelope.h.

216{ return mDragPoint; }

Referenced by EnvelopeEditor::DrawPoints(), and EnvelopeEditor::MouseEvent().

Here is the caller graph for this function:

◆ GetDragPointValid()

bool Envelope::GetDragPointValid ( ) const
inline

Definition at line 221 of file Envelope.h.

221{ return mDragPointValid; }

Referenced by EnvelopeEditor::HandleDragging().

Here is the caller graph for this function:

◆ GetExponential()

bool Envelope::GetExponential ( ) const
inline

Definition at line 95 of file Envelope.h.

95{ return mDB; }

Referenced by CommonChannelView::GetEnvelopeValues().

Here is the caller graph for this function:

◆ GetInterpolationStartValueAtPoint()

double Envelope::GetInterpolationStartValueAtPoint ( int  iPoint) const
private

GetInterpolationStartValueAtPoint() is used to select either the envelope value or its log depending on whether we are doing linear or log interpolation.

Parameters
iPointindex in env array to look at.
Returns
value there, or its (safe) log10.

Definition at line 928 of file Envelope.cpp.

929{
930 double v = mEnv[ iPoint ].GetVal();
931 if( !mDB )
932 return v;
933 else
934 return log10(v);
935}

References mDB, and mEnv.

Referenced by GetValuesRelative().

Here is the caller graph for this function:

◆ GetMaxValue()

double Envelope::GetMaxValue ( ) const
inline

Definition at line 101 of file Envelope.h.

101{ return mMaxValue; }

◆ GetMinValue()

double Envelope::GetMinValue ( ) const
inline

Definition at line 100 of file Envelope.h.

100{ return mMinValue; }

◆ GetNumberOfPoints()

size_t Envelope::GetNumberOfPoints ( ) const

Return number of points.

Definition at line 695 of file Envelope.cpp.

696{
697 return mEnv.size();
698}

References mEnv.

Referenced by EnvelopeEditor::DrawPoints(), Envelope(), EqualizationCurvesList::EnvelopeUpdated(), EqualizationBandSliders::EnvLinToLog(), EqualizationBandSliders::EnvLogToLin(), EnvelopeEditor::HandleMouseButtonDown(), and GetInfoCommand::SendEnvelopes().

Here is the caller graph for this function:

◆ GetOffset()

double Envelope::GetOffset ( ) const
inline

Definition at line 92 of file Envelope.h.

92{ return mOffset; }

Referenced by EnvelopeEditor::DrawPoints(), EnvelopeEditor::HandleMouseButtonDown(), EnvelopeEditor::MoveDragPoint(), and GetInfoCommand::SendEnvelopes().

Here is the caller graph for this function:

◆ GetPoints()

void Envelope::GetPoints ( double *  bufferWhen,
double *  bufferValue,
int  bufferLen 
) const

Returns the sets of when and value pairs.

Definition at line 700 of file Envelope.cpp.

703{
704 int n = mEnv.size();
705 if (n > bufferLen)
706 n = bufferLen;
707 int i;
708 for (i = 0; i < n; i++) {
709 bufferWhen[i] = mEnv[i].GetT() - mOffset;
710 bufferValue[i] = mEnv[i].GetVal();
711 }
712}

References mEnv, and mOffset.

Referenced by EqualizationCurvesList::EnvelopeUpdated().

Here is the caller graph for this function:

◆ GetTrackLen()

double Envelope::GetTrackLen ( ) const
inline

Definition at line 93 of file Envelope.h.

93{ return mTrackLen; }

◆ GetValue()

double Envelope::GetValue ( double  t,
double  sampleDur = 0 
) const

Get envelope value at time t.

Definition at line 837 of file Envelope.cpp.

838{
839 // t is absolute time
840 double temp;
841
842 GetValues( &temp, 1, t, sampleDur );
843 return temp;
844}
void GetValues(double *buffer, int len, double t0, double tstep) const
Get many envelope points at once.
Definition: Envelope.cpp:937

References GetValues().

Referenced by Average(), AverageOfInverse(), EqualizationFilter::CalcFilter(), CopyRange(), anonymous_namespace{WaveformView.cpp}::DrawIndividualSamples(), EqualizationBandSliders::ErrMin(), SampleHandle::FindSampleEditingLevel(), CommonChannelView::GetEnvelopeValues(), EnvelopeEditor::HandleMouseButtonDown(), EnvelopeHandle::HitEnvelope(), SampleHandle::HitTest(), and PasteEnvelope().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetValueRelative()

double Envelope::GetValueRelative ( double  t,
bool  leftLimit = false 
) const
private

Definition at line 846 of file Envelope.cpp.

847{
848 double temp;
849
850 GetValuesRelative(&temp, 1, t, 0.0, leftLimit);
851 return temp;
852}
void GetValuesRelative(double *buffer, int len, double t0, double tstep, bool leftLimit=false) const
Definition: Envelope.cpp:946

References GetValuesRelative().

Referenced by Cap(), CollapseRegion(), ExpandRegion(), PasteEnvelope(), RemoveUnneededPoints(), and SetTrackLen().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetValues()

void Envelope::GetValues ( double *  buffer,
int  len,
double  t0,
double  tstep 
) const

Get many envelope points at once.

This is much faster than calling GetValue() multiple times if you need more than one value in a row.

Definition at line 937 of file Envelope.cpp.

939{
940 // Convert t0 from absolute to clip-relative time
941 t0 -= mOffset;
942 GetValuesRelative( buffer, bufferLen, t0, tstep);
943}

References GetValuesRelative(), and mOffset.

Referenced by GetValue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetValuesRelative()

void Envelope::GetValuesRelative ( double *  buffer,
int  len,
double  t0,
double  tstep,
bool  leftLimit = false 
) const
private

Definition at line 945 of file Envelope.cpp.

948{
949 // JC: If bufferLen ==0 we have probably just allocated a zero sized buffer.
950 // wxASSERT( bufferLen > 0 );
951
952 const auto epsilon = tstep / 2;
953 int len = mEnv.size();
954
955 double t = t0;
956 double increment = 0;
957 if ( len > 1 && t <= mEnv[0].GetT() && mEnv[0].GetT() == mEnv[1].GetT() )
958 increment = leftLimit ? -epsilon : epsilon;
959
960 double tprev, vprev, tnext = 0, vnext, vstep = 0;
961
962 for (int b = 0; b < bufferLen; b++) {
963
964 // Get easiest cases out the way first...
965 // IF empty envelope THEN default value
966 if (len <= 0) {
967 buffer[b] = mDefaultValue;
968 t += tstep;
969 continue;
970 }
971
972 auto tplus = t + increment;
973
974 // IF before envelope THEN first value
975 if ( leftLimit ? tplus <= mEnv[0].GetT() : tplus < mEnv[0].GetT() ) {
976 buffer[b] = mEnv[0].GetVal();
977 t += tstep;
978 continue;
979 }
980 // IF after envelope THEN last value
981 if ( leftLimit
982 ? tplus > mEnv[len - 1].GetT() : tplus >= mEnv[len - 1].GetT() ) {
983 buffer[b] = mEnv[len - 1].GetVal();
984 t += tstep;
985 continue;
986 }
987
988 // be careful to get the correct limit even in case epsilon == 0
989 if ( b == 0 ||
990 ( leftLimit ? tplus > tnext : tplus >= tnext ) ) {
991
992 // We're beyond our tnext, so find the next one.
993 // Don't just increment lo or hi because we might
994 // be zoomed far out and that could be a large number of
995 // points to move over. That's why we binary search.
996
997 int lo,hi;
998 if ( leftLimit )
999 BinarySearchForTime_LeftLimit( lo, hi, tplus );
1000 else
1001 BinarySearchForTime( lo, hi, tplus );
1002
1003 // mEnv[0] is before tplus because of eliminations above, therefore lo >= 0
1004 // mEnv[len - 1] is after tplus, therefore hi <= len - 1
1005 wxASSERT( lo >= 0 && hi <= len - 1 );
1006
1007 tprev = mEnv[lo].GetT();
1008 tnext = mEnv[hi].GetT();
1009
1010 if ( hi + 1 < len && tnext == mEnv[ hi + 1 ].GetT() )
1011 // There is a discontinuity after this point-to-point interval.
1012 // Usually will stop evaluating in this interval when time is slightly
1013 // before tNext, then use the right limit.
1014 // This is the right intent
1015 // in case small roundoff errors cause a sample time to be a little
1016 // before the envelope point time.
1017 // Less commonly we want a left limit, so we continue evaluating in
1018 // this interval until shortly after the discontinuity.
1019 increment = leftLimit ? -epsilon : epsilon;
1020 else
1021 increment = 0;
1022
1025
1026 // Interpolate, either linear or log depending on mDB.
1027 double dt = (tnext - tprev);
1028 double to = t - tprev;
1029 double v;
1030 if (dt > 0.0)
1031 {
1032 v = (vprev * (dt - to) + vnext * to) / dt;
1033 vstep = (vnext - vprev) * tstep / dt;
1034 }
1035 else
1036 {
1037 v = vnext;
1038 vstep = 0.0;
1039 }
1040
1041 // An adjustment if logarithmic scale.
1042 if( mDB )
1043 {
1044 v = pow(10.0, v);
1045 vstep = pow( 10.0, vstep );
1046 }
1047
1048 buffer[b] = v;
1049 } else {
1050 if (mDB){
1051 buffer[b] = buffer[b - 1] * vstep;
1052 }else{
1053 buffer[b] = buffer[b - 1] + vstep;
1054 }
1055 }
1056
1057 t += tstep;
1058 }
1059}
void BinarySearchForTime(int &Lo, int &Hi, double t) const
Definition: Envelope.cpp:857
void BinarySearchForTime_LeftLimit(int &Lo, int &Hi, double t) const
Definition: Envelope.cpp:904
double GetInterpolationStartValueAtPoint(int iPoint) const
Definition: Envelope.cpp:928

References BinarySearchForTime(), BinarySearchForTime_LeftLimit(), GetInterpolationStartValueAtPoint(), mDB, mDefaultValue, and mEnv.

Referenced by GetValueRelative(), and GetValues().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * Envelope::HandleXMLChild ( const std::string_view &  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 334 of file Envelope.cpp.

335{
336 if (tag != "controlpoint")
337 return NULL;
338
339 mEnv.push_back( EnvPoint{} );
340 return &mEnv.back();
341}

References mEnv.

Referenced by AUPImportFileHandle::HandleControlPoint().

Here is the caller graph for this function:

◆ HandleXMLTag()

bool Envelope::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 309 of file Envelope.cpp.

310{
311 // Return unless it's the envelope tag.
312 if (tag != "envelope")
313 return false;
314
315 int numPoints = -1;
316
317 for (auto pair : attrs)
318 {
319 auto attr = pair.first;
320 auto value = pair.second;
321
322 if (attr == "numpoints")
323 value.TryGet(numPoints);
324 }
325
326 if (numPoints < 0)
327 return false;
328
329 mEnv.clear();
330 mEnv.reserve(numPoints);
331 return true;
332}

References mEnv.

◆ Initialize()

void Envelope::Initialize ( int  numPoints)

◆ Insert() [1/2]

void Envelope::Insert ( double  when,
double  value 
)

Definition at line 372 of file Envelope.cpp.

373{
374 mEnv.push_back( EnvPoint{ when, value });
375}

References mEnv.

◆ Insert() [2/2]

void Envelope::Insert ( int  point,
const EnvPoint p 
)

insert a point

Definition at line 367 of file Envelope.cpp.

368{
369 mEnv.insert(mEnv.begin() + point, p);
370}

References mEnv.

Referenced by ExpandRegion(), EqualizationBandSliders::GraphicEQ(), InsertOrReplaceRelative(), and RemoveUnneededPoints().

Here is the caller graph for this function:

◆ InsertOrReplace()

int Envelope::InsertOrReplace ( double  when,
double  value 
)
inline

Add a point at a particular absolute time coordinate.

Definition at line 176 of file Envelope.h.

177 { return InsertOrReplaceRelative( when - mOffset, value ); }

Referenced by EnvelopeEditor::HandleMouseButtonDown(), and TimeTrack::testMe().

Here is the caller graph for this function:

◆ InsertOrReplaceRelative()

int Envelope::InsertOrReplaceRelative ( double  when,
double  value 
)
private

Add a control point to the envelope.

Parameters
whenthe time in seconds when the envelope point should be created.
valuethe envelope value to use at the given point.
Returns
the index of the NEW envelope point within array of envelope points.

Definition at line 729 of file Envelope.cpp.

730{
731#if defined(_DEBUG)
732 // in debug builds, do a spot of argument checking
733 if(when > mTrackLen + 0.0000001)
734 {
735 wxString msg;
736 msg = wxString::Format(wxT("when %.20f mTrackLen %.20f diff %.20f"), when, mTrackLen, when-mTrackLen);
737 wxASSERT_MSG(when <= (mTrackLen), msg);
738 }
739 if(when < 0)
740 {
741 wxString msg;
742 msg = wxString::Format(wxT("when %.20f mTrackLen %.20f"), when, mTrackLen);
743 wxASSERT_MSG(when >= 0, msg);
744 }
745#endif
746
747 when = std::max( 0.0, std::min( mTrackLen, when ) );
748
749 auto range = EqualRange( when, 0 );
750 int index = range.first;
751
752 if ( index < range.second )
753 // modify existing
754 // In case of a discontinuity, ALWAYS CHANGING LEFT LIMIT ONLY!
755 mEnv[ index ].SetVal( this, value );
756 else
757 // Add NEW
758 Insert( index, EnvPoint { when, value } );
759
760 return index;
761}
wxT("CloseDown"))

References EqualRange(), Insert(), mEnv, min(), mTrackLen, and wxT().

Referenced by Cap(), CollapseRegion(), and testMe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ InsertSpace()

void Envelope::InsertSpace ( double  t0,
double  tlen 
)
Exception safety guarantee:
No-fail

Definition at line 666 of file Envelope.cpp.

667{
668 auto range = ExpandRegion( t0 - mOffset, tlen, nullptr, nullptr );
669
670 // Simplify the boundaries if possible
671 RemoveUnneededPoints( range.second, true );
672 RemoveUnneededPoints( range.first - 1, false );
673}
std::pair< int, int > ExpandRegion(double t0, double tlen, double *pLeftVal, double *pRightVal)
Definition: Envelope.cpp:616

References ExpandRegion(), mOffset, and RemoveUnneededPoints().

Here is the call graph for this function:

◆ Integral()

double Envelope::Integral ( double  t0,
double  t1 
) const

Definition at line 1180 of file Envelope.cpp.

1181{
1182 if(t0 == t1)
1183 return 0.0;
1184 if(t0 > t1)
1185 {
1186 return -Integral(t1, t0); // this makes more sense than returning the default value
1187 }
1188
1189 unsigned int count = mEnv.size();
1190 if(count == 0) // 'empty' envelope
1191 return (t1 - t0) * mDefaultValue;
1192
1193 t0 -= mOffset;
1194 t1 -= mOffset;
1195
1196 double total = 0.0, lastT, lastVal;
1197 unsigned int i; // this is the next point to check
1198 if(t0 < mEnv[0].GetT()) // t0 preceding the first point
1199 {
1200 if(t1 <= mEnv[0].GetT())
1201 return (t1 - t0) * mEnv[0].GetVal();
1202 i = 1;
1203 lastT = mEnv[0].GetT();
1204 lastVal = mEnv[0].GetVal();
1205 total += (lastT - t0) * lastVal;
1206 }
1207 else if(t0 >= mEnv[count - 1].GetT()) // t0 at or following the last point
1208 {
1209 return (t1 - t0) * mEnv[count - 1].GetVal();
1210 }
1211 else // t0 enclosed by points
1212 {
1213 // Skip any points that come before t0 using binary search
1214 int lo, hi;
1215 BinarySearchForTime(lo, hi, t0);
1216 lastVal = InterpolatePoints(mEnv[lo].GetVal(), mEnv[hi].GetVal(), (t0 - mEnv[lo].GetT()) / (mEnv[hi].GetT() - mEnv[lo].GetT()), mDB);
1217 lastT = t0;
1218 i = hi; // the point immediately after t0.
1219 }
1220
1221 // loop through the rest of the envelope points until we get to t1
1222 while (1)
1223 {
1224 if(i >= count) // the requested range extends beyond the last point
1225 {
1226 return total + (t1 - lastT) * lastVal;
1227 }
1228 else if(mEnv[i].GetT() >= t1) // this point follows the end of the range
1229 {
1230 double thisVal = InterpolatePoints(mEnv[i - 1].GetVal(), mEnv[i].GetVal(), (t1 - mEnv[i - 1].GetT()) / (mEnv[i].GetT() - mEnv[i - 1].GetT()), mDB);
1231 return total + IntegrateInterpolated(lastVal, thisVal, t1 - lastT, mDB);
1232 }
1233 else // this point precedes the end of the range
1234 {
1235 total += IntegrateInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, mDB);
1236 lastT = mEnv[i].GetT();
1237 lastVal = mEnv[i].GetVal();
1238 i++;
1239 }
1240 }
1241}
static double InterpolatePoints(double y1, double y2, double factor, bool logarithmic)
Definition: Envelope.cpp:1107
static double IntegrateInterpolated(double y1, double y2, double time, bool logarithmic)
Definition: Envelope.cpp:1115

References BinarySearchForTime(), Integral(), IntegrateInterpolated(), InterpolatePoints(), mDB, mDefaultValue, mEnv, and mOffset.

Referenced by Average(), Integral(), testMe(), and TimeTrack::testMe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IntegralOfInverse()

double Envelope::IntegralOfInverse ( double  t0,
double  t1 
) const

Definition at line 1243 of file Envelope.cpp.

1244{
1245 if(t0 == t1)
1246 return 0.0;
1247 if(t0 > t1)
1248 {
1249 return -IntegralOfInverse(t1, t0); // this makes more sense than returning the default value
1250 }
1251
1252 unsigned int count = mEnv.size();
1253 if(count == 0) // 'empty' envelope
1254 return (t1 - t0) / mDefaultValue;
1255
1256 t0 -= mOffset;
1257 t1 -= mOffset;
1258
1259 double total = 0.0, lastT, lastVal;
1260 unsigned int i; // this is the next point to check
1261 if(t0 < mEnv[0].GetT()) // t0 preceding the first point
1262 {
1263 if(t1 <= mEnv[0].GetT())
1264 return (t1 - t0) / mEnv[0].GetVal();
1265 i = 1;
1266 lastT = mEnv[0].GetT();
1267 lastVal = mEnv[0].GetVal();
1268 total += (lastT - t0) / lastVal;
1269 }
1270 else if(t0 >= mEnv[count - 1].GetT()) // t0 at or following the last point
1271 {
1272 return (t1 - t0) / mEnv[count - 1].GetVal();
1273 }
1274 else // t0 enclosed by points
1275 {
1276 // Skip any points that come before t0 using binary search
1277 int lo, hi;
1278 BinarySearchForTime(lo, hi, t0);
1279 lastVal = InterpolatePoints(mEnv[lo].GetVal(), mEnv[hi].GetVal(), (t0 - mEnv[lo].GetT()) / (mEnv[hi].GetT() - mEnv[lo].GetT()), mDB);
1280 lastT = t0;
1281 i = hi; // the point immediately after t0.
1282 }
1283
1284 // loop through the rest of the envelope points until we get to t1
1285 while (1)
1286 {
1287 if(i >= count) // the requested range extends beyond the last point
1288 {
1289 return total + (t1 - lastT) / lastVal;
1290 }
1291 else if(mEnv[i].GetT() >= t1) // this point follows the end of the range
1292 {
1293 double thisVal = InterpolatePoints(mEnv[i - 1].GetVal(), mEnv[i].GetVal(), (t1 - mEnv[i - 1].GetT()) / (mEnv[i].GetT() - mEnv[i - 1].GetT()), mDB);
1294 return total + IntegrateInverseInterpolated(lastVal, thisVal, t1 - lastT, mDB);
1295 }
1296 else // this point precedes the end of the range
1297 {
1298 total += IntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, mDB);
1299 lastT = mEnv[i].GetT();
1300 lastVal = mEnv[i].GetVal();
1301 i++;
1302 }
1303 }
1304}
static double IntegrateInverseInterpolated(double y1, double y2, double time, bool logarithmic)
Definition: Envelope.cpp:1136

References BinarySearchForTime(), IntegralOfInverse(), IntegrateInverseInterpolated(), InterpolatePoints(), mDB, mDefaultValue, mEnv, and mOffset.

Referenced by AverageOfInverse(), GeneratedUpdater::ComputeWarpedLength(), PlaybackSchedule::ComputeWarpedLength(), IntegralOfInverse(), and TimeTrack::testMe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsDirty()

bool Envelope::IsDirty ( ) const

◆ IsTrivial()

bool Envelope::IsTrivial ( ) const

Definition at line 56 of file Envelope.cpp.

57{
58 return mDefaultValue == 1.0 && mEnv.empty();
59}

References mDefaultValue, and mEnv.

◆ MoveDragPoint()

void Envelope::MoveDragPoint ( double  newWhen,
double  value 
)

Definition at line 187 of file Envelope.cpp.

188{
189 SetDragPointValid(true);
190 if (!mDragPointValid)
191 return;
192
193 // We'll limit the drag point time to be between those of the preceding
194 // and next envelope point.
195 double limitLo = 0.0;
196 double limitHi = mTrackLen;
197
198 if (mDragPoint > 0)
199 limitLo = std::max(limitLo, mEnv[mDragPoint - 1].GetT());
200 if (mDragPoint + 1 < (int)mEnv.size())
201 limitHi = std::min(limitHi, mEnv[mDragPoint + 1].GetT());
202
203 EnvPoint &dragPoint = mEnv[mDragPoint];
204 const double tt =
205 std::max(limitLo, std::min(limitHi, newWhen));
206
207 // This might temporary violate the constraint that at most two
208 // points share a time value.
209 dragPoint.SetT(tt);
210 dragPoint.SetVal( this, value );
211}
void SetT(double t)
Definition: Envelope.h:36
void SetVal(Envelope *pEnvelope, double val)
Definition: Envelope.h:261
void SetDragPointValid(bool valid)
Definition: Envelope.cpp:150

References mDragPoint, mDragPointValid, mEnv, min(), mTrackLen, SetDragPointValid(), EnvPoint::SetT(), and EnvPoint::SetVal().

Referenced by EnvelopeEditor::MoveDragPoint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NextPointAfter()

double Envelope::NextPointAfter ( double  t) const
private

Definition at line 1071 of file Envelope.cpp.

1072{
1073 int lo,hi;
1074 BinarySearchForTime( lo, hi, t );
1075 if (hi >= (int)mEnv.size())
1076 return t;
1077 else
1078 return mEnv[hi].GetT();
1079}

References BinarySearchForTime(), and mEnv.

Referenced by testMe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NumberOfPointsAfter()

int Envelope::NumberOfPointsAfter ( double  t) const
private

Definition at line 1062 of file Envelope.cpp.

1063{
1064 int lo,hi;
1065 BinarySearchForTime( lo, hi, t );
1066
1067 return mEnv.size() - hi;
1068}

References BinarySearchForTime(), and mEnv.

Referenced by testMe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator[]()

const EnvPoint & Envelope::operator[] ( int  index) const
inline

Accessor for points.

Definition at line 198 of file Envelope.h.

199 {
200 return mEnv[index];
201 }

◆ PasteEnvelope()

void Envelope::PasteEnvelope ( double  t0,
const Envelope e,
double  sampleDur 
)
Exception safety guarantee:
No-fail

Definition at line 466 of file Envelope.cpp.

467{
468 const bool wasEmpty = (this->mEnv.size() == 0);
469 auto otherSize = e->mEnv.size();
470 const double otherDur = e->mTrackLen;
471 const auto otherOffset = e->mOffset;
472 const auto deltat = otherOffset + otherDur;
473
474 if ( otherSize == 0 && wasEmpty && e->mDefaultValue == this->mDefaultValue )
475 {
476 // msmeyer: The envelope is empty and has the same default value, so
477 // there is nothing that must be inserted, just return. This avoids
478 // the creation of unnecessary duplicate control points
479 // MJS: but the envelope does get longer
480 // PRL: Assuming t0 is in the domain of the envelope
481 mTrackLen += deltat;
482 return;
483 }
484
485 // Make t0 relative to the offset of the envelope we are pasting into,
486 // and trim it to the domain of this
487 t0 = std::min( mTrackLen, std::max( 0.0, t0 - mOffset ) );
488
489 // Adjust if the insertion point rounds off near a discontinuity in this
490 if ( true )
491 {
492 double newT0;
493 auto range = EqualRange( t0, sampleDur );
494 auto index = range.first;
495 if ( index + 2 == range.second &&
496 ( newT0 = mEnv[ index ].GetT() ) == mEnv[ 1 + index ].GetT() )
497 t0 = newT0;
498 }
499
500 // Open up a space
501 double leftVal = e->GetValue( 0 );
502 double rightVal = e->GetValueRelative( otherDur );
503 // This range includes the right-side limit of the left end of the space,
504 // and the left-side limit of the right end:
505 const auto range = ExpandRegion( t0, deltat, &leftVal, &rightVal );
506 // Where to put the copied points from e -- after the first of the
507 // two points in range:
508 auto insertAt = range.first + 1;
509
510 // Copy points from e -- maybe skipping those at the extremes
511 auto end = e->mEnv.end();
512 if ( otherSize != 0 && e->mEnv[ otherSize - 1 ].GetT() == otherDur )
513 // ExpandRegion already made an equivalent limit point
514 --end, --otherSize;
515 auto begin = e->mEnv.begin();
516 if ( otherSize != 0 && otherOffset == 0.0 && e->mEnv[ 0 ].GetT() == 0.0 )
517 ++begin, --otherSize;
518 mEnv.insert( mEnv.begin() + insertAt, begin, end );
519
520 // Adjust their times
521 for ( size_t index = insertAt, last = insertAt + otherSize;
522 index < last; ++index ) {
523 auto &point = mEnv[ index ];
524 // The mOffset of the envelope-pasted-from is irrelevant.
525 // The GetT() times in it are relative to its start.
526 // The new GetT() times are relative to the envelope-pasted-to start.
527 // We are pasting at t0 relative to the envelope-pasted-to start.
528 // Hence we adjust by just t0.
529 // Bug 1844 was that we also adjusted by the envelope-pasted-from offset.
530 point.SetT( point.GetT() + /*otherOffset +*/ t0 );
531 }
532
533 // Treat removable discontinuities
534 // Right edge outward:
535 RemoveUnneededPoints( insertAt + otherSize + 1, true );
536 // Right edge inward:
537 RemoveUnneededPoints( insertAt + otherSize, false, false );
538
539 // Left edge inward:
540 RemoveUnneededPoints( range.first, true, false );
541 // Left edge outward:
542 RemoveUnneededPoints( range.first - 1, false );
543
544 // Guarantee monotonicity of times, against little round-off mistakes perhaps
546}
bool ConsistencyCheck()
Definition: Envelope.cpp:61

References PackedArray::begin(), ConsistencyCheck(), PackedArray::end(), EqualRange(), ExpandRegion(), GetValue(), GetValueRelative(), mDefaultValue, mEnv, min(), mOffset, mTrackLen, and RemoveUnneededPoints().

Here is the call graph for this function:

◆ print()

void Envelope::print ( ) const

Definition at line 1409 of file Envelope.cpp.

1410{
1411 for( unsigned int i = 0; i < mEnv.size(); i++ )
1412 wxPrintf( "(%.2f, %.2f)\n", mEnv[i].GetT(), mEnv[i].GetVal() );
1413}

References mEnv.

◆ Reassign()

int Envelope::Reassign ( double  when,
double  value 
)

Move a point at when to value.

Returns 0 if point moved, -1 if not found.

Definition at line 675 of file Envelope.cpp.

676{
677 when -= mOffset;
678
679 int len = mEnv.size();
680 if (len == 0)
681 return -1;
682
683 int i = 0;
684 while (i < len && when > mEnv[i].GetT())
685 i++;
686
687 if (i >= len || when < mEnv[i].GetT())
688 return -1;
689
690 mEnv[i].SetVal( this, value );
691 return 0;
692}

References mEnv, and mOffset.

Referenced by EqualizationBandSliders::GraphicEQ().

Here is the caller graph for this function:

◆ RemoveUnneededPoints()

void Envelope::RemoveUnneededPoints ( size_t  startAt,
bool  rightward,
bool  testNeighbors = true 
)
private
Exception safety guarantee:
No-fail

Definition at line 549 of file Envelope.cpp.

551{
552 // startAt is the index of a recently inserted point which might make no
553 // difference in envelope evaluation, or else might cause nearby points to
554 // make no difference.
555
556 auto isDiscontinuity = [this]( size_t index ) {
557 // Assume array accesses are in-bounds
558 const EnvPoint &point1 = mEnv[ index ];
559 const EnvPoint &point2 = mEnv[ index + 1 ];
560 return point1.GetT() == point2.GetT() &&
561 fabs( point1.GetVal() - point2.GetVal() ) > VALUE_TOLERANCE;
562 };
563
564 auto remove = [this]( size_t index, bool leftLimit ) {
565 // Assume array accesses are in-bounds
566 const auto &point = mEnv[ index ];
567 auto when = point.GetT();
568 auto val = point.GetVal();
569 Delete( index ); // try it to see if it's doing anything
570 auto val1 = GetValueRelative ( when, leftLimit );
571 if( fabs( val - val1 ) > VALUE_TOLERANCE ) {
572 // put it back, we needed it
573 Insert( index, EnvPoint{ when, val } );
574 return false;
575 }
576 else
577 return true;
578 };
579
580 auto len = mEnv.size();
581
582 bool leftLimit =
583 !rightward && startAt + 1 < len && isDiscontinuity( startAt );
584
585 bool removed = remove( startAt, leftLimit );
586
587 if ( removed )
588 // The given point was removable. Done!
589 return;
590
591 if ( !testNeighbors )
592 return;
593
594 // The given point was not removable. But did its insertion make nearby
595 // points removable?
596
597 int index = startAt + ( rightward ? 1 : -1 );
598 while ( index >= 0 && index < (int)len ) {
599 // Stop at any discontinuity
600 if ( index > 0 && isDiscontinuity( index - 1 ) )
601 break;
602 if ( (index + 1) < (int)len && isDiscontinuity( index ) )
603 break;
604
605 if ( ! remove( index, false ) )
606 break;
607
608 --len;
609 if ( ! rightward )
610 --index;
611 }
612}
static const double VALUE_TOLERANCE
Definition: Envelope.cpp:42

References Delete(), EnvPoint::GetT(), EnvPoint::GetVal(), GetValueRelative(), Insert(), mEnv, and VALUE_TOLERANCE.

Referenced by CollapseRegion(), InsertSpace(), and PasteEnvelope().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RescaleTimes()

void Envelope::RescaleTimes ( double  newLength)
Exception safety guarantee:
No-fail

Definition at line 814 of file Envelope.cpp.

815{
816 if ( mTrackLen == 0 ) {
817 for ( auto &point : mEnv )
818 point.SetT( 0 );
819 }
820 else {
821 auto ratio = newLength / mTrackLen;
822 for ( auto &point : mEnv )
823 point.SetT( point.GetT() * ratio );
824 }
825 mTrackLen = newLength;
826}

References mEnv, and mTrackLen.

◆ RescaleTimesBy()

void Envelope::RescaleTimesBy ( double  ratio)

Definition at line 828 of file Envelope.cpp.

829{
830 for (auto& point : mEnv)
831 point.SetT(point.GetT() * ratio);
832 if (mTrackLen != DBL_MAX)
833 mTrackLen *= ratio;
834}

References mEnv, and mTrackLen.

◆ RescaleValues()

void Envelope::RescaleValues ( double  minValue,
double  maxValue 
)

Rescale function for time tracks (could also be used for other tracks though). This is used to load old time track project files where the envelope used a 0 to 1 range instead of storing the actual time track values. This function will change the range of the envelope and rescale all envelope points accordingly (unlike SetRange, which clamps the envelope points to the NEW range). @minValue - the NEW minimum value @maxValue - the NEW maximum value

Definition at line 116 of file Envelope.cpp.

117{
118 double oldMinValue = mMinValue;
119 double oldMaxValue = mMaxValue;
120 mMinValue = minValue;
121 mMaxValue = maxValue;
122
123 // rescale the default value
124 double factor = (mDefaultValue - oldMinValue) / (oldMaxValue - oldMinValue);
126
127 // rescale all points
128 for( unsigned int i = 0; i < mEnv.size(); i++ ) {
129 factor = (mEnv[i].GetVal() - oldMinValue) / (oldMaxValue - oldMinValue);
130 mEnv[i].SetVal( this, mMinValue + (mMaxValue - mMinValue) * factor );
131 }
132
133}

References ClampValue(), mDefaultValue, mEnv, mMaxValue, and mMinValue.

Here is the call graph for this function:

◆ SetDragPoint()

void Envelope::SetDragPoint ( int  dragPoint)

Definition at line 144 of file Envelope.cpp.

145{
146 mDragPoint = std::max(-1, std::min(int(mEnv.size() - 1), dragPoint));
148}

References mDragPoint, mDragPointValid, mEnv, and min().

Referenced by EnvelopeEditor::HandleMouseButtonDown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetDragPointValid()

void Envelope::SetDragPointValid ( bool  valid)

Definition at line 150 of file Envelope.cpp.

151{
152 mDragPointValid = (valid && mDragPoint >= 0);
153 if (mDragPoint >= 0 && !valid) {
154 // We're going to be deleting the point; On
155 // screen we show this by having the envelope move to
156 // the position it will have after deletion of the point.
157 // Without deleting the point we move it left or right
158 // to the same position as the previous or next point.
159
160 static const double big = std::numeric_limits<double>::max();
161 auto size = mEnv.size();
162
163 if( size <= 1) {
164 // There is only one point - just move it
165 // off screen and at default height.
166 // temporary state when dragging only!
167 mEnv[mDragPoint].SetT(big);
168 mEnv[mDragPoint].SetVal( this, mDefaultValue );
169 return;
170 }
171 else if ( mDragPoint + 1 == (int)size ) {
172 // Put the point at the height of the last point, but also off screen.
173 mEnv[mDragPoint].SetT(big);
174 mEnv[mDragPoint].SetVal( this, mEnv[ size - 1 ].GetVal() );
175 }
176 else {
177 // Place it exactly on its right neighbour.
178 // That way the drawing code will overpaint the dark dot with
179 // a light dot, as if it were deleted.
180 const auto &neighbor = mEnv[mDragPoint + 1];
181 mEnv[mDragPoint].SetT(neighbor.GetT());
182 mEnv[mDragPoint].SetVal( this, neighbor.GetVal() );
183 }
184 }
185}

References mDefaultValue, mDragPoint, mDragPointValid, mEnv, and size.

Referenced by EnvelopeEditor::HandleDragging(), and MoveDragPoint().

Here is the caller graph for this function:

◆ SetExponential()

void Envelope::SetExponential ( bool  db)
inline

Definition at line 96 of file Envelope.h.

96{ mDB = db; }

Referenced by testMe().

Here is the caller graph for this function:

◆ SetOffset()

void Envelope::SetOffset ( double  newOffset)
Exception safety guarantee:
No-fail

Definition at line 787 of file Envelope.cpp.

788{
789 mOffset = newOffset;
790}

References mOffset.

Referenced by WaveTrack::Interval::GetStretchRenderedCopy().

Here is the caller graph for this function:

◆ SetRange()

void Envelope::SetRange ( double  minValue,
double  maxValue 
)

Definition at line 222 of file Envelope.cpp.

222 {
223 mMinValue = minValue;
224 mMaxValue = maxValue;
226 for( unsigned int i = 0; i < mEnv.size(); i++ )
227 mEnv[i].SetVal( this, mEnv[i].GetVal() ); // this clamps the value to the NEW range
228}

References ClampValue(), mDefaultValue, mEnv, mMaxValue, and mMinValue.

Here is the call graph for this function:

◆ SetTrackLen()

void Envelope::SetTrackLen ( double  trackLen,
double  sampleDur = 0.0 
)
Exception safety guarantee:
No-fail

Definition at line 793 of file Envelope.cpp.

794{
795 // Preserve the left-side limit at trackLen.
796 auto range = EqualRange( trackLen, sampleDur );
797 bool needPoint = ( range.first == range.second && trackLen < mTrackLen );
798 double value=0.0;
799 if ( needPoint )
800 value = GetValueRelative( trackLen );
801
802 mTrackLen = trackLen;
803
804 // Shrink the array.
805 // If more than one point already at the end, keep only the first of them.
806 int newLen = std::min( 1 + range.first, range.second );
807 mEnv.resize( newLen );
808
809 if ( needPoint )
810 AddPointAtEnd( mTrackLen, value );
811}

References AddPointAtEnd(), EqualRange(), GetValueRelative(), mEnv, min(), and mTrackLen.

Referenced by EqualizationFilter::EqualizationFilter(), and EqualizationBandSliders::GraphicEQ().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SolveIntegralOfInverse()

double Envelope::SolveIntegralOfInverse ( double  t0,
double  area 
) const

Definition at line 1306 of file Envelope.cpp.

1307{
1308 if(area == 0.0)
1309 return t0;
1310
1311 const auto count = mEnv.size();
1312 if(count == 0) // 'empty' envelope
1313 return t0 + area * mDefaultValue;
1314
1315 // Correct for offset!
1316 t0 -= mOffset;
1317 return mOffset + [&] {
1318 // Now we can safely assume t0 is relative time!
1319 double lastT, lastVal;
1320 int i; // this is the next point to check
1321 if(t0 < mEnv[0].GetT()) // t0 preceding the first point
1322 {
1323 if (area < 0) {
1324 return t0 + area * mEnv[0].GetVal();
1325 }
1326 else {
1327 i = 1;
1328 lastT = mEnv[0].GetT();
1329 lastVal = mEnv[0].GetVal();
1330 double added = (lastT - t0) / lastVal;
1331 if(added >= area)
1332 return t0 + area * mEnv[0].GetVal();
1333 area -= added;
1334 }
1335 }
1336 else if(t0 >= mEnv[count - 1].GetT()) // t0 at or following the last point
1337 {
1338 if (area < 0) {
1339 i = (int)count - 2;
1340 lastT = mEnv[count - 1].GetT();
1341 lastVal = mEnv[count - 1].GetVal();
1342 double added = (lastT - t0) / lastVal; // negative
1343 if(added <= area)
1344 return t0 + area * mEnv[count - 1].GetVal();
1345 area -= added;
1346 }
1347 else {
1348 return t0 + area * mEnv[count - 1].GetVal();
1349 }
1350 }
1351 else // t0 enclosed by points
1352 {
1353 // Skip any points that come before t0 using binary search
1354 int lo, hi;
1355 BinarySearchForTime(lo, hi, t0);
1356 lastVal = InterpolatePoints(mEnv[lo].GetVal(), mEnv[hi].GetVal(), (t0 - mEnv[lo].GetT()) / (mEnv[hi].GetT() - mEnv[lo].GetT()), mDB);
1357 lastT = t0;
1358 if (area < 0)
1359 i = lo;
1360 else
1361 i = hi; // the point immediately after t0.
1362 }
1363
1364 if (area < 0) {
1365 // loop BACKWARDS through the rest of the envelope points until we get to t1
1366 // (which is less than t0)
1367 while (1)
1368 {
1369 if(i < 0) // the requested range extends beyond the leftmost point
1370 {
1371 return lastT + area * lastVal;
1372 }
1373 else
1374 {
1375 double added =
1376 -IntegrateInverseInterpolated(mEnv[i].GetVal(), lastVal, lastT - mEnv[i].GetT(), mDB);
1377 if(added <= area)
1378 return lastT - SolveIntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), lastT - mEnv[i].GetT(), -area, mDB);
1379 area -= added;
1380 lastT = mEnv[i].GetT();
1381 lastVal = mEnv[i].GetVal();
1382 --i;
1383 }
1384 }
1385 }
1386 else {
1387 // loop through the rest of the envelope points until we get to t1
1388 while (1)
1389 {
1390 if(i >= (int)count) // the requested range extends beyond the last point
1391 {
1392 return lastT + area * lastVal;
1393 }
1394 else
1395 {
1396 double added = IntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, mDB);
1397 if(added >= area)
1398 return lastT + SolveIntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, area, mDB);
1399 area -= added;
1400 lastT = mEnv[i].GetT();
1401 lastVal = mEnv[i].GetVal();
1402 i++;
1403 }
1404 }
1405 }
1406 }();
1407}
static double SolveIntegrateInverseInterpolated(double y1, double y2, double time, double area, bool logarithmic)
Definition: Envelope.cpp:1153

References BinarySearchForTime(), IntegrateInverseInterpolated(), InterpolatePoints(), mDB, mDefaultValue, mEnv, mOffset, and SolveIntegrateInverseInterpolated().

Referenced by PlaybackSchedule::SolveWarpedLength().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ testMe()

void Envelope::testMe ( )

Definition at line 1424 of file Envelope.cpp.

1425{
1426 double t0=0, t1=0;
1427
1428 SetExponential(false);
1429
1430 Flatten(0.5);
1431 checkResult( 1, Integral(0.0,100.0), 50);
1432 checkResult( 2, Integral(-10.0,10.0), 10);
1433
1434 Flatten(0.5);
1435 checkResult( 3, Integral(0.0,100.0), 50);
1436 checkResult( 4, Integral(-10.0,10.0), 10);
1437 checkResult( 5, Integral(-20.0,-10.0), 5);
1438
1439 Flatten(0.5);
1440 InsertOrReplaceRelative( 5.0, 0.5 );
1441 checkResult( 6, Integral(0.0,100.0), 50);
1442 checkResult( 7, Integral(-10.0,10.0), 10);
1443
1444 Flatten(0.0);
1445 InsertOrReplaceRelative( 0.0, 0.0 );
1446 InsertOrReplaceRelative( 5.0, 1.0 );
1447 InsertOrReplaceRelative( 10.0, 0.0 );
1448 t0 = 10.0 - .1;
1449 t1 = 10.0 + .1;
1450 double result = Integral(0.0,t1);
1451 double resulta = Integral(0.0,t0);
1452 double resultb = Integral(t0,t1);
1453 // Integrals should be additive
1454 checkResult( 8, result - resulta - resultb, 0);
1455
1456 Flatten(0.0);
1457 InsertOrReplaceRelative( 0.0, 0.0 );
1458 InsertOrReplaceRelative( 5.0, 1.0 );
1459 InsertOrReplaceRelative( 10.0, 0.0 );
1460 t0 = 10.0 - .1;
1461 t1 = 10.0 + .1;
1462 checkResult( 9, Integral(0.0,t1), 5);
1463 checkResult( 10, Integral(0.0,t0), 4.999);
1464 checkResult( 11, Integral(t0,t1), .001);
1465
1466 mEnv.clear();
1467 InsertOrReplaceRelative( 0.0, 0.0 );
1468 InsertOrReplaceRelative( 5.0, 1.0 );
1469 InsertOrReplaceRelative( 10.0, 0.0 );
1470 checkResult( 12, NumberOfPointsAfter( -1 ), 3 );
1471 checkResult( 13, NumberOfPointsAfter( 0 ), 2 );
1472 checkResult( 14, NumberOfPointsAfter( 1 ), 2 );
1473 checkResult( 15, NumberOfPointsAfter( 5 ), 1 );
1474 checkResult( 16, NumberOfPointsAfter( 7 ), 1 );
1475 checkResult( 17, NumberOfPointsAfter( 10 ), 0 );
1476 checkResult( 18, NextPointAfter( 0 ), 5 );
1477 checkResult( 19, NextPointAfter( 5 ), 10 );
1478}
static void checkResult(int n, double a, double b)
Definition: Envelope.cpp:1415
int NumberOfPointsAfter(double t) const
Definition: Envelope.cpp:1062
double NextPointAfter(double t) const
Definition: Envelope.cpp:1071
void SetExponential(bool db)
Definition: Envelope.h:96
void Flatten(double value)
Definition: Envelope.cpp:138

References checkResult(), Flatten(), InsertOrReplaceRelative(), Integral(), mEnv, NextPointAfter(), NumberOfPointsAfter(), and SetExponential().

Here is the call graph for this function:

◆ WriteXML()

void Envelope::WriteXML ( XMLWriter xmlFile) const

Definition at line 343 of file Envelope.cpp.

345{
346 unsigned int ctrlPt;
347
348 xmlFile.StartTag(wxT("envelope"));
349 xmlFile.WriteAttr(wxT("numpoints"), mEnv.size());
350
351 for (ctrlPt = 0; ctrlPt < mEnv.size(); ctrlPt++) {
352 const EnvPoint &point = mEnv[ctrlPt];
353 xmlFile.StartTag(wxT("controlpoint"));
354 xmlFile.WriteAttr(wxT("t"), point.GetT(), 12);
355 xmlFile.WriteAttr(wxT("val"), point.GetVal(), 12);
356 xmlFile.EndTag(wxT("controlpoint"));
357 }
358
359 xmlFile.EndTag(wxT("envelope"));
360}
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:79
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:36
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:102

References EnvPoint::GetT(), EnvPoint::GetVal(), and wxT().

Here is the call graph for this function:

Member Data Documentation

◆ mDB

bool Envelope::mDB
private

◆ mDefaultValue

double Envelope::mDefaultValue
private

◆ mDragPoint

int Envelope::mDragPoint { -1 }
private

◆ mDragPointValid

bool Envelope::mDragPointValid { false }
private

Definition at line 255 of file Envelope.h.

Referenced by ClearDragPoint(), MoveDragPoint(), SetDragPoint(), and SetDragPointValid().

◆ mEnv

EnvArray Envelope::mEnv
private

◆ mMaxValue

double Envelope::mMaxValue
private

Definition at line 251 of file Envelope.h.

Referenced by RescaleValues(), and SetRange().

◆ mMinValue

double Envelope::mMinValue
private

Definition at line 251 of file Envelope.h.

Referenced by RescaleValues(), and SetRange().

◆ mOffset

double Envelope::mOffset { 0.0 }
private

The time at which the envelope starts, i.e. the start offset.

Definition at line 240 of file Envelope.h.

Referenced by CollapseRegion(), CopyRange(), Envelope(), GetPoints(), GetValues(), InsertSpace(), Integral(), IntegralOfInverse(), PasteEnvelope(), Reassign(), SetOffset(), and SolveIntegralOfInverse().

◆ mSearchGuess

int Envelope::mSearchGuess { -2 }
mutableprivate

Definition at line 258 of file Envelope.h.

Referenced by BinarySearchForTime(), and BinarySearchForTime_LeftLimit().

◆ mTrackEpsilon

double Envelope::mTrackEpsilon { 1.0 / 200000.0 }
private

The shortest distance apart that points on an envelope can be before being considered the same point.

Definition at line 249 of file Envelope.h.

◆ mTrackLen

double Envelope::mTrackLen { 0.0 }
private

The length of the envelope, which is the same as the length of the underlying track (normally)

Definition at line 243 of file Envelope.h.

Referenced by Cap(), CollapseRegion(), CopyRange(), Envelope(), ExpandRegion(), InsertOrReplaceRelative(), MoveDragPoint(), PasteEnvelope(), RescaleTimes(), RescaleTimesBy(), and SetTrackLen().


The documentation for this class was generated from the following files: