Audacity  3.0.3
Public Member Functions | Static 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 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 wxChar *tag, const wxChar **attrs) override
 
XMLTagHandlerHandleXMLChild (const wxChar *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)
 
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 void HandleXMLEndTag (const wxChar *WXUNUSED(tag))
 
virtual void HandleXMLContent (const wxString &WXUNUSED(content))
 
bool ReadXMLTag (const char *tag, const char **attrs)
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 

Static Public Member Functions

static void GetValues (const Envelope &env, double aligned_time, double sampleDur, double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo)
 Get many envelope points for pixel columns at once, but don't assume uniform time per pixel. More...
 

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 71 of file Envelope.h.

Constructor & Destructor Documentation

◆ Envelope() [1/3]

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

Definition at line 45 of file Envelope.cpp.

46  : mDB(exponential)
47  , mMinValue(minValue)
48  , mMaxValue(maxValue)
49  , mDefaultValue { ClampValue(defaultValue) }
50 {
51 }

References ClampValue().

Here is the call graph for this function:

◆ Envelope() [2/3]

Envelope::Envelope ( const Envelope orig)

Definition at line 259 of file Envelope.cpp.

260  : mDB(orig.mDB)
261  , mMinValue(orig.mMinValue)
262  , mMaxValue(orig.mMaxValue)
264 {
265  mOffset = orig.mOffset;
266  mTrackLen = orig.mTrackLen;
267  CopyRange(orig, 0, orig.GetNumberOfPoints());
268 }

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 245 of file Envelope.cpp.

246  : mDB(orig.mDB)
247  , mMinValue(orig.mMinValue)
248  , mMaxValue(orig.mMaxValue)
250 {
251  mOffset = wxMax(t0, orig.mOffset);
252  mTrackLen = wxMin(t1, orig.mOffset + orig.mTrackLen) - mOffset;
253 
254  auto range1 = orig.EqualRange( t0 - orig.mOffset, 0 );
255  auto range2 = orig.EqualRange( t1 - orig.mOffset, 0 );
256  CopyRange(orig, range1.first, range2.second);
257 }

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

Here is the call graph for this function:

◆ ~Envelope()

Envelope::~Envelope ( )
virtual

Definition at line 53 of file Envelope.cpp.

54 {
55 }

Member Function Documentation

◆ AddPointAtEnd()

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

Definition at line 228 of file Envelope.cpp.

229 {
230  mEnv.push_back( EnvPoint{ t, val } );
231 
232  // Assume copied points were stored by nondecreasing time.
233  // Allow no more than two points at exactly the same time.
234  // Maybe that happened, because extra points were inserted at the boundary
235  // of the copied range, which were not in the source envelope.
236  auto nn = mEnv.size() - 1;
237  while ( nn >= 2 && mEnv[ nn - 2 ].GetT() == t ) {
238  // Of three or more points at the same time, erase one in the middle,
239  // not the one newly added.
240  mEnv.erase( mEnv.begin() + nn - 1 );
241  --nn;
242  }
243 }

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 1071 of file Envelope.cpp.

1072 {
1073  if( t0 == t1 )
1074  return GetValue( t0 );
1075  else
1076  return Integral( t0, t1 ) / (t1 - t0);
1077 }

References GetValue(), and Integral().

Here is the call graph for this function:

◆ AverageOfInverse()

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

Definition at line 1079 of file Envelope.cpp.

1080 {
1081  if( t0 == t1 )
1082  return 1.0 / GetValue( t0 );
1083  else
1084  return IntegralOfInverse( t0, t1 ) / (t1 - t0);
1085 }

References GetValue(), and IntegralOfInverse().

Referenced by anonymous_namespace{Mix.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 847 of file Envelope.cpp.

848 {
849  // Optimizations for the usual pattern of repeated calls with
850  // small increases of t.
851  {
852  if (mSearchGuess >= 0 && mSearchGuess < (int)mEnv.size()) {
853  if (t >= mEnv[mSearchGuess].GetT() &&
854  (1 + mSearchGuess == (int)mEnv.size() ||
855  t < mEnv[1 + mSearchGuess].GetT())) {
856  Lo = mSearchGuess;
857  Hi = 1 + mSearchGuess;
858  return;
859  }
860  }
861 
862  ++mSearchGuess;
863  if (mSearchGuess >= 0 && mSearchGuess < (int)mEnv.size()) {
864  if (t >= mEnv[mSearchGuess].GetT() &&
865  (1 + mSearchGuess == (int)mEnv.size() ||
866  t < mEnv[1 + mSearchGuess].GetT())) {
867  Lo = mSearchGuess;
868  Hi = 1 + mSearchGuess;
869  return;
870  }
871  }
872  }
873 
874  Lo = -1;
875  Hi = mEnv.size();
876 
877  // Invariants: Lo is not less than -1, Hi not more than size
878  while (Hi > (Lo + 1)) {
879  int mid = (Lo + Hi) / 2;
880  // mid must be strictly between Lo and Hi, therefore a valid index
881  if (t < mEnv[mid].GetT())
882  Hi = mid;
883  else
884  Lo = mid;
885  }
886  wxASSERT( Hi == ( Lo+1 ));
887 
888  mSearchGuess = Lo;
889 }

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 894 of file Envelope.cpp.

895 {
896  Lo = -1;
897  Hi = mEnv.size();
898 
899  // Invariants: Lo is not less than -1, Hi not more than size
900  while (Hi > (Lo + 1)) {
901  int mid = (Lo + Hi) / 2;
902  // mid must be strictly between Lo and Hi, therefore a valid index
903  if (t <= mEnv[mid].GetT())
904  Hi = mid;
905  else
906  Lo = mid;
907  }
908  wxASSERT( Hi == ( Lo+1 ));
909 
910  mSearchGuess = Lo;
911 }

References mEnv, and mSearchGuess.

Referenced by GetValuesRelative().

Here is the caller graph for this function:

◆ Cap()

void Envelope::Cap ( double  sampleDur)

Definition at line 712 of file Envelope.cpp.

713 {
714  auto range = EqualRange( mTrackLen, sampleDur );
715  if ( range.first == range.second )
717 }

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

Here is the call graph for this function:

◆ ClampValue()

double Envelope::ClampValue ( double  value)
inline

Definition at line 110 of file Envelope.h.

110 { return std::max(mMinValue, std::min(mMaxValue, value)); }

References min().

Referenced by SetEnvelopeCommand::ApplyInner(), Envelope(), 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 178 of file Envelope.h.

178 { mEnv.clear(); }

Referenced by SetEnvelopeCommand::ApplyInner().

Here is the caller graph for this function:

◆ ClearDragPoint()

void Envelope::ClearDragPoint ( )

Definition at line 209 of file Envelope.cpp.

210 {
211  if (!mDragPointValid && mDragPoint >= 0)
213 
214  mDragPoint = -1;
215  mDragPointValid = false;
216 }

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 376 of file Envelope.cpp.

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

References EqualRange(), GetValueRelative(), InsertOrReplaceRelative(), mEnv, min(), mOffset, mTrackLen, and RemoveUnneededPoints().

Referenced by WaveClip::Clear(), and WaveClip::ClearAndAddCutLine().

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

◆ ConsistencyCheck()

bool Envelope::ConsistencyCheck ( )

Definition at line 57 of file Envelope.cpp.

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

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 270 of file Envelope.cpp.

271 {
272  size_t len = orig.mEnv.size();
273  size_t i = begin;
274 
275  // Create the point at 0 if it needs interpolated representation
276  if ( i > 0 )
277  AddPointAtEnd(0, orig.GetValue(mOffset));
278 
279  // Copy points from inside the copied region
280  for (; i < end; ++i) {
281  const EnvPoint &point = orig[i];
282  const double when = point.GetT() + (orig.mOffset - mOffset);
283  AddPointAtEnd(when, point.GetVal());
284  }
285 
286  // Create the final point if it needs interpolated representation
287  // If the last point of e was exactly at t1, this effectively copies it too.
288  if (mTrackLen > 0 && i < len)
290 }

References AddPointAtEnd(), 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 360 of file Envelope.cpp.

361 {
362  mEnv.erase(mEnv.begin() + point);
363 }

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 761 of file Envelope.cpp.

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

References 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 613 of file Envelope.cpp.

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

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 134 of file Envelope.cpp.

135 {
136  mEnv.clear();
137  mDefaultValue = ClampValue(value);
138 }

References ClampValue(), mDefaultValue, and mEnv.

Referenced by EffectEqualization::GraphicEQ(), EffectEqualization::setCurve(), 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 221 of file Envelope.h.

221 { 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 226 of file Envelope.h.

226 { return mDragPointValid; }

Referenced by EnvelopeEditor::HandleDragging().

Here is the caller graph for this function:

◆ GetExponential()

bool Envelope::GetExponential ( ) const
inline

Definition at line 101 of file Envelope.h.

101 { return mDB; }

Referenced by GetValues().

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 918 of file Envelope.cpp.

919 {
920  double v = mEnv[ iPoint ].GetVal();
921  if( !mDB )
922  return v;
923  else
924  return log10(v);
925 }

References mDB, and mEnv.

Referenced by GetValuesRelative().

Here is the caller graph for this function:

◆ GetMaxValue()

double Envelope::GetMaxValue ( ) const
inline

Definition at line 107 of file Envelope.h.

107 { return mMaxValue; }

◆ GetMinValue()

double Envelope::GetMinValue ( ) const
inline

Definition at line 106 of file Envelope.h.

106 { return mMinValue; }

◆ GetNumberOfPoints()

size_t Envelope::GetNumberOfPoints ( ) const

Return number of points.

Definition at line 693 of file Envelope.cpp.

694 {
695  return mEnv.size();
696 }

References mEnv.

Referenced by EnvelopeEditor::DrawPoints(), Envelope(), EffectEqualization::EnvelopeUpdated(), EnvelopeEditor::HandleMouseButtonDown(), and GetInfoCommand::SendEnvelopes().

Here is the caller graph for this function:

◆ GetOffset()

double Envelope::GetOffset ( ) const
inline

Definition at line 98 of file Envelope.h.

98 { 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 698 of file Envelope.cpp.

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

References mEnv, and mOffset.

Referenced by EffectEqualization::EnvelopeUpdated().

Here is the caller graph for this function:

◆ GetTrackLen()

double Envelope::GetTrackLen ( ) const
inline

Definition at line 99 of file Envelope.h.

99 { return mTrackLen; }

◆ GetValue()

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

Get envelope value at time t.

Definition at line 827 of file Envelope.cpp.

828 {
829  // t is absolute time
830  double temp;
831 
832  GetValues( &temp, 1, t, sampleDur );
833  return temp;
834 }

References GetValues().

Referenced by Average(), AverageOfInverse(), CopyRange(), anonymous_namespace{WaveformView.cpp}::DrawIndividualSamples(), SampleHandle::FindSampleEditingLevel(), GetValues(), 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 836 of file Envelope.cpp.

837 {
838  double temp;
839 
840  GetValuesRelative(&temp, 1, t, 0.0, leftLimit);
841  return temp;
842 }

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() [1/2]

void Envelope::GetValues ( const Envelope env,
double  aligned_time,
double  sampleDur,
double *  buffer,
int  bufferLen,
int  leftOffset,
const ZoomInfo zoomInfo 
)
static

Get many envelope points for pixel columns at once, but don't assume uniform time per pixel.

Definition at line 1471 of file Envelope.cpp.

1476 {
1477  // Getting many envelope values, corresponding to pixel columns, which may
1478  // not be uniformly spaced in time when there is a fisheye.
1479 
1480  double prevDiscreteTime=0.0, prevSampleVal=0.0, nextSampleVal=0.0;
1481  for ( int xx = 0; xx < bufferLen; ++xx ) {
1482  auto time = zoomInfo.PositionToTime( xx, -leftOffset );
1483  if ( sampleDur <= 0 )
1484  // Sample interval not defined (as for time track)
1485  buffer[xx] = env.GetValue( time );
1486  else {
1487  // The level of zoom-in may resolve individual samples.
1488  // If so, then instead of evaluating the envelope directly,
1489  // we draw a piecewise curve with knees at each sample time.
1490  // This actually makes clearer what happens as you drag envelope
1491  // points and make discontinuities.
1492  auto leftDiscreteTime = alignedTime +
1493  sampleDur * floor( ( time - alignedTime ) / sampleDur );
1494  if ( xx == 0 || leftDiscreteTime != prevDiscreteTime ) {
1495  prevDiscreteTime = leftDiscreteTime;
1496  prevSampleVal =
1497  env.GetValue( prevDiscreteTime, sampleDur );
1498  nextSampleVal =
1499  env.GetValue( prevDiscreteTime + sampleDur, sampleDur );
1500  }
1501  auto ratio = ( time - leftDiscreteTime ) / sampleDur;
1502  if ( env.GetExponential() )
1503  buffer[ xx ] = exp(
1504  ( 1.0 - ratio ) * log( prevSampleVal )
1505  + ratio * log( nextSampleVal ) );
1506  else
1507  buffer[ xx ] =
1508  ( 1.0 - ratio ) * prevSampleVal + ratio * nextSampleVal;
1509  }
1510  }
1511 }

References GetExponential(), GetValue(), and ZoomInfo::PositionToTime().

Referenced by anonymous_namespace{WaveformView.cpp}::DrawClipWaveform(), anonymous_namespace{TimeTrackView.cpp}::DrawHorzRulerAndCurve(), GetValue(), and EqualizationPanel::OnPaint().

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

◆ GetValues() [2/2]

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 927 of file Envelope.cpp.

929 {
930  // Convert t0 from absolute to clip-relative time
931  t0 -= mOffset;
932  GetValuesRelative( buffer, bufferLen, t0, tstep);
933 }

References GetValuesRelative(), and mOffset.

Here is the call graph for this function:

◆ GetValuesRelative()

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

Definition at line 935 of file Envelope.cpp.

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

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 wxChar *  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 332 of file Envelope.cpp.

333 {
334  if (wxStrcmp(tag, wxT("controlpoint")))
335  return NULL;
336 
337  mEnv.push_back( EnvPoint{} );
338  return &mEnv.back();
339 }

References mEnv.

Referenced by AUPImportFileHandle::HandleControlPoint().

Here is the caller graph for this function:

◆ HandleXMLTag()

bool Envelope::HandleXMLTag ( const wxChar *  tag,
const wxChar **  attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 305 of file Envelope.cpp.

306 {
307  // Return unless it's the envelope tag.
308  if (wxStrcmp(tag, wxT("envelope")))
309  return false;
310 
311  int numPoints = 0;
312  long nValue = -1;
313 
314  while (*attrs) {
315  const wxChar *attr = *attrs++;
316  const wxChar *value = *attrs++;
317  if (!value)
318  break;
319  const wxString strValue = value;
320  if( !wxStrcmp(attr, wxT("numpoints")) &&
321  XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
322  numPoints = nValue;
323  }
324  if (numPoints < 0)
325  return false;
326 
327  mEnv.clear();
328  mEnv.reserve(numPoints);
329  return true;
330 }

References XMLValueChecker::IsGoodInt(), and mEnv.

Here is the call graph for this function:

◆ Initialize()

void Envelope::Initialize ( int  numPoints)

◆ Insert() [1/2]

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

Definition at line 370 of file Envelope.cpp.

371 {
372  mEnv.push_back( EnvPoint{ when, value });
373 }

References mEnv.

◆ Insert() [2/2]

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

insert a point

Definition at line 365 of file Envelope.cpp.

366 {
367  mEnv.insert(mEnv.begin() + point, p);
368 }

References mEnv.

Referenced by ExpandRegion(), EffectEqualization::GraphicEQ(), InsertOrReplaceRelative(), EffectEqualization::ProcessOne(), RemoveUnneededPoints(), and EffectEqualization::setCurve().

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 181 of file Envelope.h.

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

Referenced by SetEnvelopeCommand::ApplyInner(), 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 727 of file Envelope.cpp.

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

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

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 664 of file Envelope.cpp.

665 {
666  auto range = ExpandRegion( t0 - mOffset, tlen, nullptr, nullptr );
667 
668  // Simplify the boundaries if possible
669  RemoveUnneededPoints( range.second, true );
670  RemoveUnneededPoints( range.first - 1, false );
671 }

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 1170 of file Envelope.cpp.

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

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

Referenced by Average(), 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 1233 of file Envelope.cpp.

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

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

Referenced by AverageOfInverse(), anonymous_namespace{PlaybackSchedule.cpp}::ComputeWarpedLength(), anonymous_namespace{Ruler.cpp}::ComputeWarpedLength(), and TimeTrack::testMe().

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

◆ IsDirty()

bool Envelope::IsDirty ( ) const

◆ MoveDragPoint()

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

Definition at line 183 of file Envelope.cpp.

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

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 1061 of file Envelope.cpp.

1062 {
1063  int lo,hi;
1064  BinarySearchForTime( lo, hi, t );
1065  if (hi >= (int)mEnv.size())
1066  return t;
1067  else
1068  return mEnv[hi].GetT();
1069 }

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 1052 of file Envelope.cpp.

1053 {
1054  int lo,hi;
1055  BinarySearchForTime( lo, hi, t );
1056 
1057  return mEnv.size() - hi;
1058 }

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 203 of file Envelope.h.

204  {
205  return mEnv[index];
206  }

◆ PasteEnvelope()

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

Definition at line 464 of file Envelope.cpp.

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

References ConsistencyCheck(), 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 1399 of file Envelope.cpp.

1400 {
1401  for( unsigned int i = 0; i < mEnv.size(); i++ )
1402  wxPrintf( "(%.2f, %.2f)\n", mEnv[i].GetT(), mEnv[i].GetVal() );
1403 }

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 673 of file Envelope.cpp.

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

References mEnv, and mOffset.

Referenced by EffectEqualization::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 547 of file Envelope.cpp.

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

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 812 of file Envelope.cpp.

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

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 112 of file Envelope.cpp.

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

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

Here is the call graph for this function:

◆ SetDragPoint()

void Envelope::SetDragPoint ( int  dragPoint)

Definition at line 140 of file Envelope.cpp.

141 {
142  mDragPoint = std::max(-1, std::min(int(mEnv.size() - 1), dragPoint));
143  mDragPointValid = (mDragPoint >= 0);
144 }

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 146 of file Envelope.cpp.

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

References mDefaultValue, mDragPoint, mDragPointValid, and mEnv.

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

Here is the caller graph for this function:

◆ SetExponential()

void Envelope::SetExponential ( bool  db)
inline

Definition at line 102 of file Envelope.h.

102 { 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 785 of file Envelope.cpp.

786 {
787  mOffset = newOffset;
788 }

References mOffset.

◆ SetRange()

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

Definition at line 218 of file Envelope.cpp.

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

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 791 of file Envelope.cpp.

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

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

Referenced by EffectEqualization::GraphicEQ(), and EffectEqualization::setCurve().

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 1296 of file Envelope.cpp.

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

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

Referenced by anonymous_namespace{PlaybackSchedule.cpp}::SolveWarpedLength(), and anonymous_namespace{Ruler.cpp}::SolveWarpedLength().

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

◆ testMe()

void Envelope::testMe ( )

Definition at line 1414 of file Envelope.cpp.

1415 {
1416  double t0=0, t1=0;
1417 
1418  SetExponential(false);
1419 
1420  Flatten(0.5);
1421  checkResult( 1, Integral(0.0,100.0), 50);
1422  checkResult( 2, Integral(-10.0,10.0), 10);
1423 
1424  Flatten(0.5);
1425  checkResult( 3, Integral(0.0,100.0), 50);
1426  checkResult( 4, Integral(-10.0,10.0), 10);
1427  checkResult( 5, Integral(-20.0,-10.0), 5);
1428 
1429  Flatten(0.5);
1430  InsertOrReplaceRelative( 5.0, 0.5 );
1431  checkResult( 6, Integral(0.0,100.0), 50);
1432  checkResult( 7, Integral(-10.0,10.0), 10);
1433 
1434  Flatten(0.0);
1435  InsertOrReplaceRelative( 0.0, 0.0 );
1436  InsertOrReplaceRelative( 5.0, 1.0 );
1437  InsertOrReplaceRelative( 10.0, 0.0 );
1438  t0 = 10.0 - .1;
1439  t1 = 10.0 + .1;
1440  double result = Integral(0.0,t1);
1441  double resulta = Integral(0.0,t0);
1442  double resultb = Integral(t0,t1);
1443  // Integrals should be additive
1444  checkResult( 8, result - resulta - resultb, 0);
1445 
1446  Flatten(0.0);
1447  InsertOrReplaceRelative( 0.0, 0.0 );
1448  InsertOrReplaceRelative( 5.0, 1.0 );
1449  InsertOrReplaceRelative( 10.0, 0.0 );
1450  t0 = 10.0 - .1;
1451  t1 = 10.0 + .1;
1452  checkResult( 9, Integral(0.0,t1), 5);
1453  checkResult( 10, Integral(0.0,t0), 4.999);
1454  checkResult( 11, Integral(t0,t1), .001);
1455 
1456  mEnv.clear();
1457  InsertOrReplaceRelative( 0.0, 0.0 );
1458  InsertOrReplaceRelative( 5.0, 1.0 );
1459  InsertOrReplaceRelative( 10.0, 0.0 );
1460  checkResult( 12, NumberOfPointsAfter( -1 ), 3 );
1461  checkResult( 13, NumberOfPointsAfter( 0 ), 2 );
1462  checkResult( 14, NumberOfPointsAfter( 1 ), 2 );
1463  checkResult( 15, NumberOfPointsAfter( 5 ), 1 );
1464  checkResult( 16, NumberOfPointsAfter( 7 ), 1 );
1465  checkResult( 17, NumberOfPointsAfter( 10 ), 0 );
1466  checkResult( 18, NextPointAfter( 0 ), 5 );
1467  checkResult( 19, NextPointAfter( 5 ), 10 );
1468 }

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 341 of file Envelope.cpp.

343 {
344  unsigned int ctrlPt;
345 
346  xmlFile.StartTag(wxT("envelope"));
347  xmlFile.WriteAttr(wxT("numpoints"), mEnv.size());
348 
349  for (ctrlPt = 0; ctrlPt < mEnv.size(); ctrlPt++) {
350  const EnvPoint &point = mEnv[ctrlPt];
351  xmlFile.StartTag(wxT("controlpoint"));
352  xmlFile.WriteAttr(wxT("t"), point.GetT(), 12);
353  xmlFile.WriteAttr(wxT("val"), point.GetVal(), 12);
354  xmlFile.EndTag(wxT("controlpoint"));
355  }
356 
357  xmlFile.EndTag(wxT("envelope"));
358 }

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

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 260 of file Envelope.h.

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

◆ mEnv

EnvArray Envelope::mEnv
private

◆ mMaxValue

double Envelope::mMaxValue
private

Definition at line 256 of file Envelope.h.

Referenced by RescaleValues(), and SetRange().

◆ mMinValue

double Envelope::mMinValue
private

Definition at line 256 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 245 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 263 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 254 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 248 of file Envelope.h.

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


The documentation for this class was generated from the following files:
XMLWriter::EndTag
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:100
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
XMLValueChecker::IsGoodInt
static bool IsGoodInt(const wxString &strInt)
Check that the supplied string can be converted to a long (32bit) integer.
Definition: XMLTagHandler.cpp:160
Envelope::mTrackLen
double mTrackLen
The length of the envelope, which is the same as the length of the underlying track (normally)
Definition: Envelope.h:248
Envelope::mSearchGuess
int mSearchGuess
Definition: Envelope.h:263
Envelope::ExpandRegion
std::pair< int, int > ExpandRegion(double t0, double tlen, double *pLeftVal, double *pRightVal)
Definition: Envelope.cpp:614
Envelope::mDB
bool mDB
Definition: Envelope.h:255
Envelope::mDefaultValue
double mDefaultValue
Definition: Envelope.h:257
Envelope::Insert
void Insert(int point, const EnvPoint &p)
insert a point
Definition: Envelope.cpp:365
Envelope::ClampValue
double ClampValue(double value)
Definition: Envelope.h:110
Envelope::IntegralOfInverse
double IntegralOfInverse(double t0, double t1) const
Definition: Envelope.cpp:1233
Envelope::BinarySearchForTime
void BinarySearchForTime(int &Lo, int &Hi, double t) const
Definition: Envelope.cpp:847
Envelope::GetExponential
bool GetExponential() const
Definition: Envelope.h:101
Envelope::ConsistencyCheck
bool ConsistencyCheck()
Definition: Envelope.cpp:57
checkResult
static void checkResult(int n, double a, double b)
Definition: Envelope.cpp:1405
Envelope::mMaxValue
double mMaxValue
Definition: Envelope.h:256
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
InterpolatePoints
static double InterpolatePoints(double y1, double y2, double factor, bool logarithmic)
Definition: Envelope.cpp:1097
Envelope::SetDragPointValid
void SetDragPointValid(bool valid)
Definition: Envelope.cpp:146
Envelope::mOffset
double mOffset
The time at which the envelope starts, i.e. the start offset.
Definition: Envelope.h:245
Envelope::NumberOfPointsAfter
int NumberOfPointsAfter(double t) const
Definition: Envelope.cpp:1052
Envelope::InsertOrReplaceRelative
int InsertOrReplaceRelative(double when, double value)
Add a control point to the envelope.
Definition: Envelope.cpp:727
Envelope::BinarySearchForTime_LeftLimit
void BinarySearchForTime_LeftLimit(int &Lo, int &Hi, double t) const
Definition: Envelope.cpp:894
Envelope::mDragPoint
int mDragPoint
Definition: Envelope.h:261
Envelope::GetInterpolationStartValueAtPoint
double GetInterpolationStartValueAtPoint(int iPoint) const
Definition: Envelope.cpp:918
EnvPoint::GetT
double GetT() const
Definition: Envelope.h:35
Envelope::GetValuesRelative
void GetValuesRelative(double *buffer, int len, double t0, double tstep, bool leftLimit=false) const
Definition: Envelope.cpp:936
SolveIntegrateInverseInterpolated
static double SolveIntegrateInverseInterpolated(double y1, double y2, double time, double area, bool logarithmic)
Definition: Envelope.cpp:1143
VALUE_TOLERANCE
static const double VALUE_TOLERANCE
Definition: Envelope.cpp:43
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
Envelope::GetValue
double GetValue(double t, double sampleDur=0) const
Get envelope value at time t.
Definition: Envelope.cpp:827
Envelope::CopyRange
void CopyRange(const Envelope &orig, size_t begin, size_t end)
Definition: Envelope.cpp:270
IntegrateInterpolated
static double IntegrateInterpolated(double y1, double y2, double time, bool logarithmic)
Definition: Envelope.cpp:1105
XMLWriter::WriteAttr
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:34
Envelope::Delete
void Delete(int point)
DELETE a point by its position in array.
Definition: Envelope.cpp:360
Envelope::mEnv
EnvArray mEnv
Definition: Envelope.h:242
Envelope::RemoveUnneededPoints
void RemoveUnneededPoints(size_t startAt, bool rightward, bool testNeighbors=true)
Definition: Envelope.cpp:548
Envelope::Flatten
void Flatten(double value)
Definition: Envelope.cpp:134
IntegrateInverseInterpolated
static double IntegrateInverseInterpolated(double y1, double y2, double time, bool logarithmic)
Definition: Envelope.cpp:1126
Envelope::NextPointAfter
double NextPointAfter(double t) const
Definition: Envelope.cpp:1061
Envelope::Integral
double Integral(double t0, double t1) const
Definition: Envelope.cpp:1170
Envelope::mDragPointValid
bool mDragPointValid
Definition: Envelope.h:260
XMLWriter::StartTag
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:77
Envelope::AddPointAtEnd
void AddPointAtEnd(double t, double val)
Definition: Envelope.cpp:228
Envelope::GetValues
static void GetValues(const Envelope &env, double aligned_time, double sampleDur, double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo)
Get many envelope points for pixel columns at once, but don't assume uniform time per pixel.
Definition: Envelope.cpp:1472
Envelope::EqualRange
std::pair< int, int > EqualRange(double when, double sampleDur) const
Definition: Envelope.cpp:761
Envelope::GetNumberOfPoints
size_t GetNumberOfPoints() const
Return number of points.
Definition: Envelope.cpp:693
Envelope::GetValueRelative
double GetValueRelative(double t, bool leftLimit=false) const
Definition: Envelope.cpp:836
ZoomInfo::PositionToTime
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ZoomInfo.cpp:43