diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a539cef4eb4..133e3c2ce0e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: RRYAN_AT_MIXXX_DOT_ORG_GPG_PRIVATE_KEY: ${{ secrets.RRYAN_AT_MIXXX_DOT_ORG_GPG_PRIVATE_KEY }} sync: - if: ${{ github.ref != 'refs/heads/main' }} && ${{ github.repository == 'mixxxdj/mixxx' }} + if: ${{ github.ref != 'refs/heads/main' && github.repository == 'mixxxdj/mixxx' }} uses: ./.github/workflows/sync_branches.yml secrets: MIXXX_BRANCH_SYNC_PAT: ${{ secrets.MIXXX_BRANCH_SYNC_PAT }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d6204845c62..205a5c06a1b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5045,7 +5045,7 @@ if(NOT CPACK_DEBIAN_PACKAGE_RELEASE) set(CPACK_DEBIAN_PACKAGE_RELEASE 1) endif() -set(CPACK_DEBIAN_DISTRIBUTION_RELEASES noble oracular plucky questing) +set(CPACK_DEBIAN_DISTRIBUTION_RELEASES noble plucky questing) set(CPACK_DEBIAN_SOURCE_DIR ${CMAKE_SOURCE_DIR}) set( CPACK_DEBIAN_UPLOAD_PPA_SCRIPT diff --git a/res/translations/mixxx_fr.ts b/res/translations/mixxx_fr.ts index d6e7afd382ad..cd4cbd3d31b3 100644 --- a/res/translations/mixxx_fr.ts +++ b/res/translations/mixxx_fr.ts @@ -3763,7 +3763,7 @@ traceĀ : ci-dessus + messages de profilage Auto DJ Track Source - Auto DJ Source de piste + Auto DJ source de piste diff --git a/src/engine/controls/ratecontrol.cpp b/src/engine/controls/ratecontrol.cpp index af0979bc03b1..7a889d62bb00 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 594a0824d70d..ed4c61084558 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 9461197e4d5c..50f31f0e614c 100644 --- a/src/engine/enginebuffer.cpp +++ b/src/engine/enginebuffer.cpp @@ -648,13 +648,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 9ca0b54dc0bc..3f1067714381 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 9cd57632b7bb..688851cd8143 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); diff --git a/src/library/dlgtrackinfomulti.cpp b/src/library/dlgtrackinfomulti.cpp index 7977dd55bc71..b1918b63364a 100644 --- a/src/library/dlgtrackinfomulti.cpp +++ b/src/library/dlgtrackinfomulti.cpp @@ -314,7 +314,10 @@ void DlgTrackInfoMulti::loadTracks(const QList& pTracks) { m_pLoadedTracks.clear(); } for (const auto& pTrack : pTracks) { - m_pLoadedTracks.insert(pTrack.get()->getId(), pTrack); + if (pTrack.get()) { + m_pLoadedTracks.insert(pTrack.get()->getId(), pTrack); + } + // Skip unavailable tracks } updateFromTracks(); diff --git a/src/skin/legacy/tooltips.cpp b/src/skin/legacy/tooltips.cpp index 60fac0eb51f8..ef1904316ba4 100644 --- a/src/skin/legacy/tooltips.cpp +++ b/src/skin/legacy/tooltips.cpp @@ -705,13 +705,13 @@ void Tooltips::addStandardTooltips() { << tr("Repeat") << tr("When active the track will repeat if you go past the end or reverse before the start."); - add("eject") << tr("Eject") << tr("Ejects track from the player.") - << tr("Un-ejects when no track is loaded, i.e. reloads the " - "track that was ejected last (of any deck).") - << QString("%1: %2").arg(doubleClick, - "Reloads the last replaced track. " - "If no track is loaded reloads the second-last " - "ejected track."); + add("eject") + << tr("Eject") << tr("Ejects track from the player.") + << tr("Un-ejects when no track is loaded, i.e. reloads the " + "track that was ejected last (of any deck).") + << QString("%1: %2").arg(doubleClick, + tr("Reloads the last replaced track. If no track is " + "loaded reloads the second-last ejected track.")); add("hotcue") << tr("Hotcue") << QString("%1: %2").arg(leftClick, diff --git a/src/widget/wtrackmenu.cpp b/src/widget/wtrackmenu.cpp index 814df40c8533..e8e01c410baf 100644 --- a/src/widget/wtrackmenu.cpp +++ b/src/widget/wtrackmenu.cpp @@ -1283,7 +1283,7 @@ TrackIdList WTrackMenu::getTrackIds() const { TrackIdList trackIds; if (m_pTrackModel) { trackIds.reserve(m_trackIndexList.size()); - for (const auto& index : m_trackIndexList) { + for (const auto& index : std::as_const(m_trackIndexList)) { const auto trackId = m_pTrackModel->getTrackId(index); if (!trackId.isValid()) { // Skip unavailable tracks @@ -1305,7 +1305,7 @@ QList WTrackMenu::getTrackRefs() const { QList trackRefs; if (m_pTrackModel) { trackRefs.reserve(m_trackIndexList.size()); - for (const auto& index : m_trackIndexList) { + for (const auto& index : std::as_const(m_trackIndexList)) { auto trackRef = TrackRef::fromFilePath( m_pTrackModel->getTrackLocation(index), m_pTrackModel->getTrackId(index)); @@ -1326,7 +1326,7 @@ QList WTrackMenu::getTrackRefs() const { TrackPointer WTrackMenu::getFirstTrackPointer() const { if (m_pTrackModel) { - for (const auto& index : m_trackIndexList) { + for (const auto& index : std::as_const(m_trackIndexList)) { const auto pTrack = m_pTrackModel->getTrack(index); if (pTrack) { return pTrack; @@ -1341,7 +1341,7 @@ TrackPointer WTrackMenu::getFirstTrackPointer() const { TrackPointerList WTrackMenu::getTrackPointers() const { TrackPointerList tracks; if (m_pTrackModel) { - for (const auto& index : m_trackIndexList) { + for (const auto& index : std::as_const(m_trackIndexList)) { const auto pTrack = m_pTrackModel->getTrack(index); if (pTrack) { tracks.append(pTrack); @@ -2723,8 +2723,12 @@ void WTrackMenu::slotShowDlgTrackInfo() { }); QList tracks; tracks.reserve(getTrackCount()); - for (int i = 0; i < m_trackIndexList.size(); i++) { - tracks.append(m_pTrackModel->getTrack(m_trackIndexList.at(i))); + for (const auto& index : std::as_const(m_trackIndexList)) { + const auto pTrack = m_pTrackModel->getTrack(index); + if (pTrack) { + tracks.append(pTrack); + } + // Skip unavailable tracks } m_pDlgTrackInfoMulti->loadTracks(tracks); m_pDlgTrackInfoMulti->show();