diff --git a/src/engine/cachingreader/cachingreader.h b/src/engine/cachingreader/cachingreader.h index c5f5a6ee32c5..ec185e2eb1ba 100644 --- a/src/engine/cachingreader/cachingreader.h +++ b/src/engine/cachingreader/cachingreader.h @@ -18,22 +18,32 @@ // 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 + FirstSound, + IntroStart, + IntroEnd, + OutroStart + }; + // 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..8b3203ac4aa6 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -70,6 +70,25 @@ inline int hotcueNumberToHotcueIndex(int hotcueNumber) { } } +void appendCueHint(HintVector* pHintList, const mixxx::audio::FramePos& frame, Hint::Type type) { + VERIFY_OR_DEBUG_ASSERT(pHintList) { + return; + } + + if (frame.isValid()) { + const Hint cueHint = { + /*.frame =*/static_cast(frame.toLowerFrameBoundary().value()), + /*.frameCount =*/Hint::kFrameCountForward, + /*.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,29 +1179,25 @@ 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.priority = 10; - 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.priority = 10; - pHintList->append(cueHint); - } + 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 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); }