diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 8ee888bdb..50fa618da 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -71,8 +71,6 @@ Envelope::Envelope() Envelope::~Envelope() { - mDragPoint = -1;// TODO: Remove - Isn't this line totally pointless since we're in the destructor? - WX_CLEAR_ARRAY(mEnv); } void Envelope::Mirror(bool mirror) @@ -98,9 +96,9 @@ void Envelope::Rescale(double minValue, double maxValue) mDefaultValue = ClampValue(mMinValue + (mMaxValue - mMinValue) * factor); // rescale all points - for( unsigned int i = 0; i < mEnv.Count(); i++ ) { - factor = (mEnv[i]->GetVal() - oldMinValue) / (oldMaxValue - oldMinValue); - mEnv[i]->SetVal(mMinValue + (mMaxValue - mMinValue) * factor); + for( unsigned int i = 0; i < mEnv.size(); i++ ) { + factor = (mEnv[i].GetVal() - oldMinValue) / (oldMaxValue - oldMinValue); + mEnv[i].SetVal(mMinValue + (mMaxValue - mMinValue) * factor); } } @@ -110,7 +108,7 @@ void Envelope::Rescale(double minValue, double maxValue) /// @value - the y-value for the flat envelope. void Envelope::Flatten(double value) { - WX_CLEAR_ARRAY(mEnv); + mEnv.clear(); mDefaultValue = ClampValue(value); } @@ -118,19 +116,14 @@ 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 + for( unsigned int i = 0; i < mEnv.size(); i++ ) + mEnv[i].SetVal(mEnv[i].GetVal()); // this clamps the value to the new range } -EnvPoint * Envelope::AddPointAtEnd( double t, double val ) +EnvPoint *Envelope::AddPointAtEnd( double t, double val ) { - // JC: Gross! (allocating one point at a time.) - // 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(this, t, val); - mEnv.Add(pt); - return pt; + mEnv.push_back(EnvPoint(this, t, val)); + return &mEnv.back(); } void Envelope::CopyFrom(const Envelope *e, double t0, double t1) @@ -140,12 +133,12 @@ void Envelope::CopyFrom(const Envelope *e, double t0, double t1) mOffset = wxMax(t0, e->mOffset); mTrackLen = wxMin(t1, e->mOffset + e->mTrackLen) - mOffset; - WX_CLEAR_ARRAY(mEnv); - int len = e->mEnv.Count(); + mEnv.clear(); + int len = e->mEnv.size(); int i = 0; // Skip the points that come before the copied region - while( (i < len) && e->mOffset + e->mEnv[i]->GetT() <= t0) + while ((i < len) && e->mOffset + e->mEnv[i].GetT() <= t0) i++; // Create the point at 0 if it needs interpolated representation @@ -153,12 +146,19 @@ 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]->GetT() - mOffset < mTrackLen) { - AddPointAtEnd( e->mOffset + e->mEnv[i]->GetT() - mOffset, e->mEnv[i]->GetVal() ); - i++; + while (i < len) { + const EnvPoint &point = e->mEnv[i]; + const double when = e->mOffset + point.GetT() - mOffset; + if (when < mTrackLen) { + AddPointAtEnd(when, point.GetVal()); + i++; + } + else + break; } // Create the final point if it needs interpolated representation + // If the last point of e was exatly at t1, this effectively copies it too. if (mTrackLen > 0 && i < len) AddPointAtEnd( mTrackLen, e->GetValue(mOffset + mTrackLen)); } @@ -191,8 +191,8 @@ void Envelope::DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, dc.SetPen(AColor::envelopePen); dc.SetBrush(*wxWHITE_BRUSH); - for (int i = 0; i < (int)mEnv.Count(); i++) { - const double time = mEnv[i]->GetT() + mOffset; + for (int i = 0; i < (int)mEnv.size(); i++) { + const double time = mEnv[i].GetT() + mOffset; const wxInt64 position = zoomInfo.TimeToPosition(time); if (position >= 0 && position < r.width) { // Change colour if this is the draggable point... @@ -201,7 +201,7 @@ void Envelope::DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, dc.SetBrush(AColor::envelopeBrush); } - double v = mEnv[i]->GetVal(); + double v = mEnv[i].GetVal(); int x = int(position); int y, y2; @@ -268,8 +268,8 @@ bool Envelope::HandleXMLTag(const wxChar *tag, const wxChar **attrs) if (numPoints < 0) return false; - WX_CLEAR_ARRAY(mEnv); - mEnv.Alloc(numPoints); + mEnv.clear(); + mEnv.reserve(numPoints); return true; } @@ -281,17 +281,18 @@ XMLTagHandler *Envelope::HandleXMLChild(const wxChar *tag) return AddPointAtEnd(0,0); } -void Envelope::WriteXML(XMLWriter &xmlFile) +void Envelope::WriteXML(XMLWriter &xmlFile) const { unsigned int ctrlPt; xmlFile.StartTag(wxT("envelope")); - xmlFile.WriteAttr(wxT("numpoints"), mEnv.GetCount()); + xmlFile.WriteAttr(wxT("numpoints"), mEnv.size()); - for (ctrlPt = 0; ctrlPt < mEnv.GetCount(); ctrlPt++) { + for (ctrlPt = 0; ctrlPt < mEnv.size(); ctrlPt++) { + const EnvPoint &point = mEnv[ctrlPt]; xmlFile.StartTag(wxT("controlpoint")); - xmlFile.WriteAttr(wxT("t"), mEnv[ctrlPt]->GetT(), 12); - xmlFile.WriteAttr(wxT("val"), mEnv[ctrlPt]->GetVal(), 12); + xmlFile.WriteAttr(wxT("t"), point.GetT(), 12); + xmlFile.WriteAttr(wxT("val"), point.GetVal(), 12); xmlFile.EndTag(wxT("controlpoint")); } @@ -351,12 +352,12 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, mContourOffset = false; // wxLogDebug(wxT("Y:%i Height:%i Offset:%i"), y, height, mContourOffset ); - int len = mEnv.Count(); + int len = mEnv.size(); // 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 - const double time = mEnv[i]->GetT() + mOffset; + const double time = mEnv[i].GetT() + mOffset; const wxInt64 position = zoomInfo.TimeToPosition(time); if (position >= 0 && position < r.width) { @@ -365,7 +366,7 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, int numControlPoints; // Outer control points - double value = mEnv[i]->GetVal(); + double value = mEnv[i].GetVal(); y[0] = GetWaveYPos(value, zoomMin, zoomMax, r.height, dB, true, dBRange, false); y[1] = GetWaveYPos(-value, zoomMin, zoomMax, r.height, @@ -440,7 +441,7 @@ bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, mUpper = upper; - mInitialVal = mEnv[mDragPoint]->GetVal(); + mInitialVal = mEnv[mDragPoint].GetVal(); mInitialY = event.m_y+mContourOffset; @@ -459,20 +460,20 @@ void Envelope::MarkDragPointForDeletion() // Without delting the point we move it left or right // to the same position as the previous or next point. - if( mEnv.Count()<=1) + if( mEnv.size() <= 1) { // There is only one point - just move it // off screen and at default height. // temporary state when dragging only! - mEnv[mDragPoint]->SetT(-1000000.0); - mEnv[mDragPoint]->SetVal(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]->SetT(mEnv[iNeighbourPoint]->GetT()); - mEnv[mDragPoint]->SetVal(mEnv[iNeighbourPoint]->GetVal()); + mEnv[mDragPoint].SetT(mEnv[iNeighbourPoint].GetT()); + mEnv[mDragPoint].SetVal(mEnv[iNeighbourPoint].GetVal()); } void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, @@ -498,15 +499,15 @@ void Envelope::MoveDraggedPoint( wxMouseEvent & event, wxRect & r, double limitHi = mTrackLen; if (mDragPoint > 0) - limitLo = mEnv[mDragPoint - 1]->GetT() + mTrackEpsilon; - if (mDragPoint < (int)mEnv.Count() - 1 ) - limitHi = mEnv[mDragPoint + 1]->GetT() - mTrackEpsilon; + limitLo = mEnv[mDragPoint - 1].GetT() + mTrackEpsilon; + if (mDragPoint < (int)mEnv.size() - 1 ) + limitHi = mEnv[mDragPoint + 1].GetT() - mTrackEpsilon; newWhen = Limit( limitLo, newWhen, limitHi ); newWhen = Limit( mTrackEpsilon, newWhen, mTrackLen - mTrackEpsilon); - mEnv[mDragPoint]->SetT(newWhen); - mEnv[mDragPoint]->SetVal(newVal); + mEnv[mDragPoint].SetT(newWhen); + mEnv[mDragPoint].SetVal(newVal); } @@ -540,8 +541,7 @@ bool Envelope::HandleDragging( wxMouseEvent & event, wxRect & r, bool Envelope::HandleMouseButtonUp() { if (mIsDeleting) { - delete mEnv[mDragPoint]; - mEnv.RemoveAt(mDragPoint); + Delete(mDragPoint); } mDragPoint = -1; mButton = wxMOUSE_BTN_NONE; @@ -550,8 +550,12 @@ bool Envelope::HandleMouseButtonUp() void Envelope::Delete( int point ) { - delete mEnv[point]; - mEnv.RemoveAt(point); + mEnv.erase(mEnv.begin() + point); +} + +void Envelope::Insert(int point, const EnvPoint &p) +{ + mEnv.insert(mEnv.begin() + point, p); } // Returns true if parent needs to be redrawn @@ -579,25 +583,24 @@ void Envelope::CollapseRegion(double t0, double t1) t0 -= mOffset; t1 -= mOffset; - t0 = Limit( 0, t0, mTrackLen ); - t1 = Limit( 0, t1, mTrackLen ); + t0 = std::max(0.0, std::min(mTrackLen, t0)); + t1 = std::max(0.0, std::min(mTrackLen, t1)); - int len = mEnv.Count(); + int len = mEnv.size(); int i; // Remove points in deleted region. for (i = 0; i < len - 0; i++) - if (mEnv[i]->GetT() >= t0 && mEnv[i]->GetT() < t1) { - delete mEnv[i]; - mEnv.RemoveAt(i); + if (mEnv[i].GetT() >= t0 && mEnv[i].GetT() < t1) { + Delete(i); len--; i--; } // Shift points left after deleted region. for (i = 0; i < len; i++) - if (mEnv[i]->GetT() >= t1) - mEnv[i]->SetT(mEnv[i]->GetT() - (t1 - t0)); + if (mEnv[i].GetT() >= t1) + mEnv[i].SetT(mEnv[i].GetT() - (t1 - t0)); mTrackLen -= (t1-t0); } @@ -609,12 +612,12 @@ void Envelope::CollapseRegion(double t0, double t1) // Rather than going to a .5-offset-index, we special case the framing. void Envelope::Paste(double t0, const Envelope *e) { - const bool wasEmpty = (this->mEnv.Count() == 0); + const bool wasEmpty = (this->mEnv.size() == 0); // JC: The old analysis of cases and the resulting code here is way more complex than needed. // TODO: simplify the analysis and simplify the code. - if (e->mEnv.Count() == 0 && wasEmpty && e->mDefaultValue == this->mDefaultValue) + if (e->mEnv.size() == 0 && wasEmpty && e->mDefaultValue == this->mDefaultValue) { // msmeyer: The envelope is empty and has the same default value, so // there is nothing that must be inserted, just return. This avoids @@ -635,7 +638,7 @@ void Envelope::Paste(double t0, const Envelope *e) bool atEnd = false; bool afterEnd = false; bool onPoint = false; - unsigned int len = mEnv.Count(); + unsigned int len = mEnv.size(); // get values to perform framing of the insertion double splitval = GetValue(t0 + mOffset); @@ -682,11 +685,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]->GetT() > t0) + if (mEnv[i].GetT() > t0) someToShift = true; else { pos = i; // last point not moved - if ( fabs(mEnv[i]->GetT() - 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; } } @@ -704,7 +707,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]->SetT(mEnv[0]->GetT() + 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")); } @@ -717,7 +720,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]->SetT(mEnv[0]->GetT() - 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: @@ -727,7 +730,7 @@ Old analysis of cases: } else { if(onPoint) { // Case 7: move the point L and insert a new one to the R - mEnv[pos]->SetT(mEnv[pos]->GetT() - mTrackEpsilon); + mEnv[pos].SetT(mEnv[pos].GetT() - mTrackEpsilon); Insert(t0 + mTrackEpsilon, splitval); someToShift = true; //wxLogDebug(wxT("Case 7")); @@ -753,10 +756,10 @@ Old analysis of cases: // Now shift existing points to the right, if required if(someToShift) { - len = mEnv.Count(); // it may well have changed + len = mEnv.size(); // it may well have changed for (i = 0; i < len; i++) - if (mEnv[i]->GetT() > t0) - mEnv[i]->SetT(mEnv[i]->GetT() + deltat); + if (mEnv[i].GetT() > t0) + mEnv[i].SetT(mEnv[i].GetT() + deltat); } mTrackLen += deltat; } @@ -786,13 +789,13 @@ Old analysis of cases: Insert(t0 + e->mTrackLen, rightval); } - len = e->mEnv.Count(); + len = e->mEnv.size(); for (i = 0; i < len; i++) - Insert(t0 + e->mEnv[i]->GetT(), e->mEnv[i]->GetVal()); + 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]->GetT(),mEnv[i]->GetVal()); */ + for (i = 0; i < mEnv.size(); i++) + wxLogDebug(wxT("Fixed i %d when %.18f val %f"),i,mEnv[i].GetT(),mEnv[i].GetVal()); */ } // Deletes 'unneeded' points, starting from the left. @@ -802,31 +805,31 @@ Old analysis of cases: // 'tolerence' without the point being there. void Envelope::RemoveUnneededPoints(double time, double tolerence) { - unsigned int len = mEnv.Count(); + unsigned int len = mEnv.size(); unsigned int i; double when, val, val1; - if(mEnv.Count() == 0) + if(mEnv.size() == 0) return; for (i = 0; i < len; i++) { - when = mEnv[i]->GetT(); + 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]->GetVal(); + val = mEnv[i].GetVal(); Delete(i); // try it to see if it's doing anything val1 = GetValue(when + mOffset); bool bExcludePoint = true; if( fabs(val -val1) > tolerence ) { - Insert(when,val); // put it back, we needed it + Insert(when, val); // put it back, we needed it //Insert may have modified instead of inserting, if two points were at the same time. // in which case len needs to shrink i and len, because the array size decreased. - bExcludePoint = (mEnv.Count() < len); + bExcludePoint = (mEnv.size() < len); } if( bExcludePoint ) { // it made no difference so leave it out @@ -838,49 +841,49 @@ void Envelope::RemoveUnneededPoints(double time, double tolerence) void Envelope::InsertSpace(double t0, double tlen) { - unsigned int len = mEnv.Count(); + unsigned int len = mEnv.size(); unsigned int i; for (i = 0; i < len; i++) - if (mEnv[i]->GetT() > t0) - mEnv[i]->SetT(mEnv[i]->GetT() + tlen); + if (mEnv[i].GetT() > t0) + mEnv[i].SetT(mEnv[i].GetT() + tlen); mTrackLen += tlen; } int Envelope::Move(double when, double value) { - int len = mEnv.Count(); + int len = mEnv.size(); if (len == 0) return -1; int i = 0; - while (i < len && when > mEnv[i]->GetT()) + while (i < len && when > mEnv[i].GetT()) i++; - if (i >= len || when < mEnv[i]->GetT()) + if (i >= len || when < mEnv[i].GetT()) return -1; - mEnv[i]->SetVal(value); + mEnv[i].SetVal(value); return 0; } int Envelope::GetNumberOfPoints() const { - return mEnv.Count(); + return mEnv.size(); } void Envelope::GetPoints(double *bufferWhen, double *bufferValue, int bufferLen) const { - int n = mEnv.Count(); + int n = mEnv.size(); if (n > bufferLen) n = bufferLen; int i; for (i = 0; i < n; i++) { - bufferWhen[i] = mEnv[i]->GetT(); - bufferValue[i] = mEnv[i]->GetVal(); + bufferWhen[i] = mEnv[i].GetT(); + bufferValue[i] = mEnv[i].GetVal(); } } @@ -932,7 +935,7 @@ int Envelope::Insert(double when, double value) } #endif - int len = mEnv.Count(); + int len = mEnv.size(); if (len && when < 0.0) return 0; @@ -946,23 +949,22 @@ int Envelope::Insert(double when, double value) int i = 0; - while (i < len && when > mEnv[i]->GetT()) + while (i < len && when > mEnv[i].GetT()) i++; - if(i < len && when == mEnv[i]->GetT()) { + if(i < len && when == mEnv[i].GetT()) { // modify existing - mEnv[i]->SetVal(value); + mEnv[i].SetVal(value); } - else{ - + else { // Add new - EnvPoint *e = new EnvPoint(this, when, value); + EnvPoint e(this, when, value); if (i < len) { - mEnv.Insert(e, i); + Insert(i, e); } else { - mEnv.Add(e); + mEnv.push_back(e); } } return i; @@ -979,11 +981,10 @@ void Envelope::SetTrackLen(double trackLen) { mTrackLen = trackLen; - int len = mEnv.Count(); + int len = mEnv.size(); for (int i = 0; i < len; i++) - if (mEnv[i]->GetT() > mTrackLen) { - delete mEnv[i]; - mEnv.RemoveAt(i); + if (mEnv[i].GetT() > mTrackLen) { + Delete(i); len--; i--; } @@ -1004,16 +1005,16 @@ double Envelope::GetValue(double t) const void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const { Lo = 0; - Hi = mEnv.Count() - 1; + Hi = mEnv.size() - 1; // JC: Do we have a problem if the envelope only has one point?? wxASSERT(Hi > Lo); // Optimizations for the usual pattern of repeated calls with // small increases of t. { - if (mSearchGuess >= 0 && mSearchGuess < int(mEnv.Count()) - 1) { - if (t >= mEnv[mSearchGuess]->GetT() && - t < mEnv[1 + mSearchGuess]->GetT()) { + if (mSearchGuess >= 0 && mSearchGuess < int(mEnv.size()) - 1) { + if (t >= mEnv[mSearchGuess].GetT() && + t < mEnv[1 + mSearchGuess].GetT()) { Lo = mSearchGuess; Hi = 1 + mSearchGuess; return; @@ -1021,9 +1022,9 @@ void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const } ++mSearchGuess; - if (mSearchGuess >= 0 && mSearchGuess < int(mEnv.Count()) - 1) { - if (t >= mEnv[mSearchGuess]->GetT() && - t < mEnv[1 + mSearchGuess]->GetT()) { + if (mSearchGuess >= 0 && mSearchGuess < int(mEnv.size()) - 1) { + if (t >= mEnv[mSearchGuess].GetT() && + t < mEnv[1 + mSearchGuess].GetT()) { Lo = mSearchGuess; Hi = 1 + mSearchGuess; return; @@ -1033,7 +1034,7 @@ void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const while (Hi > (Lo + 1)) { int mid = (Lo + Hi) / 2; - if (t < mEnv[mid]->GetT()) + if (t < mEnv[mid].GetT()) Hi = mid; else Lo = mid; @@ -1050,7 +1051,7 @@ void Envelope::BinarySearchForTime( int &Lo, int &Hi, double t ) const /// @return value there, or its (safe) log10. double Envelope::GetInterpolationStartValueAtPoint( int iPoint ) const { - double v = mEnv[ iPoint ]->GetVal(); + double v = mEnv[ iPoint ].GetVal(); if( !mDB ) return v; else @@ -1066,7 +1067,7 @@ void Envelope::GetValues(double *buffer, int bufferLen, // JC: If bufferLen ==0 we have probably just allocated a zero sized buffer. // wxASSERT( bufferLen > 0 ); - int len = mEnv.Count(); + int len = mEnv.size(); double t = t0; double tprev, vprev, tnext = 0, vnext, vstep = 0; @@ -1081,14 +1082,14 @@ void Envelope::GetValues(double *buffer, int bufferLen, continue; } // IF before envelope THEN first value - if (t <= mEnv[0]->GetT()) { - buffer[b] = mEnv[0]->GetVal(); + if (t <= mEnv[0].GetT()) { + buffer[b] = mEnv[0].GetVal(); t += tstep; continue; } // IF after envelope THEN last value - if (t >= mEnv[len - 1]->GetT()) { - buffer[b] = mEnv[len - 1]->GetVal(); + if (t >= mEnv[len - 1].GetT()) { + buffer[b] = mEnv[len - 1].GetVal(); t += tstep; continue; } @@ -1102,8 +1103,8 @@ void Envelope::GetValues(double *buffer, int bufferLen, int lo,hi; BinarySearchForTime( lo, hi, t ); - tprev = mEnv[lo]->GetT(); - tnext = mEnv[hi]->GetT(); + tprev = mEnv[lo].GetT(); + tnext = mEnv[hi].GetT(); vprev = GetInterpolationStartValueAtPoint( lo ); vnext = GetInterpolationStartValueAtPoint( hi ); @@ -1152,36 +1153,36 @@ void Envelope::GetValues int Envelope::NumberOfPointsAfter(double t) { - if( t >= mEnv[mEnv.Count()-1]->GetT() ) + if( t >= mEnv[mEnv.size()-1].GetT() ) return 0; - else if( t < mEnv[0]->GetT() ) - return mEnv.Count(); + else if( t < mEnv[0].GetT() ) + return mEnv.size(); else { int lo,hi; BinarySearchForTime( lo, hi, t ); - if( mEnv[hi]->GetT() == t ) - return mEnv.Count() - (hi+1); + if( mEnv[hi].GetT() == t ) + return mEnv.size() - (hi+1); else - return mEnv.Count() - hi; + return mEnv.size() - hi; } } double Envelope::NextPointAfter(double t) { - if( mEnv[mEnv.Count()-1]->GetT() < t ) + if( mEnv[mEnv.size()-1].GetT() < t ) return t; - else if( t < mEnv[0]->GetT() ) - return mEnv[0]->GetT(); + else if( t < mEnv[0].GetT() ) + return mEnv[0].GetT(); else { int lo,hi; BinarySearchForTime( lo, hi, t ); - if( mEnv[hi]->GetT() == t ) - return mEnv[hi+1]->GetT(); + if( mEnv[hi].GetT() == t ) + return mEnv[hi+1].GetT(); else - return mEnv[hi]->GetT(); + return mEnv[hi].GetT(); } } @@ -1293,31 +1294,31 @@ double Envelope::Integral( double t0, double t1 ) return -Integral(t1, t0); // this makes more sense than returning the default value } - unsigned int count = mEnv.Count(); + unsigned int count = mEnv.size(); if(count == 0) // 'empty' envelope return (t1 - t0) * mDefaultValue; double total = 0.0, lastT, lastVal; unsigned int i; // this is the next point to check - if(t0 < mEnv[0]->GetT()) // t0 preceding the first point + if(t0 < mEnv[0].GetT()) // t0 preceding the first point { - if(t1 <= mEnv[0]->GetT()) - return (t1 - t0) * mEnv[0]->GetVal(); + if(t1 <= mEnv[0].GetT()) + return (t1 - t0) * mEnv[0].GetVal(); i = 1; - lastT = mEnv[0]->GetT(); - lastVal = mEnv[0]->GetVal(); + lastT = mEnv[0].GetT(); + lastVal = mEnv[0].GetVal(); total += (lastT - t0) * lastVal; } - else if(t0 >= mEnv[count - 1]->GetT()) // t0 following the last point + else if(t0 >= mEnv[count - 1].GetT()) // t0 following the last point { - return (t1 - t0) * mEnv[count - 1]->GetVal(); + 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]->GetVal(), mEnv[hi]->GetVal(), (t0 - mEnv[lo]->GetT()) / (mEnv[hi]->GetT() - mEnv[lo]->GetT()), 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. } @@ -1329,16 +1330,16 @@ double Envelope::Integral( double t0, double t1 ) { return total + (t1 - lastT) * lastVal; } - else if(mEnv[i]->GetT() >= 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]->GetVal(), mEnv[i]->GetVal(), (t1 - mEnv[i - 1]->GetT()) / (mEnv[i]->GetT() - mEnv[i - 1]->GetT()), 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]->GetVal(), mEnv[i]->GetT() - lastT, mDB); - lastT = mEnv[i]->GetT(); - lastVal = mEnv[i]->GetVal(); + total += IntegrateInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, mDB); + lastT = mEnv[i].GetT(); + lastVal = mEnv[i].GetVal(); i++; } } @@ -1353,31 +1354,31 @@ double Envelope::IntegralOfInverse( double t0, double t1 ) return -IntegralOfInverse(t1, t0); // this makes more sense than returning the default value } - unsigned int count = mEnv.Count(); + unsigned int count = mEnv.size(); if(count == 0) // 'empty' envelope return (t1 - t0) / mDefaultValue; double total = 0.0, lastT, lastVal; unsigned int i; // this is the next point to check - if(t0 < mEnv[0]->GetT()) // t0 preceding the first point + if(t0 < mEnv[0].GetT()) // t0 preceding the first point { - if(t1 <= mEnv[0]->GetT()) - return (t1 - t0) / mEnv[0]->GetVal(); + if(t1 <= mEnv[0].GetT()) + return (t1 - t0) / mEnv[0].GetVal(); i = 1; - lastT = mEnv[0]->GetT(); - lastVal = mEnv[0]->GetVal(); + lastT = mEnv[0].GetT(); + lastVal = mEnv[0].GetVal(); total += (lastT - t0) / lastVal; } - else if(t0 >= mEnv[count - 1]->GetT()) // t0 following the last point + else if(t0 >= mEnv[count - 1].GetT()) // t0 following the last point { - return (t1 - t0) / mEnv[count - 1]->GetVal(); + 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]->GetVal(), mEnv[hi]->GetVal(), (t0 - mEnv[lo]->GetT()) / (mEnv[hi]->GetT() - mEnv[lo]->GetT()), 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. } @@ -1389,16 +1390,16 @@ double Envelope::IntegralOfInverse( double t0, double t1 ) { return total + (t1 - lastT) / lastVal; } - else if(mEnv[i]->GetT() >= 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]->GetVal(), mEnv[i]->GetVal(), (t1 - mEnv[i - 1]->GetT()) / (mEnv[i]->GetT() - mEnv[i - 1]->GetT()), 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]->GetVal(), mEnv[i]->GetT() - lastT, mDB); - lastT = mEnv[i]->GetT(); - lastVal = mEnv[i]->GetVal(); + total += IntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, mDB); + lastT = mEnv[i].GetT(); + lastVal = mEnv[i].GetVal(); i++; } } @@ -1409,40 +1410,40 @@ double Envelope::SolveIntegralOfInverse( double t0, double area ) if(area == 0.0) return t0; - int count = mEnv.Count(); + unsigned int count = mEnv.size(); if(count == 0) // 'empty' envelope return t0 + area * mDefaultValue; double lastT, lastVal; int i; // this is the next point to check - if(t0 < mEnv[0]->GetT()) // t0 preceding the first point + if(t0 < mEnv[0].GetT()) // t0 preceding the first point { if (area < 0) { - return t0 + area * mEnv[0]->GetVal(); + return t0 + area * mEnv[0].GetVal(); } else { i = 1; - lastT = mEnv[0]->GetT(); - lastVal = mEnv[0]->GetVal(); + lastT = mEnv[0].GetT(); + lastVal = mEnv[0].GetVal(); double added = (lastT - t0) / lastVal; if(added >= area) - return t0 + area * mEnv[0]->GetVal(); + return t0 + area * mEnv[0].GetVal(); area -= added; } } - else if(t0 >= mEnv[count - 1]->GetT()) // t0 following the last point + else if(t0 >= mEnv[count - 1].GetT()) // t0 following the last point { if (area < 0) { i = count - 2; - lastT = mEnv[count - 1]->GetT(); - lastVal = mEnv[count - 1]->GetVal(); + lastT = mEnv[count - 1].GetT(); + lastVal = mEnv[count - 1].GetVal(); double added = (lastT - t0) / lastVal; // negative if(added <= area) - return t0 + area * mEnv[count - 1]->GetVal(); + return t0 + area * mEnv[count - 1].GetVal(); area -= added; } else { - return t0 + area * mEnv[count - 1]->GetVal(); + return t0 + area * mEnv[count - 1].GetVal(); } } else // t0 enclosed by points @@ -1450,7 +1451,7 @@ double Envelope::SolveIntegralOfInverse( double t0, double area ) // Skip any points that come before t0 using binary search int lo, hi; BinarySearchForTime(lo, hi, t0); - lastVal = InterpolatePoints(mEnv[lo]->GetVal(), mEnv[hi]->GetVal(), (t0 - mEnv[lo]->GetT()) / (mEnv[hi]->GetT() - mEnv[lo]->GetT()), mDB); + lastVal = InterpolatePoints(mEnv[lo].GetVal(), mEnv[hi].GetVal(), (t0 - mEnv[lo].GetT()) / (mEnv[hi].GetT() - mEnv[lo].GetT()), mDB); lastT = t0; if (area < 0) i = lo; @@ -1470,12 +1471,12 @@ double Envelope::SolveIntegralOfInverse( double t0, double area ) else { double added = - -IntegrateInverseInterpolated(mEnv[i]->GetVal(), lastVal, lastT - mEnv[i]->GetT(), mDB); + -IntegrateInverseInterpolated(mEnv[i].GetVal(), lastVal, lastT - mEnv[i].GetT(), mDB); if(added <= area) - return lastT - SolveIntegrateInverseInterpolated(lastVal, mEnv[i]->GetVal(), lastT - mEnv[i]->GetT(), -area, mDB); + return lastT - SolveIntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), lastT - mEnv[i].GetT(), -area, mDB); area -= added; - lastT = mEnv[i]->GetT(); - lastVal = mEnv[i]->GetVal(); + lastT = mEnv[i].GetT(); + lastVal = mEnv[i].GetVal(); --i; } } @@ -1490,12 +1491,12 @@ double Envelope::SolveIntegralOfInverse( double t0, double area ) } else { - double added = IntegrateInverseInterpolated(lastVal, mEnv[i]->GetVal(), mEnv[i]->GetT() - lastT, mDB); + double added = IntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, mDB); if(added >= area) - return lastT + SolveIntegrateInverseInterpolated(lastVal, mEnv[i]->GetVal(), mEnv[i]->GetT() - lastT, area, mDB); + return lastT + SolveIntegrateInverseInterpolated(lastVal, mEnv[i].GetVal(), mEnv[i].GetT() - lastT, area, mDB); area -= added; - lastT = mEnv[i]->GetT(); - lastVal = mEnv[i]->GetVal(); + lastT = mEnv[i].GetT(); + lastVal = mEnv[i].GetVal(); i++; } } @@ -1504,8 +1505,8 @@ 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]->GetT(), mEnv[i]->GetVal() ); + for( unsigned int i = 0; i < mEnv.size(); i++ ) + printf( "(%.2f, %.2f)\n", mEnv[i].GetT(), mEnv[i].GetVal() ); } static void checkResult( int n, double a, double b ) @@ -1560,7 +1561,7 @@ void Envelope::testMe() checkResult( 10, Integral(0.0,t0), 4.999); checkResult( 11, Integral(t0,t1), .001); - WX_CLEAR_ARRAY(mEnv); + mEnv.clear(); Insert( 0.0, 0.0 ); Insert( 5.0, 1.0 ); Insert( 10.0, 0.0 ); diff --git a/src/Envelope.h b/src/Envelope.h index 53d75cd41..fa38bb8db 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -28,25 +29,19 @@ class wxTextFile; class DirManager; class Envelope; +class EnvPoint; class ZoomInfo; class EnvPoint : public XMLTagHandler { public: - EnvPoint(Envelope *envelope, double t, double val) - { - mEnvelope = envelope; - mT = t; - mVal = ClampValue(val); - } + inline EnvPoint(Envelope *envelope, double t, double val); - double ClampValue(double val); // this calls mEnvelope->ClampValue(), implementation is below the Envelope class - - double GetT() { return mT; } + double GetT() const { return mT; } void SetT(double t) { mT = t; } - double GetVal() { return mVal; } - void SetVal(double val) { mVal = ClampValue(val); } + double GetVal() const { return mVal; } + inline void SetVal(double val); bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) { @@ -77,12 +72,7 @@ private: }; -// TODO: Become an array of EnvPoint rather than of pointers to. -// Really? wxWidgets help says: -// "wxArray is suitable for storing integer types and pointers which it does not -// treat as objects in any way..." -// And why is this a TODO in any case, if it works correctly? -WX_DEFINE_ARRAY(EnvPoint *, EnvArray); +typedef std::vector EnvArray; class Envelope : public XMLTagHandler { public: @@ -114,7 +104,7 @@ class Envelope : public XMLTagHandler { // Newfangled XML file I/O virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs); virtual XMLTagHandler *HandleXMLChild(const wxChar *tag); - virtual void WriteXML(XMLWriter &xmlFile); + virtual void WriteXML(XMLWriter &xmlFile) const; void DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, bool dB, double dBRange, @@ -181,12 +171,21 @@ class Envelope : public XMLTagHandler { * Returns 0 if point moved, -1 if not found.*/ int Move(double when, double value); - /** \brief delete a point by it's position in array */ + /** \brief delete a point by its position in array */ void Delete(int point); + /** \brief insert a point */ + void Insert(int point, const EnvPoint &p); + /** \brief Return number of points */ int GetNumberOfPoints() const; + /** \brief Accessor for points */ + const EnvPoint &operator[] (int index) const + { + return mEnv[index]; + } + /** \brief Returns the sets of when and value pairs */ void GetPoints(double *bufferWhen, double *bufferValue, @@ -227,6 +226,7 @@ private: /** \brief Number of pixels contour is from the true envelope. */ int mContourOffset; + double mInitialVal; // These are used in dragging. @@ -249,9 +249,16 @@ private: }; -inline double EnvPoint::ClampValue(double val) +inline EnvPoint::EnvPoint(Envelope *envelope, double t, double val) { - return mEnvelope->ClampValue(val); + mEnvelope = envelope; + mT = t; + mVal = mEnvelope->ClampValue(val); +} + +inline void EnvPoint::SetVal(double val) +{ + mVal = mEnvelope->ClampValue(val); } #endif diff --git a/src/Project.cpp b/src/Project.cpp index abf5ecb23..9df141fe3 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -4476,32 +4476,26 @@ void AudacityProject::GetRegionsByLabel( Regions ®ions ) const LabelStruct *ls = lt->GetLabel( i ); if( ls->selectedRegion.t0() >= mViewInfo.selectedRegion.t0() && ls->selectedRegion.t1() <= mViewInfo.selectedRegion.t1() ) - { - Region *region = new Region; - region->start = ls->getT0(); - region->end = ls->getT1(); - regions.Add( region ); - } + regions.push_back(Region(ls->getT0(), ls->getT1())); } } //anything to do ? - if( regions.GetCount() == 0 ) + if( regions.size() == 0 ) return; //sort and remove unnecessary regions - regions.Sort( Region::cmp ); + std::sort(regions.begin(), regions.end()); unsigned int selected = 1; - while( selected < regions.GetCount() ) + while( selected < regions.size() ) { - Region *cur = regions.Item( selected ); - Region *last = regions.Item( selected - 1 ); - if( cur->start < last->end ) + const Region &cur = regions.at( selected ); + Region &last = regions.at( selected - 1 ); + if( cur.start < last.end ) { - if( cur->end > last->end ) - last->end = cur->end; - delete cur; - regions.RemoveAt( selected ); + if( cur.end > last.end ) + last.end = cur.end; + regions.erase( regions.begin() + selected ); } else selected++; @@ -4520,7 +4514,7 @@ void AudacityProject::EditByLabel( EditFunction action, Regions regions; GetRegionsByLabel( regions ); - if( regions.GetCount() == 0 ) + if( regions.size() == 0 ) return; TrackListIterator iter( mTracks ); @@ -4546,15 +4540,13 @@ void AudacityProject::EditByLabel( EditFunction action, (allTracks || n->GetSelected() || (bSyncLockedTracks && n->IsSyncLockSelected()))) { WaveTrack *wt = ( WaveTrack* )n; - for( int i = ( int )regions.GetCount() - 1; i >= 0; i-- ) - ( wt->*action )( regions.Item( i )->start, regions.Item( i )->end ); + for (int i = (int)regions.size() - 1; i >= 0; i--) { + const Region ®ion = regions.at(i); + (wt->*action)(region.start, region.end); + } } n = iter.Next(); } - - //delete label regions - for( unsigned int i = 0; i < regions.GetCount(); i++ ) - delete regions.Item( i ); } //Executes the edit function on all selected wave tracks with @@ -4568,7 +4560,7 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) Regions regions; GetRegionsByLabel( regions ); - if( regions.GetCount() == 0 ) + if( regions.size() == 0 ) return; TrackListIterator iter( mTracks ); @@ -4594,10 +4586,11 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) { WaveTrack *wt = ( WaveTrack* )n; WaveTrack *merged = NULL; - for( int i = ( int )regions.GetCount() - 1; i >= 0; i-- ) + for( int i = ( int )regions.size() - 1; i >= 0; i-- ) { Track *dest = NULL; - ( wt->*action )( regions.Item( i )->start, regions.Item( i )->end, + const Region ®ion = regions.at(i); + ( wt->*action )( region.start, region.end, &dest ); if( dest ) { @@ -4610,10 +4603,9 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) { // Paste to the beginning; unless this is the first region, // offset the track to account for time between the regions - if (i < (int)regions.GetCount() - 1) { + if (i < (int)regions.size() - 1) merged->Offset( - regions.Item(i+1)->start - regions.Item(i)->end); - } + regions.at(i + 1).start - region.end); bool bResult = merged->Paste( 0.0 , dest ); wxASSERT(bResult); // TO DO: Actually handle this. @@ -4621,21 +4613,18 @@ void AudacityProject::EditClipboardByLabel( EditDestFunction action ) } } else // nothing copied but there is a 'region', so the 'region' must be a 'point label' so offset - if (i < (int)regions.GetCount() - 1) - if( merged ) - merged->Offset(regions.Item(i+1)->start - regions.Item(i)->end); + if (i < (int)regions.size() - 1) + if (merged) + merged->Offset( + regions.at(i + 1).start - region.end); } if( merged ) msClipboard->Add( merged ); } } - msClipT0 = regions.Item(0)->start; - msClipT1 = regions.Item(regions.GetCount() - 1)->end; - - //delete label regions - for( unsigned int i = 0; i < regions.GetCount(); i++ ) - delete regions.Item( i ); + msClipT0 = regions.front().start; + msClipT1 = regions.back().end; } diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index a8ddbb95a..8dd55982a 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -145,21 +145,22 @@ public: for(size_t i=0;istart <= invalEnd+1 - && mRegions[i]->end >= invalStart-1) + InvalidRegion ®ion = mRegions[i]; + if(region.start <= invalEnd+1 + && region.end >= invalStart-1) { //take the union region - if(mRegions[i]->start > invalStart) - mRegions[i]->start = invalStart; - if(mRegions[i]->end < invalEnd) - mRegions[i]->end = invalEnd; + if(region.start > invalStart) + region.start = invalStart; + if(region.end < invalEnd) + region.end = invalEnd; added=true; break; } //this bit doesn't make sense because it assumes we add in order - now we go backwards after the initial OD finishes // //this array is sorted by start/end points and has no overlaps. If we've passed all possible intersections, insert. The array will remain sorted. -// if(mRegions[i]->end < invalStart) +// if(region.end < invalStart) // { // InvalidRegion* newRegion = new InvalidRegion(invalStart,invalEnd); // mRegions.insert(mRegions.begin()+i,newRegion); @@ -170,7 +171,7 @@ public: if(!added) { - InvalidRegion* newRegion = new InvalidRegion(invalStart,invalEnd); + InvalidRegion newRegion(invalStart,invalEnd); mRegions.insert(mRegions.begin(),newRegion); } @@ -179,24 +180,24 @@ public: for(size_t i=1;istart <= mRegions[i-1]->end+1 - && mRegions[i]->end >= mRegions[i-1]->start-1) + InvalidRegion ®ion = mRegions[i]; + InvalidRegion &prevRegion = mRegions[i - 1]; + if(region.start <= prevRegion.end+1 + && region.end >= prevRegion.start-1) { //take the union region - if(mRegions[i]->start > mRegions[i-1]->start) - mRegions[i]->start = mRegions[i-1]->start; - if(mRegions[i]->end < mRegions[i-1]->end) - mRegions[i]->end = mRegions[i-1]->end; + if(region.start > prevRegion.start) + region.start = prevRegion.start; + if(region.end < prevRegion.end) + region.end = prevRegion.end; - //now we must delete the previous region - delete mRegions[i-1]; mRegions.erase(mRegions.begin()+i-1); //musn't forget to reset cursor i--; } //if we are past the end of the region we added, we are past the area of regions that might be oversecting. - if(mRegions[i]->start > invalEnd) + if(region.start > invalEnd) { break; } @@ -205,15 +206,11 @@ public: //lock before calling these in a section. unlock after finished. int GetNumInvalidRegions() const {return mRegions.size();} - int GetInvalidRegionStart(int i) const {return mRegions[i]->start;} - int GetInvalidRegionEnd(int i) const {return mRegions[i]->end;} + int GetInvalidRegionStart(int i) const {return mRegions[i].start;} + int GetInvalidRegionEnd(int i) const {return mRegions[i].end;} void ClearInvalidRegions() { - for(size_t i =0;i mRegions; + std::vector mRegions; ODLock mRegionsMutex; }; diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 3f1465e4a..4b71c9954 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -1481,10 +1481,9 @@ bool WaveTrack::Disjoin(double t0, double t1) seqEnd = curSamplePos; if( seqEnd - seqStart + 1 > minSamples ) { - Region *region = new Region; - region->start = seqStart / GetRate() + clip->GetStartTime(); - region->end = seqEnd / GetRate() + clip->GetStartTime(); - regions.Add( region ); + regions.push_back(Region( + seqStart / GetRate() + clip->GetStartTime(), + seqEnd / GetRate() + clip->GetStartTime())); } seqStart = -1; } @@ -1493,10 +1492,10 @@ bool WaveTrack::Disjoin(double t0, double t1) } } - for( unsigned int i = 0; i < regions.GetCount(); i++ ) + for( unsigned int i = 0; i < regions.size(); i++ ) { - SplitDelete( regions.Item( i )->start, regions.Item( i )->end ); - delete regions.Item( i ); + const Region ®ion = regions.at(i); + SplitDelete(region.start, region.end ); } delete[] buffer; diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 7c4b6d298..8261206ba 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -17,6 +17,7 @@ #include "Experimental.h" #include "widgets/ProgressDialog.h" +#include #include #include #include @@ -40,17 +41,21 @@ class TimeWarper; /// \brief Structure to hold region of a wavetrack and a comparison function /// for sortability. -typedef struct REGION +struct Region { + Region() : start(0), end(0) {} + Region(double start_, double end_) : start(start_), end(end_) {} + double start, end; //used for sorting - static int cmp( REGION **a, REGION **b ) + bool operator < (const Region &b) const { - return ( ( *a )->start < ( *b )->start ) ? -1 : 1; + return this->start < b.start; } -}Region; -WX_DEFINE_ARRAY( Region*, Regions ); +}; + +class Regions : public std::vector < Region > {}; class Envelope; diff --git a/src/effects/TruncSilence.cpp b/src/effects/TruncSilence.cpp index db45b71e7..9d4126ec0 100644 --- a/src/effects/TruncSilence.cpp +++ b/src/effects/TruncSilence.cpp @@ -19,7 +19,7 @@ #include "TruncSilence.h" #include - +#include #include #include @@ -33,6 +33,9 @@ #include "../WaveTrack.h" #include "../widgets/valnum.h" +// Declaration of RegionList +class RegionList : public std::list < Region > {}; + enum kActions { kTruncate, @@ -71,9 +74,6 @@ static const double DEF_MinTruncMs = 0.001; // Typical fraction of total time taken by detection (better to guess low) const double detectFrac = 0.4; -#include -WX_DEFINE_LIST(RegionList); - BEGIN_EVENT_TABLE(EffectTruncSilence, wxEvtHandler) EVT_CHOICE(wxID_ANY, EffectTruncSilence::OnControlChange) EVT_TEXT(wxID_ANY, EffectTruncSilence::OnControlChange) @@ -178,13 +178,9 @@ double EffectTruncSilence::CalcPreviewInputLength(double /* previewLength */) // Master list of silent regions RegionList silences; - silences.DeleteContents(true); // Start with the whole selection silent - Region *sel = new Region; - sel->start = mT0; - sel->end = mT1; - silences.push_back(sel); + silences.push_back(Region(mT0, mT1)); SelectedTrackListOfKindIterator iter(Track::Wave, mTracks); int whichTrack = 0; @@ -193,7 +189,6 @@ double EffectTruncSilence::CalcPreviewInputLength(double /* previewLength */) WaveTrack *const wt = static_cast(t); RegionList trackSilences; - trackSilences.DeleteContents(true); sampleCount index = wt->TimeToLongSamples(mT0); sampleCount silentFrame = 0; // length of the current silence @@ -318,7 +313,6 @@ bool EffectTruncSilence::ProcessIndependently() Track *const last = link ? link : track; RegionList silences; - silences.DeleteContents(true); if (!FindSilences(silences, track, last)) return false; @@ -350,10 +344,9 @@ bool EffectTruncSilence::ProcessAll() // Copy tracks CopyInputTracks(Track::All); - // Master list of silent regions; it is responsible for deleting them. + // Master list of silent regions. // This list should always be kept in order. RegionList silences; - silences.DeleteContents(true); SelectedTrackListOfKindIterator iter(Track::Wave, mTracks); if (FindSilences(silences, iter.First(), iter.Last())) { @@ -373,10 +366,7 @@ bool EffectTruncSilence::FindSilences (RegionList &silences, Track *firstTrack, Track *lastTrack) { // Start with the whole selection silent - Region *sel = new Region; - sel->start = mT0; - sel->end = mT1; - silences.push_back(sel); + silences.push_back(Region(mT0, mT1)); // Remove non-silent regions in each track SelectedTrackListOfKindIterator iter(Track::Wave, mTracks); @@ -395,7 +385,6 @@ bool EffectTruncSilence::FindSilences // Scan the track for silences // RegionList trackSilences; - trackSilences.DeleteContents(true); sampleCount index = wt->TimeToLongSamples(mT0); sampleCount silentFrame = 0; @@ -413,10 +402,10 @@ bool EffectTruncSilence::FindSilences if (silentFrame >= minSilenceFrames) { // Track ended in silence -- record region - Region *r = new Region; - r->start = wt->LongSamplesToTime(index - silentFrame); - r->end = wt->LongSamplesToTime(index); - trackSilences.push_back(r); + trackSilences.push_back(Region( + wt->LongSamplesToTime(index - silentFrame), + wt->LongSamplesToTime(index) + )); } // Intersect with the overall silent region list @@ -441,7 +430,8 @@ bool EffectTruncSilence::DoRemoval RegionList::const_reverse_iterator rit; for (rit = silences.rbegin(); rit != silences.rend(); ++rit) { - Region *r = *rit; + const Region ®ion = *rit; + const Region *const r = ®ion; // Progress dialog and cancellation. Do additional cleanup before return. const double frac = detectFrac + @@ -597,7 +587,7 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, double curTime = wt->LongSamplesToTime(*index); for ( ; rit != silenceList.end(); ++rit) { // Find the first silent region ending after current time - if ((*rit)->end >= curTime) { + if (rit->end >= curTime) { break; } } @@ -613,16 +603,16 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, break; } - else if ((*rit)->start > curTime) { + else if (rit->start > curTime) { // End current silent region, skip ahead if (*silentFrame >= minSilenceFrames) { - Region *r = new Region; - r->start = wt->LongSamplesToTime(*index - *silentFrame); - r->end = wt->LongSamplesToTime(*index); - trackSilences.push_back(r); + trackSilences.push_back(Region( + wt->LongSamplesToTime(*index - *silentFrame), + wt->LongSamplesToTime(*index) + )); } *silentFrame = 0; - sampleCount newIndex = wt->TimeToLongSamples((*rit)->start); + sampleCount newIndex = wt->TimeToLongSamples(rit->start); if (inputLength) { sampleCount requiredTrackSamples = previewLen - outLength; // Add non-silent sample to outLength @@ -673,7 +663,10 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, Region *r = new Region; r->start = wt->LongSamplesToTime(*index + i - *silentFrame); r->end = wt->LongSamplesToTime(*index + i); - trackSilences.push_back(r); + trackSilences.push_back(Region( + wt->LongSamplesToTime(*index + i - *silentFrame), + wt->LongSamplesToTime(*index + i) + )); } else if (inputLength) { // included as part of non-silence outLength += *silentFrame; @@ -805,7 +798,7 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src) // Any time we reach the end of the dest list we're finished if (destIter == dest.end()) return; - Region *curDest = *destIter; + RegionList::iterator curDest = destIter; // Operation: find non-silent regions in src, remove them from dest. double nsStart = curDest->start; @@ -824,17 +817,16 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src) while (srcIter != src.end() || lastRun) { // Don't use curSrc unless lastRun is false! - Region *curSrc; + RegionList::const_iterator curSrc; if (lastRun) { // The last non-silent region extends as far as possible - curSrc = NULL; nsEnd = std::numeric_limits::max(); } else { - curSrc = *srcIter; + curSrc = srcIter; nsEnd = curSrc->start; } @@ -848,16 +840,14 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src) { return; } - curDest = *destIter; + curDest = destIter; } // Check for splitting dest region in two if (nsStart > curDest->start && nsEnd < curDest->end) { // The second region - Region *r = new Region; - r->start = nsEnd; - r->end = curDest->end; + Region r(nsEnd, curDest->end); // The first region curDest->end = nsStart; @@ -871,16 +861,12 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src) // versions it returns the wrong value. Second, in some versions, // it crashes when you insert at list end. if (nextIt == dest.end()) - { - dest.Append(r); - } + dest.push_back(r); else - { dest.insert(nextIt, r); - } ++destIter; // (now points at the newly-inserted region) - curDest = *destIter; + curDest = destIter; } // Check for truncating the end of dest region @@ -894,7 +880,7 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src) { return; } - curDest = *destIter; + curDest = destIter; } // Check for all dest regions that need to be removed completely @@ -905,7 +891,7 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src) { return; } - curDest = *destIter; + curDest = destIter; } // Check for truncating the beginning of dest region diff --git a/src/effects/TruncSilence.h b/src/effects/TruncSilence.h index 0d89a494a..5fd68587d 100644 --- a/src/effects/TruncSilence.h +++ b/src/effects/TruncSilence.h @@ -31,10 +31,7 @@ class wxCheckBox; #define TRUNCATESILENCE_PLUGIN_SYMBOL XO("Truncate Silence") -// Declaration of RegionList -struct REGION; -typedef struct REGION Region; -WX_DECLARE_LIST(Region, RegionList); +class RegionList; class EffectTruncSilence : public Effect {