diff --git a/src/engine/controls/ratecontrol.cpp b/src/engine/controls/ratecontrol.cpp index 29389d678ff9..cff8052a8199 100644 --- a/src/engine/controls/ratecontrol.cpp +++ b/src/engine/controls/ratecontrol.cpp @@ -628,3 +628,10 @@ void RateControl::notifyWrapAround(mixxx::audio::FramePos triggerPos, void RateControl::notifySeek(mixxx::audio::FramePos position) { m_pScratchController->notifySeek(position); } + +void RateControl::resetPositionScratchController() { + // Resets the scratch state to avoid engine freeze due to insanley high rate + // reported on track load while scratching. + // https://github.com/mixxxdj/mixxx/issues/15082 + m_pScratchController->reset(); +} diff --git a/src/engine/controls/ratecontrol.h b/src/engine/controls/ratecontrol.h index 25fc39573088..ba8e5d605586 100644 --- a/src/engine/controls/ratecontrol.h +++ b/src/engine/controls/ratecontrol.h @@ -77,6 +77,7 @@ class RateControl : public EngineControl { void notifyWrapAround(mixxx::audio::FramePos triggerPos, mixxx::audio::FramePos targetPos); void notifySeek(mixxx::audio::FramePos position) override; + void resetPositionScratchController(); public slots: void slotRateRangeChanged(double); diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp index fbf4e67c0712..34b9d36c5484 100644 --- a/src/engine/enginebuffer.cpp +++ b/src/engine/enginebuffer.cpp @@ -627,13 +627,19 @@ void EngineBuffer::ejectTrack() { if (pOldTrack) { notifyTrackLoaded(TrackPointer(), pOldTrack); + } else { + // When not invoking notifyTrackLoaded() call this separately + m_pRateControl->resetPositionScratchController(); } + m_iTrackLoading = 0; m_pChannelToCloneFrom = nullptr; } void EngineBuffer::notifyTrackLoaded( TrackPointer pNewTrack, TrackPointer pOldTrack) { + m_pRateControl->resetPositionScratchController(); + if (pOldTrack) { disconnect( pOldTrack.get(), diff --git a/src/engine/positionscratchcontroller.cpp b/src/engine/positionscratchcontroller.cpp index 4533cdb5d3b7..c52b8338dccc 100644 --- a/src/engine/positionscratchcontroller.cpp +++ b/src/engine/positionscratchcontroller.cpp @@ -329,3 +329,13 @@ void PositionScratchController::notifySeek(mixxx::audio::FramePos position) { // distance traveled in m_samplePosDeltaSum m_seekSamplePos = newPos; } + +void PositionScratchController::reset() { + // Resets the scratch state to avoid engine freeze due to insanley high rate + // reported on track load while scratching. + // https://github.com/mixxxdj/mixxx/issues/15082 + m_pScratchEnable->set(0.0); + m_isScratching = false; + m_inertiaEnabled = false; + m_rate = 0; +} diff --git a/src/engine/positionscratchcontroller.h b/src/engine/positionscratchcontroller.h index 21135d3f461b..47592b483cb8 100644 --- a/src/engine/positionscratchcontroller.h +++ b/src/engine/positionscratchcontroller.h @@ -33,6 +33,7 @@ class PositionScratchController : public QObject { return m_rate; } void notifySeek(mixxx::audio::FramePos position); + void reset(); private slots: void slotUpdateFilterParameters(double sampleRate);