From 8bdcede6fa57da90a28518f52d2b1db432294b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 26 May 2022 21:59:08 +0200 Subject: [PATCH 1/5] Replace CachingReader Hint priorities by a type enum This allows to add a more sophisticated priority handling --- src/engine/cachingreader/cachingreader.h | 18 ++++++++++++------ src/engine/controls/cuecontrol.cpp | 4 ++-- src/engine/controls/loopingcontrol.cpp | 6 +++--- src/engine/enginebuffer.cpp | 2 +- src/engine/readaheadmanager.cpp | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/engine/cachingreader/cachingreader.h b/src/engine/cachingreader/cachingreader.h index c5f5a6ee32c5..c8d6d3e19489 100644 --- a/src/engine/cachingreader/cachingreader.h +++ b/src/engine/cachingreader/cachingreader.h @@ -18,22 +18,28 @@ // SoundSource will be used 'soon' and so it should be brought into memory by // the reader work thread. typedef struct Hint { + enum class Type { + SlipPosition, // prio 1 (so far unused Mixxx 2.3 priority for reference) + CurrentPosition, // prio 1 + LoopStartEnabled, // prio 2 + MainCue, // prio 10 + HotCue, // prio 10 + LoopEndEnabled, // prio 10 + LoopStart // prio 10 + }; + // The frame to ensure is present in memory. SINT frame; // If a range of frames should be present, use frameCount to indicate that the // range (frame, frame + frameCount) should be present in memory. SINT frameCount; // Currently unused -- but in the future could be used to prioritize certain - // hints over others. A priority of 1 is the highest priority and should be - // used for samples that will be read imminently. Hints for samples that - // have the potential to be read (i.e. a cue point) should be issued with - // priority >10. - int priority; + // hints over others. + Type type; // for the default frame count in forward direction static constexpr SINT kFrameCountForward = 0; static constexpr SINT kFrameCountBackward = -1; - } Hint; // Note that we use a QVarLengthArray here instead of a QVector. Since this list diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 7601e8445448..69f59c06f5cc 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1167,7 +1167,7 @@ void CueControl::hintReader(HintVector* pHintList) { if (mainCuePosition.isValid()) { cueHint.frame = static_cast(mainCuePosition.toLowerFrameBoundary().value()); cueHint.frameCount = Hint::kFrameCountForward; - cueHint.priority = 10; + cueHint.type = Hint::Type::MainCue; pHintList->append(cueHint); } @@ -1179,7 +1179,7 @@ void CueControl::hintReader(HintVector* pHintList) { if (position.isValid()) { cueHint.frame = static_cast(position.toLowerFrameBoundary().value()); cueHint.frameCount = Hint::kFrameCountForward; - cueHint.priority = 10; + cueHint.type = Hint::Type::HotCue; pHintList->append(cueHint); } } diff --git a/src/engine/controls/loopingcontrol.cpp b/src/engine/controls/loopingcontrol.cpp index f211704bf122..7e2507ed8ce7 100644 --- a/src/engine/controls/loopingcontrol.cpp +++ b/src/engine/controls/loopingcontrol.cpp @@ -486,14 +486,14 @@ void LoopingControl::hintReader(HintVector* pHintList) { // direction we're going in, but that this is much simpler, and hints // aren't that bad to make anyway. if (loopInfo.startPosition.isValid()) { - loop_hint.priority = 2; + loop_hint.type = Hint::Type::LoopStartEnabled; loop_hint.frame = static_cast( loopInfo.startPosition.toLowerFrameBoundary().value()); loop_hint.frameCount = Hint::kFrameCountForward; pHintList->append(loop_hint); } if (loopInfo.endPosition.isValid()) { - loop_hint.priority = 10; + loop_hint.type = Hint::Type::LoopEndEnabled; loop_hint.frame = static_cast( loopInfo.endPosition.toUpperFrameBoundary().value()); loop_hint.frameCount = Hint::kFrameCountBackward; @@ -501,7 +501,7 @@ void LoopingControl::hintReader(HintVector* pHintList) { } } else { if (loopInfo.startPosition.isValid()) { - loop_hint.priority = 10; + loop_hint.type = Hint::Type::LoopStart; loop_hint.frame = static_cast( loopInfo.startPosition.toLowerFrameBoundary().value()); loop_hint.frameCount = Hint::kFrameCountForward; diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp index 34bbf41ee61e..7fc734947238 100644 --- a/src/engine/enginebuffer.cpp +++ b/src/engine/enginebuffer.cpp @@ -1395,7 +1395,7 @@ void EngineBuffer::hintReader(const double dRate) { if (m_bSlipEnabledProcessing) { Hint hint; hint.frame = static_cast(m_slipPosition.toLowerFrameBoundary().value()); - hint.priority = 1; + hint.type = Hint::Type::SlipPosition; if (m_dSlipRate >= 0) { hint.frameCount = Hint::kFrameCountForward; } else { diff --git a/src/engine/readaheadmanager.cpp b/src/engine/readaheadmanager.cpp index 451c00adb1de..b0be7cd2d368 100644 --- a/src/engine/readaheadmanager.cpp +++ b/src/engine/readaheadmanager.cpp @@ -216,7 +216,7 @@ void ReadAheadManager::hintReader(double dRate, HintVector* pHintList) { } // top priority, we need to read this data immediately - current_position.priority = 1; + current_position.type = Hint::Type::CurrentPosition; pHintList->append(current_position); } From 9cfe1ebcc433bf617d33258929886f47d048ca08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 26 May 2022 23:04:12 +0200 Subject: [PATCH 2/5] Introduce helper appendCueHint() to de-duplicate the code --- src/engine/controls/cuecontrol.cpp | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 69f59c06f5cc..e9398306506f 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -70,6 +70,21 @@ inline int hotcueNumberToHotcueIndex(int hotcueNumber) { } } +void appendCueHint(HintVector* pHintList, const mixxx::audio::FramePos& frame, Hint::Type type) { + Hint cueHint; + if (frame.isValid()) { + cueHint.frame = static_cast(frame.toLowerFrameBoundary().value()); + cueHint.frameCount = Hint::kFrameCountForward; + cueHint.type = type; + pHintList->append(cueHint); + } +} + +void appendCueHint(HintVector* pHintList, const double playPos, Hint::Type type) { + const auto frame = mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(playPos); + appendCueHint(pHintList, frame, type); +} + } // namespace CueControl::CueControl(const QString& group, @@ -1160,28 +1175,13 @@ void CueControl::hotcueEndPositionChanged( } void CueControl::hintReader(HintVector* pHintList) { - Hint cueHint; - const auto mainCuePosition = - mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid( - m_pCuePoint->get()); - if (mainCuePosition.isValid()) { - cueHint.frame = static_cast(mainCuePosition.toLowerFrameBoundary().value()); - cueHint.frameCount = Hint::kFrameCountForward; - cueHint.type = Hint::Type::MainCue; - pHintList->append(cueHint); - } + appendCueHint(pHintList, m_pCuePoint->get(), Hint::Type::MainCue); // this is called from the engine thread // it is no locking required, because m_hotcueControl is filled during the // constructor and getPosition()->get() is a ControlObject for (const auto& pControl : qAsConst(m_hotcueControls)) { - const mixxx::audio::FramePos position = pControl->getPosition(); - if (position.isValid()) { - cueHint.frame = static_cast(position.toLowerFrameBoundary().value()); - cueHint.frameCount = Hint::kFrameCountForward; - cueHint.type = Hint::Type::HotCue; - pHintList->append(cueHint); - } + appendCueHint(pHintList, pControl->getPosition(), Hint::Type::HotCue); } } From d2a99b8f52876248f44d607d2b7b0ce005ec69b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 26 May 2022 23:30:04 +0200 Subject: [PATCH 3/5] Add FirstSound, Intro and Outro to he hints for the CachingReader --- src/engine/cachingreader/cachingreader.h | 6 +++++- src/engine/controls/cuecontrol.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/engine/cachingreader/cachingreader.h b/src/engine/cachingreader/cachingreader.h index c8d6d3e19489..ec185e2eb1ba 100644 --- a/src/engine/cachingreader/cachingreader.h +++ b/src/engine/cachingreader/cachingreader.h @@ -25,7 +25,11 @@ typedef struct Hint { MainCue, // prio 10 HotCue, // prio 10 LoopEndEnabled, // prio 10 - LoopStart // prio 10 + LoopStart, // prio 10 + FirstSound, + IntroStart, + IntroEnd, + OutroStart }; // The frame to ensure is present in memory. diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index e9398306506f..7d8e22745b6e 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -1183,6 +1183,17 @@ void CueControl::hintReader(HintVector* pHintList) { for (const auto& pControl : qAsConst(m_hotcueControls)) { appendCueHint(pHintList, pControl->getPosition(), Hint::Type::HotCue); } + + CuePointer pAudibleSound = + m_pLoadedTrack->findCueByType(mixxx::CueType::AudibleSound); + if (pAudibleSound) { + const mixxx::audio::FramePos frame = pAudibleSound->getPosition(); + appendCueHint(pHintList, frame, Hint::Type::FirstSound); + } + + appendCueHint(pHintList, m_pIntroStartPosition->get(), Hint::Type::IntroStart); + appendCueHint(pHintList, m_pIntroEndPosition->get(), Hint::Type::IntroEnd); + appendCueHint(pHintList, m_pOutroStartPosition->get(), Hint::Type::OutroStart); } // Moves the cue point to current position or to closest beat in case From 019e5e06d0ba3ad3ecc7386a62abc21bb0e03d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 27 May 2022 01:13:02 +0200 Subject: [PATCH 4/5] Check pHintList for null --- src/engine/controls/cuecontrol.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 7d8e22745b6e..18a44abf9c5d 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -71,6 +71,9 @@ inline int hotcueNumberToHotcueIndex(int hotcueNumber) { } void appendCueHint(HintVector* pHintList, const mixxx::audio::FramePos& frame, Hint::Type type) { + VERIFY_OR_DEBUG_ASSERT(pHintList) { + return; + } Hint cueHint; if (frame.isValid()) { cueHint.frame = static_cast(frame.toLowerFrameBoundary().value()); From f4cecb200f040568fe6f4b07611537f6b2e491ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 27 May 2022 01:24:29 +0200 Subject: [PATCH 5/5] Use an initalizer list to populate the cue hint --- src/engine/controls/cuecontrol.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 18a44abf9c5d..8b3203ac4aa6 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -74,11 +74,12 @@ void appendCueHint(HintVector* pHintList, const mixxx::audio::FramePos& frame, H VERIFY_OR_DEBUG_ASSERT(pHintList) { return; } - Hint cueHint; + if (frame.isValid()) { - cueHint.frame = static_cast(frame.toLowerFrameBoundary().value()); - cueHint.frameCount = Hint::kFrameCountForward; - cueHint.type = type; + const Hint cueHint = { + /*.frame =*/static_cast(frame.toLowerFrameBoundary().value()), + /*.frameCount =*/Hint::kFrameCountForward, + /*.type =*/type}; pHintList->append(cueHint); } }