diff options
Diffstat (limited to 'src/engine/controls/cuecontrol.cpp')
-rw-r--r-- | src/engine/controls/cuecontrol.cpp | 460 |
1 files changed, 247 insertions, 213 deletions
diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index 1e1fd43a5f..3a160eded7 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -52,12 +52,10 @@ CueControl::CueControl(QString group, m_pClosestBeat = ControlObject::getControl(ConfigKey(group, "beat_closest")); m_pCuePoint = new ControlObject(ConfigKey(group, "cue_point")); - m_pCuePoint->set(-1.0); + m_pCuePoint->set(Cue::kNoPosition); m_pCueMode = new ControlObject(ConfigKey(group, "cue_mode")); - m_pSeekOnLoadMode = new ControlObject(ConfigKey(group, "seekonload_mode")); - m_pCueSet = new ControlPushButton(ConfigKey(group, "cue_set")); m_pCueSet->setButtonMode(ControlPushButton::TRIGGER); connect(m_pCueSet, &ControlObject::valueChanged, @@ -117,7 +115,7 @@ CueControl::CueControl(QString group, m_pPlayIndicator = new ControlIndicator(ConfigKey(group, "play_indicator")); m_pIntroStartPosition = new ControlObject(ConfigKey(group, "intro_start_position")); - m_pIntroStartPosition->set(-1.0); + m_pIntroStartPosition->set(Cue::kNoPosition); m_pIntroStartEnabled = new ControlObject(ConfigKey(group, "intro_start_enabled")); m_pIntroStartEnabled->setReadOnly(); @@ -138,7 +136,7 @@ CueControl::CueControl(QString group, Qt::DirectConnection); m_pIntroEndPosition = new ControlObject(ConfigKey(group, "intro_end_position")); - m_pIntroEndPosition->set(-1.0); + m_pIntroEndPosition->set(Cue::kNoPosition); m_pIntroEndEnabled = new ControlObject(ConfigKey(group, "intro_end_enabled")); m_pIntroEndEnabled->setReadOnly(); @@ -159,7 +157,7 @@ CueControl::CueControl(QString group, Qt::DirectConnection); m_pOutroStartPosition = new ControlObject(ConfigKey(group, "outro_start_position")); - m_pOutroStartPosition->set(-1.0); + m_pOutroStartPosition->set(Cue::kNoPosition); m_pOutroStartEnabled = new ControlObject(ConfigKey(group, "outro_start_enabled")); m_pOutroStartEnabled->setReadOnly(); @@ -180,7 +178,7 @@ CueControl::CueControl(QString group, Qt::DirectConnection); m_pOutroEndPosition = new ControlObject(ConfigKey(group, "outro_end_position")); - m_pOutroEndPosition->set(-1.0); + m_pOutroEndPosition->set(Cue::kNoPosition); m_pOutroEndEnabled = new ControlObject(ConfigKey(group, "outro_end_enabled")); m_pOutroEndEnabled->setReadOnly(); @@ -207,7 +205,6 @@ CueControl::CueControl(QString group, CueControl::~CueControl() { delete m_pCuePoint; delete m_pCueMode; - delete m_pSeekOnLoadMode; delete m_pCueSet; delete m_pCueClear; delete m_pCueGoto; @@ -306,19 +303,19 @@ void CueControl::trackLoaded(TrackPointer pNewTrack) { QMutexLocker lock(&m_mutex); if (m_pLoadedTrack) { disconnect(m_pLoadedTrack.get(), 0, this, 0); - for (const auto& pControl: m_hotcueControls) { + for (const auto& pControl : m_hotcueControls) { detachCue(pControl); } m_pCueIndicator->setBlinkValue(ControlIndicator::OFF); - m_pCuePoint->set(-1.0); - m_pIntroStartPosition->set(-1.0); + m_pCuePoint->set(Cue::kNoPosition); + m_pIntroStartPosition->set(Cue::kNoPosition); m_pIntroStartEnabled->forceSet(0.0); - m_pIntroEndPosition->set(-1.0); + m_pIntroEndPosition->set(Cue::kNoPosition); m_pIntroEndEnabled->forceSet(0.0); - m_pOutroStartPosition->set(-1.0); + m_pOutroStartPosition->set(Cue::kNoPosition); m_pOutroStartEnabled->forceSet(0.0); - m_pOutroEndPosition->set(-1.0); + m_pOutroEndPosition->set(Cue::kNoPosition); m_pOutroEndEnabled->forceSet(0.0); m_pLoadedTrack.reset(); } @@ -336,11 +333,11 @@ void CueControl::trackLoaded(TrackPointer pNewTrack) { this, &CueControl::trackBeatsUpdated, Qt::DirectConnection); - CuePointer pLoadCue; - for (const CuePointer& pCue: m_pLoadedTrack->getCuePoints()) { - if (pCue->getType() == Cue::LOAD) { - DEBUG_ASSERT(!pLoadCue); - pLoadCue = pCue; + CuePointer pMainCue; + for (const CuePointer& pCue : m_pLoadedTrack->getCuePoints()) { + if (pCue->getType() == Cue::Type::MainCue) { + DEBUG_ASSERT(!pMainCue); + pMainCue = pCue; } } @@ -349,60 +346,73 @@ void CueControl::trackLoaded(TrackPointer pNewTrack) { // Use pNewTrack from now, because m_pLoadedTrack might have been reset // immediately after leaving the locking scope! - // Because of legacy, we store the (load) cue point twice and need to // sync both values. - // The Cue::LOAD from getCuePoints() has the priority - CuePosition cuePoint; - if (pLoadCue) { - cuePoint.setPosition(pLoadCue->getPosition()); + // The Cue::Type::MainCue from getCuePoints() has the priority + CuePosition mainCuePoint; + if (pMainCue) { + mainCuePoint.setPosition(pMainCue->getPosition()); // adjust the track cue accordingly - pNewTrack->setCuePoint(cuePoint); + pNewTrack->setCuePoint(mainCuePoint); } else { // If no load cue point is stored, read from track // Note: This is 0:00 for new tracks - cuePoint = pNewTrack->getCuePoint(); + mainCuePoint = pNewTrack->getCuePoint(); // Than add the load cue to the list of cue CuePointer pCue(pNewTrack->createAndAddCue()); - pCue->setPosition(cuePoint.getPosition()); - pCue->setHotCue(-1); - pCue->setType(Cue::LOAD); + pCue->setStartPosition(mainCuePoint.getPosition()); + pCue->setHotCue(Cue::kNoHotCue); + pCue->setType(Cue::Type::MainCue); } - m_pCuePoint->set(cuePoint.getPosition()); + m_pCuePoint->set(mainCuePoint.getPosition()); // Update COs with cues from track. loadCuesFromTrack(); // Seek track according to SeekOnLoadMode. - SeekOnLoadMode seekOnLoadMode = getSeekOnLoadMode(); + SeekOnLoadMode seekOnLoadMode = getSeekOnLoadPreference(); + + CuePointer pAudibleSound = pNewTrack->findCueByType(Cue::Type::AudibleSound); + double firstSound = Cue::kNoPosition; + if (pAudibleSound) { + firstSound = pAudibleSound->getPosition(); + } + switch (seekOnLoadMode) { - case SEEK_ON_LOAD_ZERO_POS: - seekExact(0.0); + case SeekOnLoadMode::Beginning: + // This allows users to load tracks and have the needle-drop be maintained. + if (!(m_pVinylControlEnabled->get() && + m_pVinylControlMode->get() == MIXXX_VCMODE_ABSOLUTE)) { + seekExact(0.0); + } break; - case SEEK_ON_LOAD_MAIN_CUE: { - double cuePointPosition = cuePoint.getPosition(); - if (cuePointPosition != -1) { - seekExact(cuePointPosition); + case SeekOnLoadMode::FirstSound: + if (firstSound != Cue::kNoPosition) { + seekExact(firstSound); + } else { + seekExact(0.0); } break; - } - case SEEK_ON_LOAD_INTRO_CUE: - seekExact(m_pIntroStartPosition->get()); + case SeekOnLoadMode::MainCue: + if (mainCuePoint.getPosition() != Cue::kNoPosition) { + seekExact(mainCuePoint.getPosition()); + } else { + seekExact(0.0); + } break; - default: - // Respect cue recall preference option. - if (isCueRecallEnabled() && m_pCuePoint->get() != -1.0) { - // If cue recall is ON and main cue point is set, seek to it. - seekExact(m_pCuePoint->get()); - } else if (!(m_pVinylControlEnabled->get() && - m_pVinylControlMode->get() == MIXXX_VCMODE_ABSOLUTE)) { - // Otherwise, seek to zero unless vinylcontrol is on and - // set to absolute. This allows users to load tracks and - // have the needle-drop be maintained. + case SeekOnLoadMode::IntroStart: { + double introStart = m_pIntroStartPosition->get(); + if (introStart != Cue::kNoPosition) { + seekExact(introStart); + } else { seekExact(0.0); } break; } + default: + seekExact(0.0); + break; + } } void CueControl::cueUpdated() { @@ -419,15 +429,16 @@ void CueControl::loadCuesFromTrack() { return; for (const CuePointer& pCue: m_pLoadedTrack->getCuePoints()) { - if (!pLoadCue && pCue->getType() == Cue::LOAD) { + if (pCue->getType() == Cue::Type::MainCue) { + DEBUG_ASSERT(!pLoadCue); // There should be only one MainCue cue pLoadCue = pCue; - } else if (pCue->getType() == Cue::INTRO) { - DEBUG_ASSERT(!pIntroCue); // There should be only one INTRO cue + } else if (pCue->getType() == Cue::Type::Intro) { + DEBUG_ASSERT(!pIntroCue); // There should be only one Intro cue pIntroCue = pCue; - } else if (pCue->getType() == Cue::OUTRO) { - DEBUG_ASSERT(!pOutroCue); // There should be only one OUTRO cue + } else if (pCue->getType() == Cue::Type::Outro) { + DEBUG_ASSERT(!pOutroCue); // There should be only one Outro cue pOutroCue = pCue; - } else if (pCue->getType() == Cue::CUE && pCue->getHotCue() != -1) { + } else if (pCue->getType() == Cue::Type::HotCue && pCue->getHotCue() != Cue::kNoHotCue) { int hotcue = pCue->getHotCue(); HotcueControl* pControl = m_hotcueControls.value(hotcue, NULL); @@ -452,47 +463,43 @@ void CueControl::loadCuesFromTrack() { } } - if (pLoadCue) { - double position = pLoadCue->getPosition(); - Cue::CueSource source = pLoadCue->getSource(); - - m_pCuePoint->set(quantizeCuePoint(position, source, QuantizeMode::ClosestBeat)); - } else { - m_pCuePoint->set(-1.0); - } - if (pIntroCue) { double startPosition = pIntroCue->getPosition(); double endPosition = pIntroCue->getEndPosition(); - Cue::CueSource source = pIntroCue->getSource(); - m_pIntroStartPosition->set(quantizeCuePoint(startPosition, source, QuantizeMode::PreviousBeat)); - m_pIntroStartEnabled->forceSet(startPosition == -1.0 ? 0.0 : 1.0); - m_pIntroEndPosition->set(quantizeCuePoint(endPosition, source, QuantizeMode::NextBeat)); - m_pIntroEndEnabled->forceSet(endPosition == -1.0 ? 0.0 : 1.0); + m_pIntroStartPosition->set(quantizeCuePoint(startPosition, QuantizeMode::PreviousBeat)); + m_pIntroStartEnabled->forceSet(startPosition == Cue::kNoPosition ? 0.0 : 1.0); + m_pIntroEndPosition->set(quantizeCuePoint(endPosition, QuantizeMode::NextBeat)); + m_pIntroEndEnabled->forceSet(endPosition == Cue::kNoPosition ? 0.0 : 1.0); } else { - m_pIntroStartPosition->set(-1.0); + m_pIntroStartPosition->set(Cue::kNoPosition); m_pIntroStartEnabled->forceSet(0.0); - m_pIntroEndPosition->set(-1.0); + m_pIntroEndPosition->set(Cue::kNoPosition); m_pIntroEndEnabled->forceSet(0.0); } if (pOutroCue) { double startPosition = pOutroCue->getPosition(); double endPosition = pOutroCue->getEndPosition(); - Cue::CueSource source = pOutroCue->getSource(); - m_pOutroStartPosition->set(quantizeCuePoint(startPosition, source, QuantizeMode::PreviousBeat)); - m_pOutroStartEnabled->forceSet(startPosition == -1.0 ? 0.0 : 1.0); - m_pOutroEndPosition->set(quantizeCuePoint(endPosition, source, QuantizeMode::NextBeat)); - m_pOutroEndEnabled->forceSet(endPosition == -1.0 ? 0.0 : 1.0); + m_pOutroStartPosition->set(quantizeCuePoint(startPosition, QuantizeMode::PreviousBeat)); + m_pOutroStartEnabled->forceSet(startPosition == Cue::kNoPosition ? 0.0 : 1.0); + m_pOutroEndPosition->set(quantizeCuePoint(endPosition, QuantizeMode::NextBeat)); + m_pOutroEndEnabled->forceSet(endPosition == Cue::kNoPosition ? 0.0 : 1.0); } else { - m_pOutroStartPosition->set(-1.0); + m_pOutroStartPosition->set(Cue::kNoPosition); m_pOutroStartEnabled->forceSet(0.0); - m_pOutroEndPosition->set(-1.0); + m_pOutroEndPosition->set(Cue::kNoPosition); m_pOutroEndEnabled->forceSet(0.0); } + if (pLoadCue) { + double position = pLoadCue->getPosition(); + m_pCuePoint->set(quantizeCuePoint(position, QuantizeMode::ClosestBeat)); + } else { + m_pCuePoint->set(Cue::kNoPosition); + } + // Detach all hotcues that are no longer present for (int hotCue = 0; hotCue < m_iNumHotCues; ++hotCue) { if (!active_hotcues.contains(hotCue)) { @@ -519,17 +526,14 @@ void CueControl::reloadCuesFromTrack() { double intro = m_pIntroStartPosition->get(); // Make track follow the updated cues. - SeekOnLoadMode seekOnLoadMode = getSeekOnLoadMode(); - if (seekOnLoadMode == SEEK_ON_LOAD_DEFAULT) { - if ((trackAt == TrackAt::Cue || wasTrackAtZeroPos) && cue != -1.0 && isCueRecallEnabled()) { - seekExact(cue); - } - } else if (seekOnLoadMode == SEEK_ON_LOAD_MAIN_CUE) { - if ((trackAt == TrackAt::Cue || wasTrackAtZeroPos) && cue != -1.0) { + SeekOnLoadMode seekOnLoadMode = getSeekOnLoadPreference(); + + if (seekOnLoadMode == SeekOnLoadMode::MainCue) { + if ((trackAt == TrackAt::Cue || wasTrackAtZeroPos) && cue != Cue::kNoPosition) { seekExact(cue); } - } else if (seekOnLoadMode == SEEK_ON_LOAD_INTRO_CUE) { - if ((wasTrackAtIntroCue || wasTrackAtZeroPos) && intro != -1.0) { + } else if (seekOnLoadMode == SeekOnLoadMode::IntroStart) { + if ((wasTrackAtIntroCue || wasTrackAtZeroPos) && intro != Cue::kNoPosition) { seekExact(intro); } } @@ -571,11 +575,10 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) { double cuePosition = (m_pQuantizeEnabled->toBool() && closestBeat != -1) ? closestBeat : getSampleOfTrack().current; - pCue->setPosition(cuePosition); + pCue->setStartPosition(cuePosition); pCue->setHotCue(hotcue); pCue->setLabel(""); - pCue->setType(Cue::CUE); - pCue->setSource(Cue::MANUAL); + pCue->setType(Cue::Type::HotCue); // TODO(XXX) deal with spurious signals attachCue(pCue, pControl); @@ -611,7 +614,7 @@ void CueControl::hotcueGoto(HotcueControl* pControl, double v) { if (pCue) { int position = pCue->getPosition(); - if (position != -1) { + if (position != Cue::kNoPosition) { seekAbs(position); } } @@ -632,7 +635,7 @@ void CueControl::hotcueGotoAndStop(HotcueControl* pControl, double v) { if (pCue) { int position = pCue->getPosition(); - if (position != -1) { + if (position != Cue::kNoPosition) { m_pPlay->set(0.0); seekExact(position); } @@ -655,7 +658,7 @@ void CueControl::hotcueGotoAndPlay(HotcueControl* pControl, double v) { if (pCue) { int position = pCue->getPosition(); - if (position != -1) { + if (position != Cue::kNoPosition) { seekAbs(position); if (!isPlayingByPlayButton()) { // cueGoto is processed asynchrony. @@ -685,7 +688,7 @@ void CueControl::hotcueActivate(HotcueControl* pControl, double v) { if (pCue) { if (v) { - if (pCue->getPosition() == -1) { + if (pCue->getPosition() == Cue::kNoPosition) { hotcueSet(pControl, v); } else { if (isPlayingByPlayButton()) { @@ -695,7 +698,7 @@ void CueControl::hotcueActivate(HotcueControl* pControl, double v) { } } } else { - if (pCue->getPosition() != -1) { + if (pCue->getPosition() != Cue::kNoPosition) { hotcueActivatePreview(pControl, v); } } @@ -722,7 +725,7 @@ void CueControl::hotcueActivatePreview(HotcueControl* pControl, double v) { CuePointer pCue(pControl->getCue()); if (v) { - if (pCue && pCue->getPosition() != -1) { + if (pCue && pCue->getPosition() != Cue::kNoPosition) { m_iCurrentlyPreviewingHotcues++; double position = pCue->getPosition(); m_bypassCueSetByPlay = true; @@ -742,7 +745,7 @@ void CueControl::hotcueActivatePreview(HotcueControl* pControl, double v) { // Mark this hotcue as not previewing. double position = pControl->getPreviewingPosition(); pControl->setPreviewing(false); - pControl->setPreviewingPosition(-1); + pControl->setPreviewingPosition(Cue::kNoPosition); // If this is the last hotcue to leave preview. if (--m_iCurrentlyPreviewingHotcues == 0 && !m_bPreviewing) { @@ -779,11 +782,11 @@ void CueControl::hotcuePositionChanged(HotcueControl* pControl, double newPositi CuePointer pCue(pControl->getCue()); if (pCue) { - // Setting the position to -1 is the same as calling hotcue_x_clear - if (newPosition == -1) { + // Setting the position to Cue::kNoPosition is the same as calling hotcue_x_clear + if (newPosition == Cue::kNoPosition) { detachCue(pControl); } else if (newPosition > 0 && newPosition < m_pTrackSamples->get()) { - pCue->setPosition(newPosition); + pCue->setStartPosition(newPosition); } } } @@ -803,7 +806,7 @@ void CueControl::hintReader(HintVector* pHintList) { // constructor and getPosition()->get() is a ControlObject for (const auto& pControl: m_hotcueControls) { double position = pControl->getPosition(); - if (position != -1) { + if (position != Cue::kNoPosition) { cue_hint.frame = SampleUtil::floorPlayPosToFrame(position); cue_hint.frameCount = Hint::kFrameCountForward; cue_hint.priority = 10; @@ -828,7 +831,7 @@ void CueControl::cueSet(double v) { // Store cue point in loaded track if (pLoadedTrack) { - pLoadedTrack->setCuePoint(CuePosition(cue, Cue::MANUAL)); + pLoadedTrack->setCuePoint(CuePosition(cue)); } } @@ -838,7 +841,7 @@ void CueControl::cueClear(double v) { } QMutexLocker lock(&m_mutex); - m_pCuePoint->set(-1.0); + m_pCuePoint->set(Cue::kNoPosition); TrackPointer pLoadedTrack = m_pLoadedTrack; lock.unlock(); @@ -1123,15 +1126,15 @@ void CueControl::introStartSet(double v) { double introEnd = m_pIntroEndPosition->get(); double outroStart = m_pOutroStartPosition->get(); double outroEnd = m_pOutroEndPosition->get(); - if (introEnd != -1.0 && position >= introEnd) { + if (introEnd != Cue::kNoPosition && position >= introEnd) { qWarning() << "Trying to place intro start cue on or after intro end cue."; return; } - if (outroStart != -1.0 && position >= outroStart) { + if (outroStart != Cue::kNoPosition && position >= outroStart) { qWarning() << "Trying to place intro start cue on or after outro start cue."; return; } - if (outroEnd != -1.0 && position >= outroEnd) { + if (outroEnd != Cue::kNoPosition && position >= outroEnd) { qWarning() << "Trying to place intro start cue on or after outro end cue."; return; } @@ -1140,14 +1143,13 @@ void CueControl::introStartSet(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::INTRO); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Intro); if (!pCue) { pCue = pLoadedTrack->createAndAddCue(); - pCue->setType(Cue::INTRO); + pCue->setType(Cue::Type::Intro); } - pCue->setSource(Cue::MANUAL); - pCue->setPosition(position); - pCue->setLength(introEnd != -1.0 ? introEnd - position : 0.0); + pCue->setStartPosition(position); + pCue->setEndPosition(introEnd); } } @@ -1162,10 +1164,10 @@ void CueControl::introStartClear(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::INTRO); - if (introEnd != -1.0) { - pCue->setPosition(-1.0); - pCue->setLength(introEnd); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Intro); + if (introEnd != Cue::kNoPosition) { + pCue->setStartPosition(Cue::kNoPosition); + pCue->setEndPosition(introEnd); } else if (pCue) { pLoadedTrack->removeCue(pCue); } @@ -1178,7 +1180,7 @@ void CueControl::introStartActivate(double v) { double introStart = m_pIntroStartPosition->get(); lock.unlock(); - if (introStart == -1.0) { + if (introStart == Cue::kNoPosition) { introStartSet(1.0); } else { seekAbs(introStart); @@ -1202,15 +1204,15 @@ void CueControl::introEndSet(double v) { double introStart = m_pIntroStartPosition->get(); double outroStart = m_pOutroStartPosition->get(); double outroEnd = m_pOutroEndPosition->get(); - if (introStart != -1.0 && position <= introStart) { + if (introStart != Cue::kNoPosition && position <= introStart) { qWarning() << "Trying to place intro end cue on or before intro start cue."; return; } - if (outroStart != -1.0 && position >= outroStart) { + if (outroStart != Cue::kNoPosition && position >= outroStart) { qWarning() << "Trying to place intro end cue on or after outro start cue."; return; } - if (outroEnd != -1.0 && position >= outroEnd) { + if (outroEnd != Cue::kNoPosition && position >= outroEnd) { qWarning() << "Trying to place intro end cue on or after outro end cue."; return; } @@ -1219,19 +1221,13 @@ void CueControl::introEndSet(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::INTRO); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Intro); if (!pCue) { pCue = pLoadedTrack->createAndAddCue(); - pCue->setType(Cue::INTRO); - } - pCue->setSource(Cue::MANUAL); - if (introStart != -1.0) { - pCue->setPosition(introStart); - pCue->setLength(position - introStart); - } else { - pCue->setPosition(-1.0); - pCue->setLength(position); + pCue->setType(Cue::Type::Intro); } + pCue->setStartPosition(introStart); + pCue->setEndPosition(position); } } @@ -1246,10 +1242,10 @@ void CueControl::introEndClear(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::INTRO); - if (introStart != -1.0) { - pCue->setPosition(introStart); - pCue->setLength(0.0); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Intro); + if (introStart != Cue::kNoPosition) { + pCue->setStartPosition(introStart); + pCue->setEndPosition(Cue::kNoPosition); } else if (pCue) { pLoadedTrack->removeCue(pCue); } @@ -1262,7 +1258,7 @@ void CueControl::introEndActivate(double v) { double introEnd = m_pIntroEndPosition->get(); lock.unlock(); - if (introEnd == -1.0) { + if (introEnd == Cue::kNoPosition) { introEndSet(1.0); } else { seekAbs(introEnd); @@ -1286,15 +1282,15 @@ void CueControl::outroStartSet(double v) { double introStart = m_pIntroStartPosition->get(); double introEnd = m_pIntroEndPosition->get(); double outroEnd = m_pOutroEndPosition->get(); - if (introStart != -1.0 && position <= introStart) { + if (introStart != Cue::kNoPosition && position <= introStart) { qWarning() << "Trying to place outro start cue on or before intro start cue."; return; } - if (introEnd != -1.0 && position <= introEnd) { + if (introEnd != Cue::kNoPosition && position <= introEnd) { qWarning() << "Trying to place outro start cue on or before intro end cue."; return; } - if (outroEnd != -1.0 && position >= outroEnd) { + if (outroEnd != Cue::kNoPosition && position >= outroEnd) { qWarning() << "Trying to place outro start cue on or after outro end cue."; return; } @@ -1303,14 +1299,13 @@ void CueControl::outroStartSet(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::OUTRO); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Outro); if (!pCue) { pCue = pLoadedTrack->createAndAddCue(); - pCue->setType(Cue::OUTRO); + pCue->setType(Cue::Type::Outro); } - pCue->setSource(Cue::MANUAL); - pCue->setPosition(position); - pCue->setLength(outroEnd != -1.0 ? outroEnd - position : 0.0); + pCue->setStartPosition(position); + pCue->setEndPosition(outroEnd); } } @@ -1325,10 +1320,10 @@ void CueControl::outroStartClear(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::OUTRO); - if (outroEnd != -1.0) { - pCue->setPosition(-1.0); - pCue->setLength(outroEnd); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Outro); + if (outroEnd != Cue::kNoPosition) { + pCue->setStartPosition(Cue::kNoPosition); + pCue->setEndPosition(outroEnd); } else if (pCue) { pLoadedTrack->removeCue(pCue); } @@ -1341,7 +1336,7 @@ void CueControl::outroStartActivate(double v) { double outroStart = m_pOutroStartPosition->get(); lock.unlock(); - if (outroStart == -1.0) { + if (outroStart == Cue::kNoPosition) { outroStartSet(1.0); } else { seekAbs(outroStart); @@ -1365,15 +1360,15 @@ void CueControl::outroEndSet(double v) { double introStart = m_pIntroStartPosition->get(); double introEnd = m_pIntroEndPosition->get(); double outroStart = m_pOutroStartPosition->get(); - if (introStart != -1.0 && position <= introStart) { + if (introStart != Cue::kNoPosition && position <= introStart) { qWarning() << "Trying to place outro end cue on or before intro start cue."; return; } - if (introEnd != -1.0 && position <= introEnd) { + if (introEnd != Cue::kNoPosition && position <= introEnd) { qWarning() << "Trying to place outro end cue on or before intro end cue."; return; } - if (outroStart != -1.0 && position <= outroStart) { + if (outroStart != Cue::kNoPosition && position <= outroStart) { qWarning() << "Trying to place outro end cue on or before outro start cue."; return; } @@ -1382,19 +1377,13 @@ void CueControl::outroEndSet(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::OUTRO); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Outro); if (!pCue) { pCue = pLoadedTrack->createAndAddCue(); - pCue->setType(Cue::OUTRO); - } - pCue->setSource(Cue::MANUAL); - if (outroStart != -1.0) { - pCue->setPosition(outroStart); - pCue->setLength(position - outroStart); - } else { - pCue->setPosition(-1.0); - pCue->setLength(position); + pCue->setType(Cue::Type::Outro); } + pCue->setStartPosition(outroStart); + pCue->setEndPosition(position); } } @@ -1409,10 +1398,10 @@ void CueControl::outroEndClear(double v) { lock.unlock(); if (pLoadedTrack) { - CuePointer pCue = pLoadedTrack->findCueByType(Cue::OUTRO); - if (outroStart != -1.0) { - pCue->setPosition(outroStart); - pCue->setLength(0.0); + CuePointer pCue = pLoadedTrack->findCueByType(Cue::Type::Outro); + if (outroStart != Cue::kNoPosition) { + pCue->setStartPosition(outroStart); + pCue->setEndPosition(Cue::kNoPosition); } else if (pCue) { pLoadedTrack->removeCue(pCue); } @@ -1425,7 +1414,7 @@ void CueControl::outroEndActivate(double v) { double outroEnd = m_pOutroEndPosition->get(); lock.unlock(); - if (outroEnd == -1.0) { + if (outroEnd == Cue::kNoPosition) { outroEndSet(1.0); } else { seekAbs(outroEnd); @@ -1437,11 +1426,11 @@ bool CueControl::updateIndicatorsAndModifyPlay(bool newPlay, bool playPossible) //qDebug() << "updateIndicatorsAndModifyPlay" << newPlay << playPossible // << m_iCurrentlyPreviewingHotcues << m_bPreviewing; QMutexLocker lock(&m_mutex); - double cueMode = m_pCueMode->get(); - if ((cueMode == CUE_MODE_DENON || cueMode == CUE_MODE_NUMARK) && - newPlay && playPossible && - !m_pPlay->toBool() && - !m_bypassCueSetByPlay) { + CueMode cueMode = static_cast<CueMode>(static_cast<int>(m_pCueMode->get())); + if ((cueMode == CueMode::Denon || cueMode == CueMode::Numark) && + newPlay && playPossible && + !m_pPlay->toBool() && + !m_bypassCueSetByPlay) { // in Denon mode each play from pause moves the cue point // if not previewing cueSet(1.0); @@ -1476,15 +1465,15 @@ bool CueControl::updateIndicatorsAndModifyPlay(bool newPlay, bool playPossible) } else { // Pause: m_pStopButton->set(1.0); - if (cueMode == CUE_MODE_DENON) { + if (cueMode == CueMode::Denon) { if (trackAt == TrackAt::Cue || previewing) { m_pPlayIndicator->setBlinkValue(ControlIndicator::OFF); } else { // Flashing indicates that a following play would move cue point m_pPlayIndicator->setBlinkValue(ControlIndicator::RATIO1TO1_500MS); } - } else if (cueMode == CUE_MODE_MIXXX || cueMode == CUE_MODE_MIXXX_NO_BLINK || - cueMode == CUE_MODE_NUMARK) { + } else if (cueMode == CueMode::Mixxx || cueMode == CueMode::MixxxNoBlinking || + cueMode == CueMode::Numark) { m_pPlayIndicator->setBlinkValue(ControlIndicator::OFF); } else { // Flashing indicates that play is possible in Pioneer mode @@ -1492,13 +1481,13 @@ bool CueControl::updateIndicatorsAndModifyPlay(bool newPlay, bool playPossible) } } - if (cueMode != CUE_MODE_DENON && cueMode != CUE_MODE_NUMARK) { - if (m_pCuePoint->get() != -1) { + if (cueMode != CueMode::Denon && cueMode != CueMode::Numark) { + if (m_pCuePoint->get() != Cue::kNoPosition) { if (newPlay == 0.0 && trackAt == TrackAt::ElseWhere) { - if (cueMode == CUE_MODE_MIXXX) { + if (cueMode == CueMode::Mixxx) { // in Mixxx mode Cue Button is flashing slow if CUE will move Cue point m_pCueIndicator->setBlinkValue(ControlIndicator::RATIO1TO1_500MS); - } else if (cueMode == CUE_MODE_MIXXX_NO_BLINK) { + } else if (cueMode == CueMode::MixxxNoBlinking) { m_pCueIndicator->setBlinkValue(ControlIndicator::OFF); } else { // in Pioneer mode Cue Button is flashing fast if CUE will move Cue point @@ -1589,7 +1578,7 @@ CueControl::TrackAt CueControl::getTrackAt() const { return TrackAt::End; } double cue = m_pCuePoint->get(); - if (cue != -1 && fabs(sot.current - cue) < 1.0f) { + if (cue != Cue::kNoPosition && fabs(sot.current - cue) < 1.0f) { return TrackAt::Cue; } return TrackAt::ElseWhere; @@ -1597,15 +1586,20 @@ CueControl::TrackAt CueControl::getTrackAt() const { double CueControl::quantizeCurrentPosition(QuantizeMode mode) { SampleOfTrack sampleOfTrack = getSampleOfTrack(); + const double currentPos = sampleOfTrack.current; + const double total = sampleOfTrack.total; // Don't quantize if quantization is disabled. if (!m_pQuantizeEnabled->toBool()) { - return sampleOfTrack.current; + return currentPos; } if (mode == QuantizeMode::ClosestBeat) { double closestBeat = m_pClosestBeat->get(); - return closestBeat != -1.0 ? closestBeat : sampleOfTrack.current; + if (closestBeat != -1.0 && closestBeat <= total) { + return closestBeat; + } + return currentPos; } double prevBeat = m_pPrevBeat->get(); @@ -1613,45 +1607,88 @@ double CueControl::quantizeCurrentPosition(QuantizeMode mode) { if (mode == QuantizeMode::PreviousBeat) { // Quantize to previous beat, fall back to next beat. - return prevBeat != -1.0 ? prevBeat : (nextBeat != -1.0 ? nextBeat : sampleOfTrack.current); - } else if (mode == QuantizeMode::NextBeat) { - // Quantize to next beat, fall back to previous beat. - return nextBeat != -1.0 ? nextBeat : (prevBeat != -1.0 ? prevBeat : sampleOfTrack.current); - } else { - qWarning() << "PROGRAMMING ERROR: Invalid quantize mode" << static_cast<int>(mode); - return -1.0; + if (prevBeat != -1.0) { + return prevBeat; + } + if (nextBeat != -1.0 && nextBeat <= total) { + return nextBeat; + } + return currentPos; + } + if (mode == QuantizeMode::NextBeat) { + // use current position if we are already exactly on the grid, + // otherwise quantize to next beat, fall back to previous beat. + if (prevBeat == currentPos) { + return currentPos; + } + if (nextBeat != -1.0 && nextBeat <= total) { + return nextBeat; + } + if (prevBeat != -1.0) { + return prevBeat; + } + return currentPos; } + DEBUG_ASSERT(!"PROGRAMMING ERROR: Invalid quantize mode"); + return currentPos; } -double CueControl::quantizeCuePoint(double position, Cue::CueSource source, QuantizeMode mode) { +double CueControl::quantizeCuePoint(double cuePos, QuantizeMode mode) { + // we need to use m_pTrackSamples here because SampleOfTrack + // is set later by the engine and not during EngineBuffer::slotTrackLoaded + const double total = m_pTrackSamples->get(); + + VERIFY_OR_DEBUG_ASSERT(cuePos <= total) { + cuePos = total; + } + // Don't quantize unset cues, manual cues or when quantization is disabled. - if (position == -1.0 || source == Cue::MANUAL || !m_pQuantizeEnabled->toBool()) { - return position; + if (cuePos == Cue::kNoPosition || !m_pQuantizeEnabled->toBool()) { + return cuePos; } BeatsPointer pBeats = m_pLoadedTrack->getBeats(); if (!pBeats) { - return position; + return cuePos; } if (mode == QuantizeMode::ClosestBeat) { - double closestBeat = pBeats->findClosestBeat(position); - return closestBeat != -1.0 ? closestBeat : position; + double closestBeat = pBeats->findClosestBeat(cuePos); + if (closestBeat != -1.0 && closestBeat <= total) { + return closestBeat; + } + return cuePos; } double prevBeat, nextBeat; - pBeats->findPrevNextBeats(position, &prevBeat, &nextBeat); + pBeats->findPrevNextBeats(cuePos, &prevBeat, &nextBeat); if (mode == QuantizeMode::PreviousBeat) { // Quantize to previous beat, fall back to next beat. - return prevBeat != -1.0 ? prevBeat : (nextBeat != -1.0 ? nextBeat : position); - } else if (mode == QuantizeMode::NextBeat) { - // Quantize to next beat, fall back to previous beat. - return nextBeat != -1.0 ? nextBeat : (prevBeat != -1.0 ? prevBeat : position); - } else { - qWarning() << "PROGRAMMING ERROR: Invalid quantize mode" << static_cast<int>(mode); - return -1.0; + if (prevBeat != -1.0) { + return prevBeat; + } + if (nextBeat != -1.0 && nextBeat <= total) { + return nextBeat; + } + return cuePos; + } + if (mode == QuantizeMode::NextBeat) { + // use current cuePos if we are already exactly on the grid, + // otherwise quantize to next beat, fall back to previous beat. + if (prevBeat == cuePos) { + return cuePos; + } + if (nextBeat != -1.0 && nextBeat <= total) { + return nextBeat; + } + if (prevBeat != -1.0) { + return prevBeat; + } + return cuePos; } + DEBUG_ASSERT(!"PROGRAMMING ERROR: Invalid quantize mode"); + return cuePos; } bool CueControl::isTrackAtZeroPos() { @@ -1667,13 +1704,10 @@ bool CueControl::isPlayingByPlayButton() { !m_iCurrentlyPreviewingHotcues && !m_bPreviewing; } -bool CueControl::isCueRecallEnabled() { - // Note that [Controls],CueRecall == 0 corresponds to "ON", not "OFF". - return getConfig()->getValue(ConfigKey("[Controls]", "CueRecall"), 0) == 0; -} - -SeekOnLoadMode CueControl::getSeekOnLoadMode() { - return seekOnLoadModeFromDouble(m_pSeekOnLoadMode->get()); +SeekOnLoadMode CueControl::getSeekOnLoadPreference() { + int configValue = getConfig()->getValue(ConfigKey("[Controls]", "CueRecall"), + static_cast<int>(SeekOnLoadMode::IntroStart)); + return static_cast<SeekOnLoadMode>(configValue); } @@ -1695,7 +1729,7 @@ HotcueControl::HotcueControl(QString group, int i) connect(m_hotcuePosition, &ControlObject::valueChanged, this, &HotcueControl::slotHotcuePositionChanged, Qt::DirectConnection); - m_hotcuePosition->set(-1); + m_hotcuePosition->set(Cue::kNoPosition); m_hotcueEnabled = new ControlObject(keyForControl(i, "enabled")); m_hotcueEnabled->setReadOnly(); @@ -1786,7 +1820,7 @@ void HotcueControl::slotHotcueClear(double v) { } void HotcueControl::slotHotcuePositionChanged(double newPosition) { - m_hotcueEnabled->forceSet(newPosition == -1 ? 0.0 : 1.0); + m_hotcueEnabled->forceSet(newPosition == Cue::kNoPosition ? 0.0 : 1.0); emit(hotcuePositionChanged(this, newPosition)); } @@ -1817,10 +1851,10 @@ void HotcueControl::resetCue() { // clear pCue first because we have a null check for valid data else where // in the code m_pCue.reset(); - setPosition(-1.0); + setPosition(Cue::kNoPosition); } void HotcueControl::setPosition(double position) { m_hotcuePosition->set(position); - m_hotcueEnabled->forceSet(position == -1.0 ? 0.0 : 1.0); + m_hotcueEnabled->forceSet(position == Cue::kNoPosition ? 0.0 : 1.0); } |