mirror of
https://github.com/cookiengineer/audacity
synced 2026-03-10 16:35:32 +01:00
Commit most of patch-envelope-range-2.patch from Maarten Baert, excluding an unrelated change and some independent ones already committed. There is an outstanding potential issue with the TimeTrack:: copy constructor awaiting further input
This commit is contained in:
279
src/Envelope.cpp
279
src/Envelope.cpp
@@ -60,6 +60,9 @@ Envelope::Envelope()
|
||||
mDirty = false;
|
||||
mIsDeleting = false;
|
||||
mMirror = true;
|
||||
|
||||
mMinValue = 1.0e-7;
|
||||
mMaxValue = 2.0;
|
||||
|
||||
mButton = wxMOUSE_BTN_NONE;
|
||||
}
|
||||
@@ -81,7 +84,15 @@ void Envelope::Mirror(bool mirror)
|
||||
void Envelope::Flatten(double value)
|
||||
{
|
||||
WX_CLEAR_ARRAY(mEnv);
|
||||
SetDefaultValue(value);
|
||||
mDefaultValue = ClampValue(value);
|
||||
}
|
||||
|
||||
void Envelope::SetRange(double minValue, double maxValue) {
|
||||
mMinValue = minValue;
|
||||
mMaxValue = maxValue;
|
||||
mDefaultValue = ClampValue(mDefaultValue);
|
||||
for( unsigned int i = 0; i < mEnv.Count(); i++ )
|
||||
mEnv[i]->SetVal(mEnv[i]->GetVal()); // this clamps the value to the new range
|
||||
}
|
||||
|
||||
EnvPoint * Envelope::AddPointAtEnd( double t, double val )
|
||||
@@ -90,9 +101,7 @@ EnvPoint * Envelope::AddPointAtEnd( double t, double val )
|
||||
// TODO: switch over to using an array of EnvPoints
|
||||
// rather than an array of pointers to EnvPoints.
|
||||
// What value does that add?
|
||||
EnvPoint *pt = new EnvPoint();
|
||||
pt->t = t;
|
||||
pt->val = val;
|
||||
EnvPoint *pt = new EnvPoint(this, t, val);
|
||||
mEnv.Add(pt);
|
||||
return pt;
|
||||
}
|
||||
@@ -109,7 +118,7 @@ void Envelope::CopyFrom(const Envelope *e, double t0, double t1)
|
||||
int i = 0;
|
||||
|
||||
// Skip the points that come before the copied region
|
||||
while( (i < len) && e->mOffset + e->mEnv[i]->t <= t0)
|
||||
while( (i < len) && e->mOffset + e->mEnv[i]->GetT() <= t0)
|
||||
i++;
|
||||
|
||||
// Create the point at 0 if it needs interpolated representation
|
||||
@@ -117,8 +126,8 @@ void Envelope::CopyFrom(const Envelope *e, double t0, double t1)
|
||||
AddPointAtEnd( 0, e->GetValue(mOffset) );
|
||||
|
||||
// Copy points from inside the copied region
|
||||
while ( (i < len) && e->mOffset + e->mEnv[i]->t - mOffset < mTrackLen) {
|
||||
AddPointAtEnd( e->mOffset + e->mEnv[i]->t - mOffset, e->mEnv[i]->val );
|
||||
while ( (i < len) && e->mOffset + e->mEnv[i]->GetT() - mOffset < mTrackLen) {
|
||||
AddPointAtEnd( e->mOffset + e->mEnv[i]->GetT() - mOffset, e->mEnv[i]->GetVal() );
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -190,15 +199,15 @@ void Envelope::DrawPoints(wxDC & dc, const wxRect & r, double h, double pps, boo
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
|
||||
for (int i = 0; i < (int)mEnv.Count(); i++) {
|
||||
if (mEnv[i]->t >= h && mEnv[i]->t <= tright) {
|
||||
if (mEnv[i]->GetT() >= h && mEnv[i]->GetT() <= tright) {
|
||||
// Change colour if this is the draggable point...
|
||||
if (i == mDragPoint) {
|
||||
dc.SetPen(AColor::envelopePen);
|
||||
dc.SetBrush(AColor::envelopeBrush);
|
||||
}
|
||||
|
||||
double v = mEnv[i]->val;
|
||||
int x = int ((mEnv[i]->t - h) * pps);
|
||||
double v = mEnv[i]->GetVal();
|
||||
int x = int ((mEnv[i]->GetT() - h) * pps);
|
||||
int y, y2;
|
||||
|
||||
y = GetWaveYPos(v, zoomMin, zoomMax, r.height, dB,
|
||||
@@ -286,8 +295,8 @@ void Envelope::WriteXML(XMLWriter &xmlFile)
|
||||
|
||||
for (ctrlPt = 0; ctrlPt < mEnv.GetCount(); ctrlPt++) {
|
||||
xmlFile.StartTag(wxT("controlpoint"));
|
||||
xmlFile.WriteAttr(wxT("t"), mEnv[ctrlPt]->t, 12);
|
||||
xmlFile.WriteAttr(wxT("val"), mEnv[ctrlPt]->val, 12);
|
||||
xmlFile.WriteAttr(wxT("t"), mEnv[ctrlPt]->GetT(), 12);
|
||||
xmlFile.WriteAttr(wxT("val"), mEnv[ctrlPt]->GetVal(), 12);
|
||||
xmlFile.EndTag(wxT("controlpoint"));
|
||||
}
|
||||
|
||||
@@ -305,10 +314,8 @@ void Envelope::WriteXML(XMLWriter &xmlFile)
|
||||
/// @dB - display mode either linear or log.
|
||||
/// @zoomMin - vertical scale, typically -1.0
|
||||
/// @zoomMax - vertical scale, typically +1.0
|
||||
/// @eMin - clips result to this range.
|
||||
/// @eMax - clips result to this range.
|
||||
float Envelope::ValueOfPixel( int y, int height, bool upper, bool dB,
|
||||
float zoomMin, float zoomMax, float eMin, float eMax )
|
||||
float zoomMin, float zoomMax)
|
||||
{
|
||||
float v;
|
||||
|
||||
@@ -324,22 +331,12 @@ float Envelope::ValueOfPixel( int y, int height, bool upper, bool dB,
|
||||
if (dB)
|
||||
v = fromDB(v);
|
||||
|
||||
// JC: The eMin/eMax code originally assumed a symmetrical range.
|
||||
// so only eMin was needed. I'm very dubious about the lower curve
|
||||
// behaviour and expect some funny behaviour when dragging
|
||||
// the lower curve when we have asymmetric ranges.
|
||||
|
||||
// Upper curve: gets clamped between eMin and eMax. Looks OK.
|
||||
// Lower curve: reset to eMin if > 0 otherwise made positive and <=eMax.
|
||||
if ((upper && v < eMin) || (!upper && v > 0))
|
||||
v = eMin;
|
||||
else if (!upper)
|
||||
v = -v;
|
||||
|
||||
if(v > eMax)
|
||||
v = eMax;
|
||||
|
||||
return v;
|
||||
// MB: this is mostly equivalent to what the old code did, I'm not sure
|
||||
// if anything special is needed for asymmetric ranges
|
||||
if(upper)
|
||||
return ClampValue(v);
|
||||
else
|
||||
return ClampValue(-v);
|
||||
}
|
||||
|
||||
/// HandleMouseButtonDown either finds an existing control point or adds a new one
|
||||
@@ -350,10 +347,10 @@ float Envelope::ValueOfPixel( int y, int height, bool upper, bool dB,
|
||||
/// Also we may be showing an inner envelope (at 0.5 the range).
|
||||
bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
|
||||
double h, double pps, bool dB,
|
||||
float zoomMin, float zoomMax, float eMin, float eMax)
|
||||
float zoomMin, float zoomMax)
|
||||
{
|
||||
int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin));
|
||||
bool upper = (zoomMin == eMin) || (event.m_y - r.y < ctr);
|
||||
bool upper = !mMirror || (zoomMin >= 0.0) || (event.m_y - r.y < ctr);
|
||||
|
||||
int clip_y = event.m_y - r.y;
|
||||
if(clip_y < 0) clip_y = 0; //keeps point in rect r, even if mouse isn't
|
||||
@@ -378,22 +375,22 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
|
||||
// TODO: extract this into a function FindNearestControlPoint()
|
||||
// TODO: also fix it so that we can drag the last point on an envelope.
|
||||
for (int i = 0; i < len; i++) { //search for control point nearest click
|
||||
if (mEnv[i]->t >= tleft && mEnv[i]->t <= tright) {
|
||||
if (mEnv[i]->GetT() >= tleft && mEnv[i]->GetT() <= tright) {
|
||||
|
||||
int x = int ((mEnv[i]->t + mOffset - h) * pps) + r.x;
|
||||
int x = int ((mEnv[i]->GetT() + mOffset - h) * pps) + r.x;
|
||||
int y[4];
|
||||
int numControlPoints;
|
||||
|
||||
// Outer control points
|
||||
y[0] = GetWaveYPos( mEnv[i]->val, zoomMin, zoomMax, r.height,
|
||||
y[0] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height,
|
||||
dB, true, dBr, false);
|
||||
y[1] = GetWaveYPos( -mEnv[i]->val, zoomMin, zoomMax, r.height,
|
||||
y[1] = GetWaveYPos( -mEnv[i]->GetVal(), zoomMin, zoomMax, r.height,
|
||||
dB, true, dBr, false);
|
||||
|
||||
// Inner control points(contour)
|
||||
y[2] = GetWaveYPos( mEnv[i]->val, zoomMin, zoomMax, r.height,
|
||||
y[2] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height,
|
||||
dB, false, dBr, false);
|
||||
y[3] = GetWaveYPos( -mEnv[i]->val-.00000001, zoomMin, zoomMax,
|
||||
y[3] = GetWaveYPos( -mEnv[i]->GetVal()-.00000001, zoomMin, zoomMax,
|
||||
r.height, dB, false, dBr, false);
|
||||
|
||||
numControlPoints = 4;
|
||||
@@ -450,7 +447,7 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
|
||||
}
|
||||
|
||||
double newVal = ValueOfPixel(clip_y, r.height, upper, dB,
|
||||
zoomMin, zoomMax, eMin, eMax);
|
||||
zoomMin, zoomMax);
|
||||
|
||||
mDragPoint = Insert(when, newVal);
|
||||
mDirty = true;
|
||||
@@ -458,8 +455,8 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r,
|
||||
|
||||
mUpper = upper;
|
||||
|
||||
mInitialWhen = mEnv[mDragPoint]->t;
|
||||
mInitialVal = mEnv[mDragPoint]->val;
|
||||
mInitialWhen = mEnv[mDragPoint]->GetT();
|
||||
mInitialVal = mEnv[mDragPoint]->GetVal();
|
||||
|
||||
mInitialX = event.m_x;
|
||||
mInitialY = event.m_y+mContourOffset;
|
||||
@@ -484,26 +481,26 @@ void Envelope::MarkDragPointForDeletion()
|
||||
// There is only one point - just move it
|
||||
// off screen and at default height.
|
||||
// temporary state when dragging only!
|
||||
mEnv[mDragPoint]->t = -1000000.0;
|
||||
mEnv[mDragPoint]->val = mDefaultValue;
|
||||
mEnv[mDragPoint]->SetT(-1000000.0);
|
||||
mEnv[mDragPoint]->SetVal(mDefaultValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// Place it exactly on one of its neighbours.
|
||||
int iNeighbourPoint = mDragPoint + ((mDragPoint > 0) ? -1:+1);
|
||||
mEnv[mDragPoint]->t = mEnv[iNeighbourPoint]->t;
|
||||
mEnv[mDragPoint]->val = mEnv[iNeighbourPoint]->val;
|
||||
mEnv[mDragPoint]->SetT(mEnv[iNeighbourPoint]->GetT());
|
||||
mEnv[mDragPoint]->SetVal(mEnv[iNeighbourPoint]->GetVal());
|
||||
}
|
||||
|
||||
void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r,
|
||||
double h, double pps, bool dB,
|
||||
float zoomMin, float zoomMax, float eMin, float eMax)
|
||||
float zoomMin, float zoomMax)
|
||||
{
|
||||
int clip_y = event.m_y - r.y;
|
||||
if(clip_y < 0) clip_y = 0;
|
||||
if(clip_y > r.height) clip_y = r.height;
|
||||
double newVal = ValueOfPixel(clip_y, r.height, mUpper, dB,
|
||||
zoomMin, zoomMax, eMin, eMax);
|
||||
zoomMin, zoomMax);
|
||||
|
||||
wxASSERT( pps > 0 );
|
||||
// We no longer tolerate multiple envelope points at the same t.
|
||||
@@ -519,15 +516,15 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r,
|
||||
double limitHi = mTrackLen;
|
||||
|
||||
if (mDragPoint > 0)
|
||||
limitLo = mEnv[mDragPoint - 1]->t + mTrackEpsilon;
|
||||
limitLo = mEnv[mDragPoint - 1]->GetT() + mTrackEpsilon;
|
||||
if (mDragPoint < (int)mEnv.Count() - 1 )
|
||||
limitHi = mEnv[mDragPoint + 1]->t - mTrackEpsilon;
|
||||
limitHi = mEnv[mDragPoint + 1]->GetT() - mTrackEpsilon;
|
||||
|
||||
newWhen = Limit( limitLo, newWhen, limitHi );
|
||||
newWhen = Limit( mTrackEpsilon, newWhen, mTrackLen - mTrackEpsilon);
|
||||
|
||||
mEnv[mDragPoint]->t = newWhen;
|
||||
mEnv[mDragPoint]->val = newVal;
|
||||
mEnv[mDragPoint]->SetT(newWhen);
|
||||
mEnv[mDragPoint]->SetVal(newVal);
|
||||
|
||||
}
|
||||
|
||||
@@ -545,7 +542,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r,
|
||||
// IF we're in the rect THEN we're not deleting this point (anymore).
|
||||
mIsDeleting = false;
|
||||
// ...we're dragging it.
|
||||
MoveDraggedPoint( event, r,h,pps,dB, zoomMin, zoomMax, eMin, eMax );
|
||||
MoveDraggedPoint( event, r,h,pps,dB, zoomMin, zoomMax);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -580,14 +577,14 @@ void Envelope::Delete( int point )
|
||||
// Returns true if parent needs to be redrawn
|
||||
bool Envelope::MouseEvent(wxMouseEvent & event, wxRect & r,
|
||||
double h, double pps, bool dB,
|
||||
float zoomMin, float zoomMax, float eMin, float eMax)
|
||||
float zoomMin, float zoomMax)
|
||||
{
|
||||
if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE)
|
||||
return HandleMouseButtonDown( event, r, h, pps,dB,
|
||||
zoomMin, zoomMax, eMin, eMax);
|
||||
zoomMin, zoomMax);
|
||||
if (event.Dragging() && mDragPoint >= 0)
|
||||
return HandleDragging( event, r, h, pps,dB,
|
||||
zoomMin, zoomMax, eMin, eMax);
|
||||
zoomMin, zoomMax);
|
||||
if (event.ButtonUp() && event.GetButton() == mButton)
|
||||
return HandleMouseButtonUp( event, r, h, pps, dB,
|
||||
zoomMin, zoomMax);
|
||||
@@ -611,7 +608,7 @@ void Envelope::CollapseRegion(double t0, double t1)
|
||||
|
||||
// Remove points in deleted region.
|
||||
for (i = 0; i < len - 0; i++)
|
||||
if (mEnv[i]->t >= t0 && mEnv[i]->t < t1) {
|
||||
if (mEnv[i]->GetT() >= t0 && mEnv[i]->GetT() < t1) {
|
||||
delete mEnv[i];
|
||||
mEnv.RemoveAt(i);
|
||||
len--;
|
||||
@@ -620,8 +617,8 @@ void Envelope::CollapseRegion(double t0, double t1)
|
||||
|
||||
// Shift points left after deleted region.
|
||||
for (i = 0; i < len; i++)
|
||||
if (mEnv[i]->t >= t1)
|
||||
mEnv[i]->t -= (t1 - t0);
|
||||
if (mEnv[i]->GetT() >= t1)
|
||||
mEnv[i]->SetT(mEnv[i]->GetT() - (t1 - t0));
|
||||
|
||||
mTrackLen -= (t1-t0);
|
||||
}
|
||||
@@ -716,11 +713,11 @@ Old analysis of cases:
|
||||
|
||||
// See if existing points need shifting to the right, and what Case we are in
|
||||
for (i = 0; i < len; i++) {
|
||||
if (mEnv[i]->t > t0)
|
||||
if (mEnv[i]->GetT() > t0)
|
||||
someToShift = true;
|
||||
else {
|
||||
pos = i; // last point not moved
|
||||
if ( fabs(mEnv[i]->t - t0) - 1/500000.0 < 0.0 ) // close enough to a point
|
||||
if ( fabs(mEnv[i]->GetT() - t0) - 1/500000.0 < 0.0 ) // close enough to a point
|
||||
onPoint = true;
|
||||
}
|
||||
}
|
||||
@@ -738,7 +735,7 @@ Old analysis of cases:
|
||||
// Now test for the various Cases, and try to do the right thing
|
||||
if(atStart) { // insertion at the beginning
|
||||
if(onPoint) { // first env point is at LH end
|
||||
mEnv[0]->t +=mTrackEpsilon; // Case 1: move it R slightly to avoid duplicate point
|
||||
mEnv[0]->SetT(mEnv[0]->GetT() + mTrackEpsilon); // Case 1: move it R slightly to avoid duplicate point
|
||||
someToShift = true; // there is now, even if there wasn't before
|
||||
//wxLogDebug(wxT("Case 1"));
|
||||
}
|
||||
@@ -751,7 +748,7 @@ Old analysis of cases:
|
||||
else {
|
||||
if(atEnd) { // insertion at the end
|
||||
if(onPoint) { // last env point is at RH end, Case 2:
|
||||
mEnv[0]->t -= mTrackEpsilon; // move it L slightly to avoid duplicate point
|
||||
mEnv[0]->SetT(mEnv[0]->GetT() - mTrackEpsilon); // move it L slightly to avoid duplicate point
|
||||
//wxLogDebug(wxT("Case 2"));
|
||||
}
|
||||
else { // Case 4:
|
||||
@@ -761,7 +758,7 @@ Old analysis of cases:
|
||||
}
|
||||
else {
|
||||
if(onPoint) { // Case 7: move the point L and insert a new one to the R
|
||||
mEnv[pos]->t -= mTrackEpsilon;
|
||||
mEnv[pos]->SetT(mEnv[pos]->GetT() - mTrackEpsilon);
|
||||
Insert(t0 + mTrackEpsilon, splitval);
|
||||
someToShift = true;
|
||||
//wxLogDebug(wxT("Case 7"));
|
||||
@@ -789,8 +786,8 @@ Old analysis of cases:
|
||||
if(someToShift) {
|
||||
len = mEnv.Count(); // it may well have changed
|
||||
for (i = 0; i < len; i++)
|
||||
if (mEnv[i]->t > t0)
|
||||
mEnv[i]->t += deltat;
|
||||
if (mEnv[i]->GetT() > t0)
|
||||
mEnv[i]->SetT(mEnv[i]->GetT() + deltat);
|
||||
}
|
||||
mTrackLen += deltat;
|
||||
}
|
||||
@@ -811,11 +808,11 @@ Old analysis of cases:
|
||||
// Copy points from inside the selection
|
||||
len = e->mEnv.Count();
|
||||
for (i = 0; i < len; i++)
|
||||
pos=Insert(t0 + e->mEnv[i]->t, e->mEnv[i]->val);
|
||||
pos=Insert(t0 + e->mEnv[i]->GetT(), e->mEnv[i]->GetVal());
|
||||
|
||||
/* if(len != 0)
|
||||
for (i = 0; i < mEnv.Count(); i++)
|
||||
wxLogDebug(wxT("Fixed i %d when %.18f val %f"),i,mEnv[i]->t,mEnv[i]->val); */
|
||||
wxLogDebug(wxT("Fixed i %d when %.18f val %f"),i,mEnv[i]->GetT(),mEnv[i]->GetVal()); */
|
||||
|
||||
if(pointsAdded)
|
||||
while(e->mEnv.Count() != 0)
|
||||
@@ -837,13 +834,13 @@ void Envelope::RemoveUnneededPoints(double time, double tolerence)
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
when = mEnv[i]->t;
|
||||
when = mEnv[i]->GetT();
|
||||
if(time >= 0)
|
||||
{
|
||||
if(fabs(when + mOffset - time) > 0.00025) // 2 samples at 8kHz, 11 at 44.1kHz
|
||||
continue;
|
||||
}
|
||||
val = mEnv[i]->val;
|
||||
val = mEnv[i]->GetVal();
|
||||
Delete(i); // try it to see if it's doing anything
|
||||
val1 = GetValue(when + mOffset);
|
||||
bool bExcludePoint = true;
|
||||
@@ -869,8 +866,8 @@ void Envelope::InsertSpace(double t0, double tlen)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (mEnv[i]->t > t0)
|
||||
mEnv[i]->t += tlen;
|
||||
if (mEnv[i]->GetT() > t0)
|
||||
mEnv[i]->SetT(mEnv[i]->GetT() + tlen);
|
||||
mTrackLen += tlen;
|
||||
}
|
||||
|
||||
@@ -881,13 +878,13 @@ int Envelope::Move(double when, double value)
|
||||
return -1;
|
||||
|
||||
int i = 0;
|
||||
while (i < len && when > mEnv[i]->t)
|
||||
while (i < len && when > mEnv[i]->GetT())
|
||||
i++;
|
||||
|
||||
if (i >= len || when < mEnv[i]->t)
|
||||
if (i >= len || when < mEnv[i]->GetT())
|
||||
return -1;
|
||||
|
||||
mEnv[i]->val = value;
|
||||
mEnv[i]->SetVal(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -906,8 +903,8 @@ void Envelope::GetPoints(double *bufferWhen,
|
||||
n = bufferLen;
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
bufferWhen[i] = mEnv[i]->t;
|
||||
bufferValue[i] = mEnv[i]->val;
|
||||
bufferWhen[i] = mEnv[i]->GetT();
|
||||
bufferValue[i] = mEnv[i]->GetVal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,21 +970,19 @@ int Envelope::Insert(double when, double value)
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (i < len && when > mEnv[i]->t)
|
||||
while (i < len && when > mEnv[i]->GetT())
|
||||
i++;
|
||||
|
||||
if(i < len && when == mEnv[i]->t) {
|
||||
if(i < len && when == mEnv[i]->GetT()) {
|
||||
|
||||
// modify existing
|
||||
mEnv[i]->val = value;
|
||||
mEnv[i]->SetVal(value);
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
// Add new
|
||||
EnvPoint *e = new EnvPoint();
|
||||
e->t = when;
|
||||
e->val = value;
|
||||
EnvPoint *e = new EnvPoint(this, when, value);
|
||||
if (i < len) {
|
||||
mEnv.Insert(e, i);
|
||||
} else {
|
||||
@@ -1010,7 +1005,7 @@ void Envelope::SetTrackLen(double trackLen)
|
||||
|
||||
int len = mEnv.Count();
|
||||
for (int i = 0; i < len; i++)
|
||||
if (mEnv[i]->t > mTrackLen) {
|
||||
if (mEnv[i]->GetT() > mTrackLen) {
|
||||
delete mEnv[i];
|
||||
mEnv.RemoveAt(i);
|
||||
len--;
|
||||
@@ -1045,7 +1040,7 @@ void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const
|
||||
wxASSERT( Hi > Lo );
|
||||
while (Hi > (Lo + 1)) {
|
||||
int mid = (Lo + Hi) / 2;
|
||||
if (t < mEnv[mid]->t)
|
||||
if (t < mEnv[mid]->GetT())
|
||||
Hi = mid;
|
||||
else
|
||||
Lo = mid;
|
||||
@@ -1060,8 +1055,7 @@ void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const
|
||||
/// @return value there, or its (safe) log10.
|
||||
double Envelope::GetInterpolationStartValueAtPoint( int iPoint ) const
|
||||
{
|
||||
//TODO-MB: make minimum value adjustable and apply this consistently
|
||||
double v = std::max(1.0e-7, mEnv[ iPoint ]->val);
|
||||
double v = mEnv[ iPoint ]->GetVal();
|
||||
if( !mDB )
|
||||
return v;
|
||||
else
|
||||
@@ -1091,14 +1085,14 @@ void Envelope::GetValues(double *buffer, int bufferLen,
|
||||
continue;
|
||||
}
|
||||
// IF before envelope THEN first value
|
||||
if (t <= mEnv[0]->t) {
|
||||
buffer[b] = mEnv[0]->val;
|
||||
if (t <= mEnv[0]->GetT()) {
|
||||
buffer[b] = mEnv[0]->GetVal();
|
||||
t += tstep;
|
||||
continue;
|
||||
}
|
||||
// IF after envelope THEN last value
|
||||
if (t >= mEnv[len - 1]->t) {
|
||||
buffer[b] = mEnv[len - 1]->val;
|
||||
if (t >= mEnv[len - 1]->GetT()) {
|
||||
buffer[b] = mEnv[len - 1]->GetVal();
|
||||
t += tstep;
|
||||
continue;
|
||||
}
|
||||
@@ -1112,8 +1106,8 @@ void Envelope::GetValues(double *buffer, int bufferLen,
|
||||
|
||||
int lo,hi;
|
||||
BinarySearchForTime( lo, hi, t );
|
||||
tprev = mEnv[lo]->t;
|
||||
tnext = mEnv[hi]->t;
|
||||
tprev = mEnv[lo]->GetT();
|
||||
tnext = mEnv[hi]->GetT();
|
||||
|
||||
vprev = GetInterpolationStartValueAtPoint( lo );
|
||||
vnext = GetInterpolationStartValueAtPoint( hi );
|
||||
@@ -1155,16 +1149,16 @@ void Envelope::GetValues(double *buffer, int bufferLen,
|
||||
|
||||
int Envelope::NumberOfPointsAfter(double t)
|
||||
{
|
||||
if( t >= mEnv[mEnv.Count()-1]->t )
|
||||
if( t >= mEnv[mEnv.Count()-1]->GetT() )
|
||||
return 0;
|
||||
else if( t < mEnv[0]->t )
|
||||
else if( t < mEnv[0]->GetT() )
|
||||
return mEnv.Count();
|
||||
else
|
||||
{
|
||||
int lo,hi;
|
||||
BinarySearchForTime( lo, hi, t );
|
||||
|
||||
if( mEnv[hi]->t == t )
|
||||
if( mEnv[hi]->GetT() == t )
|
||||
return mEnv.Count() - (hi+1);
|
||||
else
|
||||
return mEnv.Count() - hi;
|
||||
@@ -1173,18 +1167,18 @@ int Envelope::NumberOfPointsAfter(double t)
|
||||
|
||||
double Envelope::NextPointAfter(double t)
|
||||
{
|
||||
if( mEnv[mEnv.Count()-1]->t < t )
|
||||
if( mEnv[mEnv.Count()-1]->GetT() < t )
|
||||
return t;
|
||||
else if( t < mEnv[0]->t )
|
||||
return mEnv[0]->t;
|
||||
else if( t < mEnv[0]->GetT() )
|
||||
return mEnv[0]->GetT();
|
||||
else
|
||||
{
|
||||
int lo,hi;
|
||||
BinarySearchForTime( lo, hi, t );
|
||||
if( mEnv[hi]->t == t )
|
||||
return mEnv[hi+1]->t;
|
||||
if( mEnv[hi]->GetT() == t )
|
||||
return mEnv[hi+1]->GetT();
|
||||
else
|
||||
return mEnv[hi]->t;
|
||||
return mEnv[hi]->GetT();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1302,25 +1296,25 @@ double Envelope::Integral( double t0, double t1 )
|
||||
|
||||
double total = 0.0, lastT, lastVal;
|
||||
unsigned int i; // this is the next point to check
|
||||
if(t0 < mEnv[0]->t) // t0 preceding the first point
|
||||
if(t0 < mEnv[0]->GetT()) // t0 preceding the first point
|
||||
{
|
||||
if(t1 <= mEnv[0]->t)
|
||||
return (t1 - t0) * mEnv[0]->val;
|
||||
if(t1 <= mEnv[0]->GetT())
|
||||
return (t1 - t0) * mEnv[0]->GetVal();
|
||||
i = 1;
|
||||
lastT = mEnv[0]->t;
|
||||
lastVal = mEnv[0]->val;
|
||||
lastT = mEnv[0]->GetT();
|
||||
lastVal = mEnv[0]->GetVal();
|
||||
total += (lastT - t0) * lastVal;
|
||||
}
|
||||
else if(t0 >= mEnv[count - 1]->t) // t0 following the last point
|
||||
else if(t0 >= mEnv[count - 1]->GetT()) // t0 following the last point
|
||||
{
|
||||
return (t1 - t0) * mEnv[count - 1]->val;
|
||||
return (t1 - t0) * mEnv[count - 1]->GetVal();
|
||||
}
|
||||
else // t0 enclosed by points
|
||||
{
|
||||
// Skip any points that come before t0 using binary search
|
||||
int lo, hi;
|
||||
BinarySearchForTime(lo, hi, t0);
|
||||
lastVal = InterpolatePoints(mEnv[lo]->val, mEnv[hi]->val, (t0 - mEnv[lo]->t) / (mEnv[hi]->t - mEnv[lo]->t), mDB);
|
||||
lastVal = InterpolatePoints(mEnv[lo]->GetVal(), mEnv[hi]->GetVal(), (t0 - mEnv[lo]->GetT()) / (mEnv[hi]->GetT() - mEnv[lo]->GetT()), mDB);
|
||||
lastT = t0;
|
||||
i = hi; // the point immediately after t0.
|
||||
}
|
||||
@@ -1332,16 +1326,16 @@ double Envelope::Integral( double t0, double t1 )
|
||||
{
|
||||
return total + (t1 - lastT) * lastVal;
|
||||
}
|
||||
else if(mEnv[i]->t >= t1) // this point follows the end of the range
|
||||
else if(mEnv[i]->GetT() >= t1) // this point follows the end of the range
|
||||
{
|
||||
double thisVal = InterpolatePoints(mEnv[i - 1]->val, mEnv[i]->val, (t1 - mEnv[i - 1]->t) / (mEnv[i]->t - mEnv[i - 1]->t), mDB);
|
||||
double thisVal = InterpolatePoints(mEnv[i - 1]->GetVal(), mEnv[i]->GetVal(), (t1 - mEnv[i - 1]->GetT()) / (mEnv[i]->GetT() - mEnv[i - 1]->GetT()), mDB);
|
||||
return total + IntegrateInterpolated(lastVal, thisVal, t1 - lastT, mDB);
|
||||
}
|
||||
else // this point preceeds the end of the range
|
||||
{
|
||||
total += IntegrateInterpolated(lastVal, mEnv[i]->val, mEnv[i]->t - lastT, mDB);
|
||||
lastT = mEnv[i]->t;
|
||||
lastVal = mEnv[i]->val;
|
||||
total += IntegrateInterpolated(lastVal, mEnv[i]->GetVal(), mEnv[i]->GetT() - lastT, mDB);
|
||||
lastT = mEnv[i]->GetT();
|
||||
lastVal = mEnv[i]->GetVal();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -1362,25 +1356,25 @@ double Envelope::IntegralOfInverse( double t0, double t1 )
|
||||
|
||||
double total = 0.0, lastT, lastVal;
|
||||
unsigned int i; // this is the next point to check
|
||||
if(t0 < mEnv[0]->t) // t0 preceding the first point
|
||||
if(t0 < mEnv[0]->GetT()) // t0 preceding the first point
|
||||
{
|
||||
if(t1 <= mEnv[0]->t)
|
||||
return (t1 - t0) / mEnv[0]->val;
|
||||
if(t1 <= mEnv[0]->GetT())
|
||||
return (t1 - t0) / mEnv[0]->GetVal();
|
||||
i = 1;
|
||||
lastT = mEnv[0]->t;
|
||||
lastVal = mEnv[0]->val;
|
||||
lastT = mEnv[0]->GetT();
|
||||
lastVal = mEnv[0]->GetVal();
|
||||
total += (lastT - t0) / lastVal;
|
||||
}
|
||||
else if(t0 >= mEnv[count - 1]->t) // t0 following the last point
|
||||
else if(t0 >= mEnv[count - 1]->GetT()) // t0 following the last point
|
||||
{
|
||||
return (t1 - t0) / mEnv[count - 1]->val;
|
||||
return (t1 - t0) / mEnv[count - 1]->GetVal();
|
||||
}
|
||||
else // t0 enclosed by points
|
||||
{
|
||||
// Skip any points that come before t0 using binary search
|
||||
int lo, hi;
|
||||
BinarySearchForTime(lo, hi, t0);
|
||||
lastVal = InterpolatePoints(mEnv[lo]->val, mEnv[hi]->val, (t0 - mEnv[lo]->t) / (mEnv[hi]->t - mEnv[lo]->t), mDB);
|
||||
lastVal = InterpolatePoints(mEnv[lo]->GetVal(), mEnv[hi]->GetVal(), (t0 - mEnv[lo]->GetT()) / (mEnv[hi]->GetT() - mEnv[lo]->GetT()), mDB);
|
||||
lastT = t0;
|
||||
i = hi; // the point immediately after t0.
|
||||
}
|
||||
@@ -1392,16 +1386,16 @@ double Envelope::IntegralOfInverse( double t0, double t1 )
|
||||
{
|
||||
return total + (t1 - lastT) / lastVal;
|
||||
}
|
||||
else if(mEnv[i]->t >= t1) // this point follows the end of the range
|
||||
else if(mEnv[i]->GetT() >= t1) // this point follows the end of the range
|
||||
{
|
||||
double thisVal = InterpolatePoints(mEnv[i - 1]->val, mEnv[i]->val, (t1 - mEnv[i - 1]->t) / (mEnv[i]->t - mEnv[i - 1]->t), mDB);
|
||||
double thisVal = InterpolatePoints(mEnv[i - 1]->GetVal(), mEnv[i]->GetVal(), (t1 - mEnv[i - 1]->GetT()) / (mEnv[i]->GetT() - mEnv[i - 1]->GetT()), mDB);
|
||||
return total + IntegrateInverseInterpolated(lastVal, thisVal, t1 - lastT, mDB);
|
||||
}
|
||||
else // this point preceeds the end of the range
|
||||
{
|
||||
total += IntegrateInverseInterpolated(lastVal, mEnv[i]->val, mEnv[i]->t - lastT, mDB);
|
||||
lastT = mEnv[i]->t;
|
||||
lastVal = mEnv[i]->val;
|
||||
total += IntegrateInverseInterpolated(lastVal, mEnv[i]->GetVal(), mEnv[i]->GetT() - lastT, mDB);
|
||||
lastT = mEnv[i]->GetT();
|
||||
lastVal = mEnv[i]->GetVal();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -1423,26 +1417,26 @@ double Envelope::SolveIntegralOfInverse( double t0, double area )
|
||||
|
||||
double lastT, lastVal;
|
||||
unsigned int i; // this is the next point to check
|
||||
if(t0 < mEnv[0]->t) // t0 preceding the first point
|
||||
if(t0 < mEnv[0]->GetT()) // t0 preceding the first point
|
||||
{
|
||||
i = 1;
|
||||
lastT = mEnv[0]->t;
|
||||
lastVal = mEnv[0]->val;
|
||||
lastT = mEnv[0]->GetT();
|
||||
lastVal = mEnv[0]->GetVal();
|
||||
double added = (lastT - t0) / lastVal;
|
||||
if(added >= area)
|
||||
return t0 + area * mEnv[0]->val;
|
||||
return t0 + area * mEnv[0]->GetVal();
|
||||
area -= added;
|
||||
}
|
||||
else if(t0 >= mEnv[count - 1]->t) // t0 following the last point
|
||||
else if(t0 >= mEnv[count - 1]->GetT()) // t0 following the last point
|
||||
{
|
||||
return t0 + area * mEnv[count - 1]->val;
|
||||
return t0 + area * mEnv[count - 1]->GetVal();
|
||||
}
|
||||
else // t0 enclosed by points
|
||||
{
|
||||
// Skip any points that come before t0 using binary search
|
||||
int lo, hi;
|
||||
BinarySearchForTime(lo, hi, t0);
|
||||
lastVal = InterpolatePoints(mEnv[lo]->val, mEnv[hi]->val, (t0 - mEnv[lo]->t) / (mEnv[hi]->t - mEnv[lo]->t), mDB);
|
||||
lastVal = InterpolatePoints(mEnv[lo]->GetVal(), mEnv[hi]->GetVal(), (t0 - mEnv[lo]->GetT()) / (mEnv[hi]->GetT() - mEnv[lo]->GetT()), mDB);
|
||||
lastT = t0;
|
||||
i = hi; // the point immediately after t0.
|
||||
}
|
||||
@@ -1456,12 +1450,12 @@ double Envelope::SolveIntegralOfInverse( double t0, double area )
|
||||
}
|
||||
else
|
||||
{
|
||||
double added = IntegrateInverseInterpolated(lastVal, mEnv[i]->val, mEnv[i]->t - lastT, mDB);
|
||||
double added = IntegrateInverseInterpolated(lastVal, mEnv[i]->GetVal(), mEnv[i]->GetT() - lastT, mDB);
|
||||
if(added >= area)
|
||||
return lastT + SolveIntegrateInverseInterpolated(lastVal, mEnv[i]->val, mEnv[i]->t - lastT, area, mDB);
|
||||
return lastT + SolveIntegrateInverseInterpolated(lastVal, mEnv[i]->GetVal(), mEnv[i]->GetT() - lastT, area, mDB);
|
||||
area -= added;
|
||||
lastT = mEnv[i]->t;
|
||||
lastVal = mEnv[i]->val;
|
||||
lastT = mEnv[i]->GetT();
|
||||
lastVal = mEnv[i]->GetVal();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -1470,7 +1464,7 @@ double Envelope::SolveIntegralOfInverse( double t0, double area )
|
||||
void Envelope::print()
|
||||
{
|
||||
for( unsigned int i = 0; i < mEnv.Count(); i++ )
|
||||
printf( "(%.2f, %.2f)\n", mEnv[i]->t, mEnv[i]->val );
|
||||
printf( "(%.2f, %.2f)\n", mEnv[i]->GetT(), mEnv[i]->GetVal() );
|
||||
}
|
||||
|
||||
void checkResult( int n, double a, double b )
|
||||
@@ -1489,24 +1483,20 @@ void Envelope::testMe()
|
||||
SetInterpolateDB(false);
|
||||
Mirror(false);
|
||||
|
||||
SetDefaultValue(0.5);
|
||||
Flatten(0.5);
|
||||
checkResult( 1, Integral(0.0,100.0), 50);
|
||||
checkResult( 2, Integral(-10.0,10.0), 10);
|
||||
|
||||
SetDefaultValue(1.0);
|
||||
Flatten(0.5);
|
||||
checkResult( 3, Integral(0.0,100.0), 50);
|
||||
checkResult( 4, Integral(-10.0,10.0), 10);
|
||||
checkResult( 5, Integral(-20.0,-10.0), 5);
|
||||
|
||||
SetDefaultValue(0.5);
|
||||
Flatten(0.5);
|
||||
Insert( 5.0, 0.5 );
|
||||
checkResult( 6, Integral(0.0,100.0), 50);
|
||||
checkResult( 7, Integral(-10.0,10.0), 10);
|
||||
|
||||
SetDefaultValue(0.5);
|
||||
Flatten(0.0);
|
||||
Insert( 0.0, 0.0 );
|
||||
Insert( 5.0, 1.0 );
|
||||
@@ -1519,7 +1509,6 @@ void Envelope::testMe()
|
||||
// Integrals should be additive
|
||||
checkResult( 8, result - resulta - resultb, 0);
|
||||
|
||||
SetDefaultValue(0.5);
|
||||
Flatten(0.0);
|
||||
Insert( 0.0, 0.0 );
|
||||
Insert( 5.0, 1.0 );
|
||||
|
||||
Reference in New Issue
Block a user