From 3c4a15f5cb395e23656db76883672840b8f6655f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 26 Dec 2016 14:53:59 -0500 Subject: [PATCH 1/4] Remove some unused members --- src/ondemand/ODComputeSummaryTask.cpp | 2 -- src/ondemand/ODComputeSummaryTask.h | 1 - src/ondemand/ODDecodeTask.cpp | 2 -- src/ondemand/ODDecodeTask.h | 1 - 4 files changed, 6 deletions(-) diff --git a/src/ondemand/ODComputeSummaryTask.cpp b/src/ondemand/ODComputeSummaryTask.cpp index 9d31aaf10..35ca63562 100644 --- a/src/ondemand/ODComputeSummaryTask.cpp +++ b/src/ondemand/ODComputeSummaryTask.cpp @@ -31,7 +31,6 @@ updating the ODPCMAliasBlockFile and the GUI of the newly available data. ODComputeSummaryTask::ODComputeSummaryTask() { mMaxBlockFiles = 0; - mComputedBlockFiles = 0; mHasUpdateRan=false; } @@ -83,7 +82,6 @@ void ODComputeSummaryTask::DoSomeInternal() success = true; blockStartSample = bf->GetStart(); blockEndSample = blockStartSample + bf->GetLength(); - mComputedBlockFiles++; } else { diff --git a/src/ondemand/ODComputeSummaryTask.h b/src/ondemand/ODComputeSummaryTask.h index 2863e4214..544a7d62e 100644 --- a/src/ondemand/ODComputeSummaryTask.h +++ b/src/ondemand/ODComputeSummaryTask.h @@ -75,7 +75,6 @@ protected: ODLock mBlockFilesMutex; std::vector< std::shared_ptr< ODPCMAliasBlockFile > > mBlockFiles; int mMaxBlockFiles; - int mComputedBlockFiles; ODLock mHasUpdateRanMutex; bool mHasUpdateRan; }; diff --git a/src/ondemand/ODDecodeTask.cpp b/src/ondemand/ODDecodeTask.cpp index 457d6d0e7..636ba8b9c 100644 --- a/src/ondemand/ODDecodeTask.cpp +++ b/src/ondemand/ODDecodeTask.cpp @@ -27,7 +27,6 @@ updating the ODDecodeBlockFile and the GUI of the newly available data. ODDecodeTask::ODDecodeTask() { mMaxBlockFiles = 0; - mComputedBlockFiles = 0; } @@ -74,7 +73,6 @@ void ODDecodeTask::DoSomeInternal() success = true; blockStartSample = bf->GetStart(); blockEndSample = blockStartSample + bf->GetLength(); - mComputedBlockFiles++; } } else diff --git a/src/ondemand/ODDecodeTask.h b/src/ondemand/ODDecodeTask.h index f0d83ed72..dbee9b4b3 100644 --- a/src/ondemand/ODDecodeTask.h +++ b/src/ondemand/ODDecodeTask.h @@ -93,7 +93,6 @@ protected: std::vector> mDecoders; int mMaxBlockFiles; - int mComputedBlockFiles; }; From 0af9b46eac4a64181d30f78bd2145236cc495f35 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 25 Jan 2016 22:46:56 -0500 Subject: [PATCH 2/4] Move many fields out of Envelope that are needed only during editing --- src/Envelope.cpp | 225 ++++++++++++++++++++--------------- src/Envelope.h | 118 +++++++++++------- src/TimeTrack.cpp | 2 - src/TrackArtist.cpp | 4 +- src/TrackPanel.cpp | 50 ++++---- src/TrackPanel.h | 4 + src/WaveTrack.cpp | 12 -- src/WaveTrack.h | 1 - src/effects/Equalization.cpp | 9 +- src/effects/Equalization.h | 2 + src/effects/NoiseRemoval.cpp | 3 +- 11 files changed, 244 insertions(+), 186 deletions(-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 7ae799fed..a78d4df0b 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -57,27 +57,19 @@ Envelope::Envelope() mDB = true; mDefaultValue = 1.0; mDragPoint = -1; - mDirty = false; - mIsDeleting = false; - mMirror = true; mMinValue = 1.0e-7; mMaxValue = 2.0; - mButton = wxMOUSE_BTN_NONE; - mSearchGuess = -1; + + mDragPointValid = false; } Envelope::~Envelope() { } -void Envelope::Mirror(bool mirror) -{ - mMirror = mirror; -} - /// 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 @@ -112,6 +104,84 @@ void Envelope::Flatten(double value) mDefaultValue = ClampValue(value); } +void Envelope::SetDragPoint(int dragPoint) +{ + mDragPoint = std::max(-1, std::min(int(mEnv.size() - 1), dragPoint)); + mDragPointValid = (mDragPoint >= 0); +} + +void Envelope::SetDragPointValid(bool valid) +{ + mDragPointValid = (valid && mDragPoint >= 0); + if (mDragPoint >= 0 && !valid) { + // We're going to be deleting the point; On + // screen we show this by having the envelope move to + // the position it will have after deletion of the point. + // Without deleting the point we move it left or right + // to the same position as the previous or next point. + + static const double big = std::numeric_limits::max(); + auto size = mEnv.size(); + + if( size <= 1) { + // There is only one point - just move it + // off screen and at default height. + // temporary state when dragging only! + mEnv[mDragPoint].SetT(big); + mEnv[mDragPoint].SetVal(mDefaultValue); + return; + } + else if ( mDragPoint + 1 == size ) { + // Put the point at the height of the last point, but also off screen. + mEnv[mDragPoint].SetT(big); + mEnv[mDragPoint].SetVal(mEnv[ size - 1 ].GetVal()); + } + else { + // Place it exactly on its right neighbour. + // That way the drawing code will overpaint the dark dot with + // a light dot, as if it were deleted. + const auto &neighbor = mEnv[mDragPoint + 1]; + mEnv[mDragPoint].SetT(neighbor.GetT()); + mEnv[mDragPoint].SetVal(neighbor.GetVal()); + } + } +} + +void Envelope::MoveDragPoint(double newWhen, double value) +{ + SetDragPointValid(true); + if (!mDragPointValid) + return; + + // We'll limit the drag point time to be between those of the preceding + // and next envelope point. + double limitLo = 0.0; + double limitHi = mTrackLen; + + if (mDragPoint > 0) + limitLo = std::max(limitLo, mEnv[mDragPoint - 1].GetT()); + if (mDragPoint + 1 < mEnv.size()) + limitHi = std::min(limitHi, mEnv[mDragPoint + 1].GetT()); + + EnvPoint &dragPoint = mEnv[mDragPoint]; + const double tt = + std::max(limitLo, std::min(limitHi, newWhen)); + + // This might temporary violate the constraint that at most two + // points share a time value. + dragPoint.SetT(tt); + dragPoint.SetVal(value); +} + +void Envelope::ClearDragPoint() +{ + if (!mDragPointValid && mDragPoint >= 0) + Delete(mDragPoint); + + mDragPoint = -1; + mDragPointValid = false; +} + void Envelope::SetRange(double minValue, double maxValue) { mMinValue = minValue; mMaxValue = maxValue; @@ -186,7 +256,7 @@ static void DrawPoint(wxDC & dc, const wxRect & r, int x, int y, bool top) /// TODO: This should probably move to track artist. void Envelope::DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax) const + float zoomMin, float zoomMax, bool mirrored) const { dc.SetPen(AColor::envelopePen); dc.SetBrush(*wxWHITE_BRUSH); @@ -207,7 +277,7 @@ void Envelope::DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, y = GetWaveYPos(v, zoomMin, zoomMax, r.height, dB, true, dBRange, false); - if (!mMirror) { + if (!mirrored) { DrawPoint(dc, r, x, y, true); } else { @@ -311,7 +381,7 @@ inline int SQR(int x) { return x * x; } /// @dB - display mode either linear or log. /// @zoomMin - vertical scale, typically -1.0 /// @zoomMax - vertical scale, typically +1.0 -float Envelope::ValueOfPixel( int y, int height, bool upper, +float EnvelopeEditor::ValueOfPixel( int y, int height, bool upper, bool dB, double dBRange, float zoomMin, float zoomMax) { @@ -320,9 +390,9 @@ float Envelope::ValueOfPixel( int y, int height, bool upper, // 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); + return mEnvelope.ClampValue(v); else - return ClampValue(-v); + return mEnvelope.ClampValue(-v); } /// HandleMouseButtonDown either finds an existing control point or adds a NEW one @@ -331,13 +401,13 @@ float Envelope::ValueOfPixel( int y, int height, bool upper, /// a given time value: /// We have an upper and lower envelope line. /// Also we may be showing an inner envelope (at 0.5 the range). -bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, +bool EnvelopeEditor::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin, float zoomMax) { int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin)); - bool upper = !mMirror || (zoomMin >= 0.0) || (event.m_y - r.y < ctr); + bool upper = !mMirrored || (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 @@ -348,16 +418,15 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, // Member variables hold state that will be needed in dragging. mButton = event.GetButton(); - mIsDeleting = false; mContourOffset = false; // wxLogDebug(wxT("Y:%i Height:%i Offset:%i"), y, height, mContourOffset ); - int len = mEnv.size(); + int len = mEnvelope.GetNumberOfPoints(); // 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 = mEnvelope[i].GetT() + mEnvelope.GetOffset(); const wxInt64 position = zoomInfo.TimeToPosition(time); if (position >= 0 && position < r.width) { @@ -366,7 +435,7 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, int numControlPoints; // Outer control points - double value = mEnv[i].GetVal(); + double value = mEnvelope[i].GetVal(); y[0] = GetWaveYPos(value, zoomMin, zoomMax, r.height, dB, true, dBRange, false); y[1] = GetWaveYPos(-value, zoomMin, zoomMax, r.height, @@ -383,7 +452,7 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, if (y[2] > y[3]) numControlPoints = 2; - if (!mMirror) + if (!mMirrored) numControlPoints = 1; const int deltaXSquared = SQR(x - (event.m_x - r.x)); @@ -400,7 +469,7 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, } if (bestNum >= 0) { - mDragPoint = bestNum; + mEnvelope.SetDragPoint(bestNum); } else { // TODO: Extract this into a function CreateNewPoint @@ -409,13 +478,13 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, // if (when <= 0 || when >= mTrackLen) // return false; - const double v = GetValue( when ); + const double v = mEnvelope.GetValue( when ); int ct = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB, false, dBRange, false) ; int cb = GetWaveYPos( -v-.000000001, zoomMin, zoomMax, r.height, dB, false, dBRange, false) ; - if( ct <= cb || !mMirror ){ + if (ct <= cb || !mMirrored) { int t = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB, true, dBRange, false) ; int b = GetWaveYPos( -v, zoomMin, zoomMax, r.height, dB, @@ -424,7 +493,7 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, ct = (t + ct) / 2; cb = (b + cb) / 2; - if(mMirror && + if (mMirrored && (event.m_y - r.y) > ct && ((event.m_y - r.y) < cb)) mContourOffset = true; @@ -435,50 +504,22 @@ bool Envelope::HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, double newVal = ValueOfPixel(clip_y, r.height, upper, dB, dBRange, zoomMin, zoomMax); - mDragPoint = Insert(when - mOffset, newVal); + mEnvelope.SetDragPoint(mEnvelope.Insert(when - mEnvelope.GetOffset(), newVal)); mDirty = true; } mUpper = upper; - mInitialVal = mEnv[mDragPoint].GetVal(); - - mInitialY = event.m_y+mContourOffset; + // const int dragPoint = mEnvelope.GetDragPoint(); + // mInitialVal = mEnvelope[dragPoint].GetVal(); + // mInitialY = event.m_y+mContourOffset; return true; } -/// Mark dragged point for deletion. -/// It will be deleted on mouse button up. -void Envelope::MarkDragPointForDeletion() -{ - mIsDeleting = true; - - // We're going to be deleting the point; On - // screen we show this by having the envelope move to - // the position it will have after deletion of the point. - // Without delting the point we move it left or right - // to the same position as the previous or next point. - - 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); - 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()); -} - -void Envelope::MoveDraggedPoint( const wxMouseEvent & event, wxRect & r, - const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax) +void EnvelopeEditor::MoveDragPoint(const wxMouseEvent & event, wxRect & r, + const ZoomInfo &zoomInfo, bool dB, double dBRange, + float zoomMin, float zoomMax) { int clip_y = event.m_y - r.y; if(clip_y < 0) clip_y = 0; @@ -491,29 +532,14 @@ void Envelope::MoveDraggedPoint( const wxMouseEvent & event, wxRect & r, // TODO: However because mTrackEpsilon assumes 200KHz this use // of epsilon is a tad bogus. What we need to do instead is DELETE // a duplicated point on a mouse up. - double newWhen = zoomInfo.PositionToTime(event.m_x, r.x) - mOffset; - - // We'll limit the drag point time to be between those of the preceding - // and next envelope point. - double limitLo = 0.0; - double limitHi = mTrackLen; - - if (mDragPoint > 0) - 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); - + double newWhen = zoomInfo.PositionToTime(event.m_x, r.x) - mEnvelope.GetOffset(); + mEnvelope.MoveDragPoint(newWhen, newVal); } -bool Envelope::HandleDragging( const wxMouseEvent & event, wxRect & r, +bool EnvelopeEditor::HandleDragging(const wxMouseEvent & event, wxRect & r, const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax) + float zoomMin, float zoomMax, + float WXUNUSED(eMin), float WXUNUSED(eMax)) { mDirty = true; @@ -523,27 +549,24 @@ bool Envelope::HandleDragging( const wxMouseEvent & event, wxRect & r, if (larger.Contains(event.m_x, event.m_y)) { // IF we're in the rect THEN we're not deleting this point (anymore). - mIsDeleting = false; // ...we're dragging it. - MoveDraggedPoint( event, r, zoomInfo, dB, dBRange, zoomMin, zoomMax); + MoveDragPoint( event, r, zoomInfo, dB, dBRange, zoomMin, zoomMax); return true; } - if(mIsDeleting ) + if(!mEnvelope.GetDragPointValid()) // IF we already know we're deleting THEN no envelope point to update. return false; - MarkDragPointForDeletion(); + // Invalidate the point + mEnvelope.SetDragPointValid(false); return true; } -// Exit dragging mode and deletes dragged point if neccessary. -bool Envelope::HandleMouseButtonUp() +// Exit dragging mode and delete dragged point if neccessary. +bool EnvelopeEditor::HandleMouseButtonUp() { - if (mIsDeleting) { - Delete(mDragPoint); - } - mDragPoint = -1; + mEnvelope.ClearDragPoint(); mButton = wxMOUSE_BTN_NONE; return true; } @@ -559,14 +582,14 @@ void Envelope::Insert(int point, const EnvPoint &p) } // Returns true if parent needs to be redrawn -bool Envelope::MouseEvent(const wxMouseEvent & event, wxRect & r, +bool EnvelopeEditor::MouseEvent(const wxMouseEvent & event, wxRect & r, const ZoomInfo &zoomInfo, bool dB, double dBRange, float zoomMin, float zoomMax) { if (event.ButtonDown() && mButton == wxMOUSE_BTN_NONE) return HandleMouseButtonDown( event, r, zoomInfo, dB, dBRange, zoomMin, zoomMax); - if (event.Dragging() && mDragPoint >= 0) + if (event.Dragging() && mEnvelope.GetDragPoint() >= 0) return HandleDragging( event, r, zoomInfo, dB, dBRange, zoomMin, zoomMax); if (event.ButtonUp() && event.GetButton() == mButton) @@ -1523,7 +1546,6 @@ void Envelope::testMe() double t0=0, t1=0; SetInterpolateDB(false); - Mirror(false); Flatten(0.5); checkResult( 1, Integral(0.0,100.0), 50); @@ -1575,3 +1597,18 @@ void Envelope::testMe() checkResult( 19, NextPointAfter( 5 ), 10 ); } +EnvelopeEditor::EnvelopeEditor(Envelope &envelope, bool mirrored) + : mEnvelope(envelope) + , mMirrored(mirrored) + , mContourOffset(-1) + // , mInitialVal(-1.0) + // , mInitialY(-1) + , mUpper(false) + , mButton(wxMOUSE_BTN_NONE) + , mDirty(false) +{ +} + +EnvelopeEditor::~EnvelopeEditor() +{ +} diff --git a/src/Envelope.h b/src/Envelope.h index 2da8ad7cb..a95222066 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -81,13 +81,14 @@ class Envelope final : public XMLTagHandler { virtual ~ Envelope(); + double GetOffset() const { return mOffset; } + double GetTrackLen() const { return mTrackLen; } + bool GetInterpolateDB() { return mDB; } void SetInterpolateDB(bool db) { mDB = db; } - void Mirror(bool mirror); void Rescale(double minValue, double maxValue); void Flatten(double value); - int GetDragPoint(void) {return mDragPoint;} double GetMinValue() const { return mMinValue; } double GetMaxValue() const { return mMaxValue; } @@ -107,21 +108,8 @@ class Envelope final : public XMLTagHandler { void WriteXML(XMLWriter &xmlFile) const /* not override */; void DrawPoints(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo, - bool dB, double dBRange, - float zoomMin, float zoomMax) const; - - // Event Handlers - // Each ofthese returns true if parents needs to be redrawn - bool MouseEvent(const wxMouseEvent & event, wxRect & r, - const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax); - bool HandleMouseButtonDown( const wxMouseEvent & event, wxRect & r, - const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax); - bool HandleDragging( const wxMouseEvent & event, wxRect & r, - const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax); - bool HandleMouseButtonUp(); + bool dB, double dBRange, + float zoomMin, float zoomMax, bool mirrored) const; // Handling Cut/Copy/Paste events void CollapseRegion(double t0, double t1); @@ -181,28 +169,38 @@ class Envelope final : public XMLTagHandler { /** \brief Return number of points */ size_t GetNumberOfPoints() const; +private: + friend class EnvelopeEditor; /** \brief Accessor for points */ - const EnvPoint &operator[] (int index) const + EnvPoint &operator[] (int index) { return mEnv[index]; } +public: /** \brief Returns the sets of when and value pairs */ void GetPoints(double *bufferWhen, - double *bufferValue, - int bufferLen) const; + double *bufferValue, + int bufferLen) const; + + // UI-related + // The drag point needs to display differently. + int GetDragPoint() const { return mDragPoint; } + // Choose the drag point. + void SetDragPoint(int dragPoint); + // Mark or unmark the drag point for deletion. + void SetDragPointValid(bool valid); + bool GetDragPointValid() const { return mDragPointValid; } + // Modify the dragged point and change its value. + // But consistency constraints may move it less then you ask for. + void MoveDragPoint(double newWhen, double value); + // May delete the drag point. Restores envelope consistency. + void ClearDragPoint(); private: EnvPoint * AddPointAtEnd( double t, double val ); - void MarkDragPointForDeletion(); - float ValueOfPixel( int y, int height, bool upper, - bool dB, double dBRange, - float zoomMin, float zoomMax); void BinarySearchForTime( int &Lo, int &Hi, double t ) const; double GetInterpolationStartValueAtPoint( int iPoint ) const; - void MoveDraggedPoint( const wxMouseEvent & event, wxRect & r, - const ZoomInfo &zoomInfo, bool dB, double dBRange, - float zoomMin, float zoomMax); // Possibly inline functions: // This function resets them integral memoizers (call whenever the Envelope changes) @@ -210,7 +208,6 @@ private: // The list of envelope control points. EnvArray mEnv; - bool mMirror; /** \brief The time at which the envelope starts, i.e. the start offset */ double mOffset; @@ -224,21 +221,7 @@ private: * before being considered the same point */ double mTrackEpsilon; double mDefaultValue; - - /** \brief Number of pixels contour is from the true envelope. */ - int mContourOffset; - - double mInitialVal; - - // These are used in dragging. - int mDragPoint; - int mInitialY; - bool mUpper; - bool mIsDeleting; - int mButton; bool mDB; - bool mDirty; - double mMinValue, mMaxValue; // These are memoizing variables for Integral() @@ -246,8 +229,11 @@ private: double lastIntegral_t1; double lastIntegral_result; - mutable int mSearchGuess; + // UI stuff + bool mDragPointValid; + int mDragPoint; + mutable int mSearchGuess; }; inline EnvPoint::EnvPoint(Envelope *envelope, double t, double val) @@ -262,5 +248,49 @@ inline void EnvPoint::SetVal(double val) mVal = mEnvelope->ClampValue(val); } -#endif +// A class that holds state for the duration of dragging +// of an envelope point. +class EnvelopeEditor +{ +public: + EnvelopeEditor(Envelope &envelope, bool mirrored); + ~EnvelopeEditor(); + // Event Handlers + // Each of these returns true if the envelope needs to be redrawn + bool MouseEvent(const wxMouseEvent & event, wxRect & r, + const ZoomInfo &zoomInfo, bool dB, double dBRange, + float zoomMin = -1.0, float zoomMax = 1.0); + +private: + bool HandleMouseButtonDown(const wxMouseEvent & event, wxRect & r, + const ZoomInfo &zoomInfo, bool dB, double dBRange, + float zoomMin = -1.0, float zoomMax = 1.0); + bool HandleDragging(const wxMouseEvent & event, wxRect & r, + const ZoomInfo &zoomInfo, bool dB, double dBRange, + float zoomMin = -1.0, float zoomMax = 1.0, float eMin = 0., float eMax = 2.); + bool HandleMouseButtonUp(); + +private: + float ValueOfPixel(int y, int height, bool upper, + bool dB, double dBRange, + float zoomMin, float zoomMax); + void MoveDragPoint(const wxMouseEvent & event, wxRect & r, + const ZoomInfo &zoomInfo, bool dB, double dBRange, + float zoomMin, float zoomMax); + + Envelope &mEnvelope; + const bool mMirrored; + + /** \brief Number of pixels contour is from the true envelope. */ + int mContourOffset; + + // double mInitialVal; + + // int mInitialY; + bool mUpper; + int mButton; + bool mDirty; +}; + +#endif diff --git a/src/TimeTrack.cpp b/src/TimeTrack.cpp index 4be32cfd5..bdfa67d8f 100644 --- a/src/TimeTrack.cpp +++ b/src/TimeTrack.cpp @@ -48,7 +48,6 @@ TimeTrack::TimeTrack(const std::shared_ptr &projDirManager, const Zo mEnvelope->SetTrackLen(DBL_MAX); mEnvelope->SetInterpolateDB(true); mEnvelope->Flatten(1.0); - mEnvelope->Mirror(false); mEnvelope->SetOffset(0); mEnvelope->SetRange(TIMETRACK_MIN, TIMETRACK_MAX); @@ -75,7 +74,6 @@ TimeTrack::TimeTrack(const TimeTrack &orig): mEnvelope->SetTrackLen(DBL_MAX); SetInterpolateLog(orig.GetInterpolateLog()); // this calls Envelope::SetInterpolateDB mEnvelope->Flatten(1.0); - mEnvelope->Mirror(false); mEnvelope->SetOffset(0); mEnvelope->SetRange(orig.mEnvelope->GetMinValue(), orig.mEnvelope->GetMaxValue()); mEnvelope->Paste(0.0, orig.mEnvelope.get()); diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp index 2c3ee0f68..6838ae735 100644 --- a/src/TrackArtist.cpp +++ b/src/TrackArtist.cpp @@ -1926,7 +1926,7 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track, if (drawEnvelope) { DrawEnvelope(dc, mid, env, zoomMin, zoomMax, dB, dBRange); - clip->GetEnvelope()->DrawPoints(dc, rect, zoomInfo, dB, dBRange, zoomMin, zoomMax); + clip->GetEnvelope()->DrawPoints(dc, rect, zoomInfo, dB, dBRange, zoomMin, zoomMax, true); } // Draw arrows on the left side if the track extends to the left of the @@ -3209,7 +3209,7 @@ void TrackArtist::DrawTimeTrack(const TimeTrack *track, upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / mdBrange + 1.0; } track->GetEnvelope()->DrawPoints(dc, envRect, zoomInfo, - track->GetDisplayLog(), mdBrange, lower, upper); + track->GetDisplayLog(), mdBrange, lower, upper, false); } void TrackArtist::UpdatePrefs() diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 1b8fd67df..66bace059 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -3213,8 +3213,13 @@ void TrackPanel::ForwardEventToTimeTrackEnvelope(wxMouseEvent & event) lower = LINEAR_TO_DB(std::max(1.0e-7, lower)) / dBRange + 1.0; upper = LINEAR_TO_DB(std::max(1.0e-7, upper)) / dBRange + 1.0; } + if (event.ButtonDown()) { + mEnvelopeEditor = std::make_unique(*pspeedenvelope, false); + mEnvelopeEditorRight.reset(); + } bool needUpdate = - pspeedenvelope->MouseEvent( + mEnvelopeEditor && + mEnvelopeEditor->MouseEvent( event, envRect, *mViewInfo, ptimetrack->GetDisplayLog(), dBRange, lower, upper); @@ -3250,7 +3255,13 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) wxRect envRect = mCapturedRect; float zoomMin, zoomMax; pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); - needUpdate = penvelope->MouseEvent( + if (event.ButtonDown()) { + mEnvelopeEditor = std::make_unique(*penvelope, true); + mEnvelopeEditorRight.reset(); + } + needUpdate = + mEnvelopeEditor && + mEnvelopeEditor->MouseEvent( event, envRect, *mViewInfo, dB, dBRange, zoomMin, zoomMax); @@ -3260,30 +3271,23 @@ void TrackPanel::ForwardEventToWaveTrackEnvelope(wxMouseEvent & event) // Assume linked track is wave or null const auto link = static_cast(mCapturedTrack->GetLink()); if (link) { - Envelope *e2 = link->GetEnvelopeAtX(event.GetX()); - // There isn't necessarily an envelope there; no guarantee a - // linked track has the same WaveClip structure... - bool updateNeeded = false; - if (e2) { + if (event.ButtonDown()) { + Envelope *e2 = link->GetEnvelopeAtX(event.GetX()); + if (e2) + mEnvelopeEditorRight = std::make_unique(*e2, true); + else { + // There isn't necessarily an envelope there; no guarantee a + // linked track has the same WaveClip structure... + } + } + if (mEnvelopeEditorRight) { wxRect envRect = mCapturedRect; float zoomMin, zoomMax; pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); - updateNeeded = e2->MouseEvent(event, envRect, - *mViewInfo, dB, dBRange, - zoomMin, zoomMax); - needUpdate |= updateNeeded; - } - if(!e2 || !updateNeeded) // no envelope found at this x point, or found but not updated - { - if( (e2 = link->GetActiveEnvelope()) != 0 ) // search for any active DragPoint - { - wxRect envRect = mCapturedRect; - float zoomMin, zoomMax; - pwavetrack->GetDisplayBounds(&zoomMin, &zoomMax); - needUpdate |= e2->MouseEvent(event, envRect, - *mViewInfo, dB, dBRange, - zoomMin, zoomMax); - } + needUpdate|= mEnvelopeEditorRight->MouseEvent(event, envRect, + *mViewInfo, + dB, dBRange, + zoomMin, zoomMax); } } diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 6adc12be8..76af1ecc1 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -30,6 +30,7 @@ class wxMenu; class wxRect; +class EnvelopeEditor; class LabelTrack; class SpectrumAnalyst; class TrackPanel; @@ -809,6 +810,9 @@ protected: // Keeps track of extra fractional vertical scroll steps double mVertScrollRemainder; + std::unique_ptr mEnvelopeEditor; + std::unique_ptr mEnvelopeEditorRight; + protected: // The screenshot class needs to access internals diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 174d612ce..87018fee4 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -2228,18 +2228,6 @@ Envelope* WaveTrack::GetEnvelopeAtX(int xcoord) return NULL; } -// Search for any active DragPoint on the current track -Envelope* WaveTrack::GetActiveEnvelope(void) -{ - for (const auto &clip : mClips) - { - Envelope* env = clip->GetEnvelope() ; - if (env->GetDragPoint() >= 0) - return env; - } - return NULL; -} - Sequence* WaveTrack::GetSequenceAtX(int xcoord) { WaveClip* clip = GetClipAtX(xcoord); diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 4d729da84..372169b6a 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -264,7 +264,6 @@ class AUDACITY_DLL_API WaveTrack final : public Track { WaveClip* GetClipAtX(int xcoord); Sequence* GetSequenceAtX(int xcoord); Envelope* GetEnvelopeAtX(int xcoord); - Envelope* GetActiveEnvelope(void); WaveClip* GetClipAtSample(sampleCount sample); diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 0138d36ba..9cd91036c 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -241,12 +241,10 @@ EffectEqualization::EffectEqualization() mLogEnvelope = std::make_unique(); mLogEnvelope->SetInterpolateDB(false); - mLogEnvelope->Mirror(false); mLogEnvelope->SetRange(MIN_dBMin, MAX_dBMax); // MB: this is the highest possible range mLinEnvelope = std::make_unique(); mLinEnvelope->SetInterpolateDB(false); - mLinEnvelope->Mirror(false); mLinEnvelope->SetRange(MIN_dBMin, MAX_dBMax); // MB: this is the highest possible range mEnvelope = (mLin ? mLinEnvelope : mLogEnvelope).get(); @@ -2365,7 +2363,6 @@ void EffectEqualization::ErrMin(void) int j=0; Envelope testEnvelope; testEnvelope.SetInterpolateDB(false); - testEnvelope.Mirror(false); testEnvelope.SetRange(-120.0, 60.0); testEnvelope.Flatten(0.); testEnvelope.SetTrackLen(1.0); @@ -2893,8 +2890,8 @@ EqualizationPanel::EqualizationPanel(EffectEqualization *effect, wxWindow *paren mWidth = 0; mHeight = 0; + mEditor = std::make_unique(*mEffect->mEnvelope, false); mEffect->mEnvelope->Flatten(0.); - mEffect->mEnvelope->Mirror(false); mEffect->mEnvelope->SetTrackLen(1.0); ForceRecalc(); @@ -3103,7 +3100,7 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) if( mEffect->mDraw->GetValue() ) { mEffect->mEnvelope->DrawPoints(memDC, mEnvRect, ZoomInfo(0.0, mEnvRect.width-1), false, 0.0, - mEffect->mdBMin, mEffect->mdBMax); + mEffect->mdBMin, mEffect->mdBMax, false); } dc.Blit(0, 0, mWidth, mHeight, &memDC, 0, 0, wxCOPY, FALSE); @@ -3121,7 +3118,7 @@ void EqualizationPanel::OnMouseEvent(wxMouseEvent & event) CaptureMouse(); } - if (mEffect->mEnvelope->MouseEvent(event, mEnvRect, ZoomInfo(0.0, mEnvRect.width), + if (mEditor->MouseEvent(event, mEnvRect, ZoomInfo(0.0, mEnvRect.width), false, 0.0, mEffect->mdBMin, mEffect->mdBMax)) { diff --git a/src/effects/Equalization.h b/src/effects/Equalization.h index 8923ad9b1..9be3d2da4 100644 --- a/src/effects/Equalization.h +++ b/src/effects/Equalization.h @@ -46,6 +46,7 @@ class Envelope; +class EnvelopeEditor; class EqualizationPanel; // @@ -308,6 +309,7 @@ public: private: wxWindow *mParent; EffectEqualization *mEffect; + std::unique_ptr mEditor; bool mRecalcRequired; diff --git a/src/effects/NoiseRemoval.cpp b/src/effects/NoiseRemoval.cpp index 99f1bd88b..effefc33c 100644 --- a/src/effects/NoiseRemoval.cpp +++ b/src/effects/NoiseRemoval.cpp @@ -45,7 +45,6 @@ #include "NoiseRemoval.h" -#include "../Envelope.h" #include "../WaveTrack.h" #include "../Prefs.h" #include "../Project.h" @@ -883,4 +882,4 @@ void NoiseRemovalDialog::OnTimeSlider(wxCommandEvent & WXUNUSED(event)) mTimeT->SetValue(wxString::Format(wxT("%.2f"), mTime)); } -#endif \ No newline at end of file +#endif From b9e4aa01ebc601260fe6742c5785be82600a4a22 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 7 Jan 2017 14:49:20 -0500 Subject: [PATCH 3/4] Simplify Normalize by removing needless member variables --- src/effects/Normalize.cpp | 75 +++++++++++++++++++-------------------- src/effects/Normalize.h | 16 ++++----- 2 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/effects/Normalize.cpp b/src/effects/Normalize.cpp index bf1664312..627783c08 100644 --- a/src/effects/Normalize.cpp +++ b/src/effects/Normalize.cpp @@ -163,7 +163,7 @@ bool EffectNormalize::Process() WaveTrack *track = (WaveTrack *) iter.First(); WaveTrack *prevTrack; prevTrack = track; - mCurTrackNum = 0; + int curTrackNum = 0; wxString topMsg; if(mDC && mGain) topMsg = _("Removing DC offset and Normalizing...\n"); @@ -193,9 +193,11 @@ bool EffectNormalize::Process() msg = topMsg + _("Analyzing: ") + trackName; else msg = topMsg + _("Analyzing first track of stereo pair: ") + trackName; - AnalyseTrack(track, msg); // sets mOffset and offset-adjusted mMin and mMax - if(!track->GetLinked() || mStereoInd) { // mono or 'stereo tracks independently' - float extent = wxMax(fabs(mMax), fabs(mMin)); + float offset, min, max; + AnalyseTrack(track, msg, curTrackNum, offset, min, max); + if(!track->GetLinked() || mStereoInd) { + // mono or 'stereo tracks independently' + float extent = wxMax(fabs(max), fabs(min)); if( (extent > 0) && mGain ) mMult = ratio / extent; else @@ -204,7 +206,7 @@ bool EffectNormalize::Process() if(track->GetLinked() || prevTrack->GetLinked()) // only get here if there is a linked track but we are processing independently msg = topMsg + _("Processing stereo channels independently: ") + trackName; - if (!ProcessOne(track, msg)) + if (!ProcessOne(track, msg, curTrackNum, offset)) { bGoodResult = false; break; @@ -215,37 +217,27 @@ bool EffectNormalize::Process() // we have a linked stereo track // so we need to find it's min, max and offset // as they are needed to calc the multiplier for both tracks - float offset1 = mOffset; // remember ones from first track - float min1 = mMin; - float max1 = mMax; track = (WaveTrack *) iter.Next(); // get the next one - mCurTrackNum++; // keeps progress bar correct msg = topMsg + _("Analyzing second track of stereo pair: ") + trackName; - AnalyseTrack(track, msg); // sets mOffset and offset-adjusted mMin and mMax - float offset2 = mOffset; // ones for second track - float min2 = mMin; - float max2 = mMax; - float extent = wxMax(fabs(min1), fabs(max1)); + float offset2, min2, max2; + AnalyseTrack(track, msg, curTrackNum + 1, offset2, min2, max2); + float extent = wxMax(fabs(min), fabs(max)); extent = wxMax(extent, fabs(min2)); extent = wxMax(extent, fabs(max2)); if( (extent > 0) && mGain ) mMult = ratio / extent; // we need to use this for both linked tracks else mMult = 1.0; - mOffset = offset1; track = (WaveTrack *) iter.Prev(); // go back to the first linked one - mCurTrackNum--; // keeps progress bar correct msg = topMsg + _("Processing first track of stereo pair: ") + trackName; - if (!ProcessOne(track, msg)) + if (!ProcessOne(track, msg, curTrackNum, offset)) { bGoodResult = false; break; } - mOffset = offset2; track = (WaveTrack *) iter.Next(); // go to the second linked one - mCurTrackNum++; // keeps progress bar correct msg = topMsg + _("Processing second track of stereo pair: ") + trackName; - if (!ProcessOne(track, msg)) + if (!ProcessOne(track, msg, curTrackNum, offset2)) { bGoodResult = false; break; @@ -256,7 +248,7 @@ bool EffectNormalize::Process() //Iterate to the next track prevTrack = track; track = (WaveTrack *) iter.Next(); - mCurTrackNum++; + curTrackNum++; } this->ReplaceProcessedTracks(bGoodResult); @@ -333,7 +325,9 @@ bool EffectNormalize::TransferDataFromWindow() // EffectNormalize implementation -void EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg) +void EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg, + int curTrackNum, + float &offset, float &min, float &max) { if(mGain) { // Since we need complete summary data, we need to block until the OD tasks are done for this track @@ -344,28 +338,29 @@ void EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg) wxMilliSleep(100); } - track->GetMinMax(&mMin, &mMax, mCurT0, mCurT1); // set mMin, mMax. No progress bar here as it's fast. + track->GetMinMax(&min, &max, mCurT0, mCurT1); } else { - mMin = -1.0, mMax = 1.0; // sensible defaults? + min = -1.0, max = 1.0; // sensible defaults? } if(mDC) { - AnalyseDC(track, msg); // sets mOffset - mMin += mOffset; - mMax += mOffset; + AnalyseDC(track, msg, curTrackNum, offset); + min += offset; + max += offset; } else { - mOffset = 0.0; + offset = 0.0; } } //AnalyseDC() takes a track, transforms it to bunch of buffer-blocks, //and executes AnalyzeData on it... -// sets mOffset -bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg) +bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg, + int curTrackNum, + float &offset) { bool rc = true; - mOffset = 0.0; // we might just return + offset = 0.0; // we might just return if(!mDC) // don't do analysis if not doing dc removal return(rc); @@ -407,7 +402,7 @@ bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg) s += block; //Update the Progress meter - if (TrackProgress(mCurTrackNum, + if (TrackProgress(curTrackNum, ((s - start).as_double() / len)/2.0, msg)) { rc = false; //lda .. break, not return, so that buffer is deleted break; @@ -417,7 +412,7 @@ bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg) //Clean up the buffer delete[] buffer; - mOffset = -mSum / mCount.as_double(); // calculate actual offset (amount that needs to be added on) + offset = -mSum / mCount.as_double(); // calculate actual offset (amount that needs to be added on) //Return true because the effect processing succeeded ... unless cancelled return rc; @@ -425,8 +420,10 @@ bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg) //ProcessOne() takes a track, transforms it to bunch of buffer-blocks, //and executes ProcessData, on it... -// uses mMult and mOffset to normalize a track. Needs to have them set before being called -bool EffectNormalize::ProcessOne(WaveTrack * track, const wxString &msg) +// uses mMult and offset to normalize a track. +// mMult must be set before this is called +bool EffectNormalize::ProcessOne( + WaveTrack * track, const wxString &msg, int curTrackNum, float offset) { bool rc = true; @@ -458,7 +455,7 @@ bool EffectNormalize::ProcessOne(WaveTrack * track, const wxString &msg) track->Get((samplePtr) buffer, floatSample, s, block); //Process the buffer. - ProcessData(buffer, block); + ProcessData(buffer, block, offset); //Copy the newly-changed samples back onto the track. track->Set((samplePtr) buffer, floatSample, s, block); @@ -467,7 +464,7 @@ bool EffectNormalize::ProcessOne(WaveTrack * track, const wxString &msg) s += block; //Update the Progress meter - if (TrackProgress(mCurTrackNum, + if (TrackProgress(curTrackNum, 0.5+((s - start).as_double() / len)/2.0, msg)) { rc = false; //lda .. break, not return, so that buffer is deleted break; @@ -487,10 +484,10 @@ void EffectNormalize::AnalyzeData(float *buffer, size_t len) mCount += len; } -void EffectNormalize::ProcessData(float *buffer, size_t len) +void EffectNormalize::ProcessData(float *buffer, size_t len, float offset) { for(decltype(len) i = 0; i < len; i++) { - float adjFrame = (buffer[i] + mOffset) * mMult; + float adjFrame = (buffer[i] + offset) * mMult; buffer[i] = adjFrame; } } diff --git a/src/effects/Normalize.h b/src/effects/Normalize.h index e108f4c51..1655542dc 100644 --- a/src/effects/Normalize.h +++ b/src/effects/Normalize.h @@ -56,11 +56,15 @@ public: private: // EffectNormalize implementation - bool ProcessOne(WaveTrack * t, const wxString &msg); - void AnalyseTrack(const WaveTrack * track, const wxString &msg); + bool ProcessOne( + WaveTrack * t, const wxString &msg, int curTrackNum, float offset); + void AnalyseTrack(const WaveTrack * track, const wxString &msg, + int curTrackNum, + float &offset, float &min, float &max); void AnalyzeData(float *buffer, size_t len); - bool AnalyseDC(const WaveTrack * track, const wxString &msg); - void ProcessData(float *buffer, size_t len); + bool AnalyseDC(const WaveTrack * track, const wxString &msg, int curTrackNum, + float &offset); + void ProcessData(float *buffer, size_t len, float offset); void OnUpdateUI(wxCommandEvent & evt); void UpdateUI(); @@ -71,13 +75,9 @@ private: bool mDC; bool mStereoInd; - int mCurTrackNum; double mCurT0; double mCurT1; float mMult; - float mOffset; - float mMin; - float mMax; double mSum; sampleCount mCount; From 08b99c533bbcbea0f5917129e5082e0a867adc17 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 16 Dec 2016 12:37:15 -0500 Subject: [PATCH 4/4] Remove Effect::mWarper, and stack-allocate warpers instead --- src/WaveTrack.cpp | 9 ++------ src/WaveTrack.h | 2 +- src/effects/ChangePitch.cpp | 4 ++-- src/effects/ChangeSpeed.cpp | 13 ++++++----- src/effects/ChangeTempo.cpp | 6 ++--- src/effects/Effect.cpp | 14 ------------ src/effects/Effect.h | 5 ---- src/effects/Generator.cpp | 7 +++--- src/effects/SBSMSEffect.cpp | 11 ++++----- src/effects/SoundTouchEffect.cpp | 39 ++++++++++++++++++-------------- src/effects/SoundTouchEffect.h | 20 +++++++++------- 11 files changed, 58 insertions(+), 72 deletions(-) diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 87018fee4..3409e089a 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -810,7 +810,7 @@ bool WaveTrack::ClearAndPaste(double t0, // Start of time to clear const Track *src, // What to paste bool preserve, // Whether to reinsert splits/cuts bool merge, // Whether to remove 'extra' splits - TimeWarper *effectWarper // How does time change + const TimeWarper *effectWarper // How does time change ) { double dur = wxMin(t1 - t0, src->GetEndTime()); @@ -824,12 +824,7 @@ bool WaveTrack::ClearAndPaste(double t0, // Start of time to clear // If provided time warper was NULL, use a default one that does nothing IdentityTimeWarper localWarper; - TimeWarper *warper = NULL; - if (effectWarper != NULL) { - warper = effectWarper; - } else { - warper = &localWarper; - } + const TimeWarper *warper = (effectWarper ? effectWarper : &localWarper); // Align to a sample t0 = LongSamplesToTime(TimeToLongSamples(t0)); diff --git a/src/WaveTrack.h b/src/WaveTrack.h index 372169b6a..c1fd2941c 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -175,7 +175,7 @@ class AUDACITY_DLL_API WaveTrack final : public Track { const Track *src, bool preserve = true, bool merge = true, - TimeWarper *effectWarper = NULL) /* not override */; + const TimeWarper *effectWarper = NULL) /* not override */; bool Silence(double t0, double t1) override; bool InsertSilence(double t, double len) override; diff --git a/src/effects/ChangePitch.cpp b/src/effects/ChangePitch.cpp index fa39b2497..a2d98bf78 100644 --- a/src/effects/ChangePitch.cpp +++ b/src/effects/ChangePitch.cpp @@ -194,7 +194,7 @@ bool EffectChangePitch::Process() #endif { mSoundTouch = std::make_unique(); - SetTimeWarper(std::make_unique()); + IdentityTimeWarper warper; mSoundTouch->setPitchSemiTones((float)(m_dSemitonesChange)); #ifdef USE_MIDI // Pitch shifting note tracks is currently only supported by SoundTouchEffect @@ -209,7 +209,7 @@ bool EffectChangePitch::Process() // eliminate the next line: mSemitones = m_dSemitonesChange; #endif - return EffectSoundTouch::Process(); + return EffectSoundTouch::ProcessWithTimeWarper(warper); } } diff --git a/src/effects/ChangeSpeed.cpp b/src/effects/ChangeSpeed.cpp index 13ae8f839..4188220c3 100644 --- a/src/effects/ChangeSpeed.cpp +++ b/src/effects/ChangeSpeed.cpp @@ -455,10 +455,10 @@ bool EffectChangeSpeed::TransferDataFromWindow() // the region are shifted along according to how the region size changed. bool EffectChangeSpeed::ProcessLabelTrack(LabelTrack *lt) { - SetTimeWarper(std::make_unique(mT0, mT1, - std::make_unique(mT0, mT0, - mT1, mT0 + (mT1-mT0)*mFactor))); - lt->WarpLabels(*GetTimeWarper()); + RegionTimeWarper warper { mT0, mT1, + std::make_unique(mT0, mT0, + mT1, mT0 + (mT1-mT0)*mFactor) }; + lt->WarpLabels(warper); return true; } @@ -542,8 +542,9 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track, double newLength = outputTrack->GetEndTime(); if (bResult) { - SetTimeWarper(std::make_unique(mCurT0, mCurT0, mCurT1, mCurT0 + newLength)); - bResult = track->ClearAndPaste(mCurT0, mCurT1, outputTrack.get(), true, false, GetTimeWarper()); + LinearTimeWarper warper { mCurT0, mCurT0, mCurT1, mCurT0 + newLength }; + bResult = track->ClearAndPaste( + mCurT0, mCurT1, outputTrack.get(), true, false, &warper); } if (newLength > mMaxNewLength) diff --git a/src/effects/ChangeTempo.cpp b/src/effects/ChangeTempo.cpp index 015d16aa1..7e5292cb6 100644 --- a/src/effects/ChangeTempo.cpp +++ b/src/effects/ChangeTempo.cpp @@ -183,9 +183,9 @@ bool EffectChangeTempo::Process() mSoundTouch = std::make_unique(); mSoundTouch->setTempoChange(m_PercentChange); double mT1Dashed = mT0 + (mT1 - mT0)/(m_PercentChange/100.0 + 1.0); - SetTimeWarper(std::make_unique(mT0, mT1, - std::make_unique(mT0, mT0, mT1, mT1Dashed ))); - success = EffectSoundTouch::Process(); + RegionTimeWarper warper{ mT0, mT1, + std::make_unique(mT0, mT0, mT1, mT1Dashed ) }; + success = EffectSoundTouch::ProcessWithTimeWarper(warper); } if(success) diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index d7c7a5220..65431820a 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -91,8 +91,6 @@ Effect::Effect() mClient = NULL; - mWarper = NULL; - mTracks = NULL; mOutputTracksType = Track::None; mT0 = 0.0; @@ -2036,18 +2034,6 @@ void Effect::GetSamples( } } -void Effect::SetTimeWarper(std::unique_ptr &&warper) -{ - wxASSERT(warper); - mWarper = std::move(warper); -} - -TimeWarper *Effect::GetTimeWarper() -{ - wxASSERT(mWarper); - return mWarper.get(); -} - // // private methods // diff --git a/src/effects/Effect.h b/src/effects/Effect.h index e0e1aec64..a3d268568 100644 --- a/src/effects/Effect.h +++ b/src/effects/Effect.h @@ -46,7 +46,6 @@ class ShuttleGui; class AudacityProject; class LabelTrack; class SelectedRegion; -class TimeWarper; class EffectUIHost; class Track; class TrackList; @@ -330,9 +329,6 @@ protected: void GetSamples( const WaveTrack *track, sampleCount *start, sampleCount *len); - void SetTimeWarper(std::unique_ptr &&warper); - TimeWarper *GetTimeWarper(); - // Previewing linear effect can be optimised by pre-mixing. However this // should not be used for non-linear effects such as dynamic processors // To allow pre-mixing before Preview, set linearEffectFlag to true. @@ -446,7 +442,6 @@ protected: double mF0; double mF1; #endif - std::unique_ptr mWarper; wxArrayString mPresetNames; wxArrayString mPresetValues; int mPass; diff --git a/src/effects/Generator.cpp b/src/effects/Generator.cpp index b3b568db1..b718c68b9 100644 --- a/src/effects/Generator.cpp +++ b/src/effects/Generator.cpp @@ -78,9 +78,10 @@ bool Generator::Process() else { // Transfer the data from the temporary track to the actual one tmp->Flush(); - SetTimeWarper(std::make_unique(mT0+GetDuration(), GetDuration()-(mT1-mT0))); - bGoodResult = track->ClearAndPaste(p->GetSel0(), p->GetSel1(), &*tmp, true, - false, GetTimeWarper()); + StepTimeWarper warper{ + mT0+GetDuration(), GetDuration()-(mT1-mT0) }; + bGoodResult = track->ClearAndPaste( + p->GetSel0(), p->GetSel1(), &*tmp, true, false, &warper); } if (!bGoodResult) { diff --git a/src/effects/SBSMSEffect.cpp b/src/effects/SBSMSEffect.cpp index b908e1e60..a12a55beb 100644 --- a/src/effects/SBSMSEffect.cpp +++ b/src/effects/SBSMSEffect.cpp @@ -187,9 +187,9 @@ std::unique_ptr createTimeWarper(double t0, double t1, double durati // it are shifted along appropriately. bool EffectSBSMS::ProcessLabelTrack(LabelTrack *lt) { - auto warper = createTimeWarper(mT0,mT1,(mT1-mT0)*mTotalStretch,rateStart,rateEnd,rateSlideType); - SetTimeWarper(std::make_unique(mT0, mT1, std::move(warper))); - lt->WarpLabels(*GetTimeWarper()); + auto warper1 = createTimeWarper(mT0,mT1,(mT1-mT0)*mTotalStretch,rateStart,rateEnd,rateSlideType); + RegionTimeWarper warper{ mT0, mT1, std::move(warper1) }; + lt->WarpLabels(warper); return true; } @@ -372,7 +372,6 @@ bool EffectSBSMS::Process() maxDuration = duration; auto warper = createTimeWarper(mCurT0,mCurT1,maxDuration,rateStart,rateEnd,rateSlideType); - SetTimeWarper(std::move(warper)); rb.outputLeftTrack = mFactory->NewWaveTrack(leftTrack->GetSampleFormat(), leftTrack->GetRate()); @@ -419,7 +418,7 @@ bool EffectSBSMS::Process() bool bResult = leftTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputLeftTrack.get(), - true, false, GetTimeWarper()); + true, false, warper.get()); wxASSERT(bResult); // TO DO: Actually handle this. wxUnusedVar(bResult); @@ -427,7 +426,7 @@ bool EffectSBSMS::Process() { bResult = rightTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputRightTrack.get(), - true, false, GetTimeWarper()); + true, false, warper.get()); wxASSERT(bResult); // TO DO: Actually handle this. } } diff --git a/src/effects/SoundTouchEffect.cpp b/src/effects/SoundTouchEffect.cpp index 886314d10..c85887899 100644 --- a/src/effects/SoundTouchEffect.cpp +++ b/src/effects/SoundTouchEffect.cpp @@ -25,24 +25,25 @@ effect that uses SoundTouch to do its processing (ChangeTempo #include "TimeWarper.h" #include "../NoteTrack.h" -bool EffectSoundTouch::ProcessLabelTrack(LabelTrack *lt) +bool EffectSoundTouch::ProcessLabelTrack( + LabelTrack *lt, const TimeWarper &warper) { // SetTimeWarper(std::make_unique(mCurT0, mCurT1, // std::make_unique(mCurT0, mCurT0, // mCurT1, mCurT0 + (mCurT1-mCurT0)*mFactor))); - lt->WarpLabels(*GetTimeWarper()); + lt->WarpLabels(warper); return true; } #ifdef USE_MIDI -bool EffectSoundTouch::ProcessNoteTrack(NoteTrack *nt) +bool EffectSoundTouch::ProcessNoteTrack(NoteTrack *nt, const TimeWarper &warper) { - nt->WarpAndTransposeNotes(mCurT0, mCurT1, *GetTimeWarper(), mSemitones); + nt->WarpAndTransposeNotes(mCurT0, mCurT1, warper, mSemitones); return true; } #endif -bool EffectSoundTouch::Process() +bool EffectSoundTouch::ProcessWithTimeWarper(const TimeWarper &warper) { // Assumes that mSoundTouch has already been initialized // by the subclass for subclass-specific parameters. The @@ -51,7 +52,7 @@ bool EffectSoundTouch::Process() // Check if this effect will alter the selection length; if so, we need // to operate on sync-lock selected tracks. bool mustSync = true; - if (mT1 == GetTimeWarper()->Warp(mT1)) { + if (mT1 == warper.Warp(mT1)) { mustSync = false; } @@ -70,7 +71,7 @@ bool EffectSoundTouch::Process() if (t->GetKind() == Track::Label && (t->GetSelected() || (mustSync && t->IsSyncLockSelected())) ) { - if (!ProcessLabelTrack(static_cast(t))) + if (!ProcessLabelTrack(static_cast(t), warper)) { bGoodResult = false; break; @@ -80,7 +81,7 @@ bool EffectSoundTouch::Process() else if (t->GetKind() == Track::Note && (t->GetSelected() || (mustSync && t->IsSyncLockSelected()))) { - if (!ProcessNoteTrack(static_cast(t))) + if (!ProcessNoteTrack(static_cast(t), warper)) { bGoodResult = false; break; @@ -123,7 +124,7 @@ bool EffectSoundTouch::Process() mSoundTouch->setChannels(2); //ProcessStereo() (implemented below) processes a stereo track - if (!ProcessStereo(leftTrack, rightTrack, start, end)) + if (!ProcessStereo(leftTrack, rightTrack, start, end, warper)) { bGoodResult = false; break; @@ -138,7 +139,7 @@ bool EffectSoundTouch::Process() mSoundTouch->setChannels(1); //ProcessOne() (implemented below) processes a single track - if (!ProcessOne(leftTrack, start, end)) + if (!ProcessOne(leftTrack, start, end, warper)) { bGoodResult = false; break; @@ -148,7 +149,7 @@ bool EffectSoundTouch::Process() mCurTrackNum++; } else if (mustSync && t->IsSyncLockSelected()) { - t->SyncLockAdjust(mT1, GetTimeWarper()->Warp(mT1)); + t->SyncLockAdjust(mT1, warper.Warp(mT1)); } //Iterate to the next track @@ -169,7 +170,8 @@ bool EffectSoundTouch::Process() //ProcessOne() takes a track, transforms it to bunch of buffer-blocks, //and executes ProcessSoundTouch on these blocks bool EffectSoundTouch::ProcessOne(WaveTrack *track, - sampleCount start, sampleCount end) + sampleCount start, sampleCount end, + const TimeWarper &warper) { mSoundTouch->setSampleRate((unsigned int)(track->GetRate()+0.5)); @@ -234,7 +236,7 @@ bool EffectSoundTouch::ProcessOne(WaveTrack *track, // Take the output track and insert it in place of the original // sample data - track->ClearAndPaste(mCurT0, mCurT1, outputTrack.get(), true, false, GetTimeWarper()); + track->ClearAndPaste(mCurT0, mCurT1, outputTrack.get(), true, false, &warper); double newLength = outputTrack->GetEndTime(); m_maxNewLength = wxMax(m_maxNewLength, newLength); @@ -243,8 +245,9 @@ bool EffectSoundTouch::ProcessOne(WaveTrack *track, return true; } -bool EffectSoundTouch::ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack, - sampleCount start, sampleCount end) +bool EffectSoundTouch::ProcessStereo( + WaveTrack* leftTrack, WaveTrack* rightTrack, + sampleCount start, sampleCount end, const TimeWarper &warper) { mSoundTouch->setSampleRate((unsigned int)(leftTrack->GetRate()+0.5)); @@ -335,8 +338,10 @@ bool EffectSoundTouch::ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack // Take the output tracks and insert in place of the original // sample data. - leftTrack->ClearAndPaste(mCurT0, mCurT1, outputLeftTrack.get(), true, false, GetTimeWarper()); - rightTrack->ClearAndPaste(mCurT0, mCurT1, outputRightTrack.get(), true, false, GetTimeWarper()); + leftTrack->ClearAndPaste( + mCurT0, mCurT1, outputLeftTrack.get(), true, false, &warper); + rightTrack->ClearAndPaste( + mCurT0, mCurT1, outputRightTrack.get(), true, false, &warper); // Track the longest result length double newLength = outputLeftTrack->GetEndTime(); diff --git a/src/effects/SoundTouchEffect.h b/src/effects/SoundTouchEffect.h index a5b9c5558..ed38f94ad 100644 --- a/src/effects/SoundTouchEffect.h +++ b/src/effects/SoundTouchEffect.h @@ -32,16 +32,13 @@ using namespace soundtouch; +class TimeWarper; class WaveTrack; class EffectSoundTouch /* not final */ : public Effect { public: - // Effect implementation - - bool Process() override; - // EffectSoundTouch implementation #ifdef USE_MIDI @@ -50,18 +47,25 @@ public: #endif protected: + // Effect implementation + + bool ProcessWithTimeWarper(const TimeWarper &warper); + std::unique_ptr mSoundTouch; double mCurT0; double mCurT1; private: - bool ProcessLabelTrack(LabelTrack *track); + bool ProcessLabelTrack(LabelTrack *track, const TimeWarper &warper); #ifdef USE_MIDI - bool ProcessNoteTrack(NoteTrack *track); + bool ProcessNoteTrack(NoteTrack *track, const TimeWarper &warper); #endif - bool ProcessOne(WaveTrack * t, sampleCount start, sampleCount end); + bool ProcessOne( + WaveTrack * t, sampleCount start, sampleCount end, + const TimeWarper &warper); bool ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack, - sampleCount start, sampleCount end); + sampleCount start, sampleCount end, + const TimeWarper &warper); bool ProcessStereoResults(const unsigned int outputCount, WaveTrack* outputLeftTrack, WaveTrack* outputRightTrack);