@@ -400,7 +400,7 @@ double BpmControl::calcSyncedRate(double userTweak) {
400400
401401 // Now that we have our beat distance we can also check how large the
402402 // current loop is. If we are in a <1 beat loop, don't worry about offset.
403- const bool loop_enabled = m_pLoopEnabled->get () > 0.0 ;
403+ const bool loop_enabled = m_pLoopEnabled->toBool () ;
404404 const double loop_size = (m_pLoopEndPosition->get () -
405405 m_pLoopStartPosition->get ()) /
406406 dBeatLength;
@@ -567,14 +567,14 @@ bool BpmControl::getBeatContextNoLookup(
567567 return true ;
568568}
569569
570- double BpmControl::getPhaseOffset (double dThisPosition) {
570+ double BpmControl::getNearestPositionInPhase (double dThisPosition, bool respectLoops ) {
571571 // Without a beatgrid, we don't know the phase offset.
572572 if (!m_pBeats) {
573- return 0 ;
573+ return dThisPosition ;
574574 }
575575 // Master buffer is always in sync!
576576 if (getSyncMode () == SYNC_MASTER ) {
577- return 0 ;
577+ return dThisPosition ;
578578 }
579579
580580 // Get the current position of this deck.
@@ -588,13 +588,13 @@ double BpmControl::getPhaseOffset(double dThisPosition) {
588588 if (!getBeatContext (m_pBeats, dThisPosition,
589589 &dThisPrevBeat, &dThisNextBeat,
590590 &dThisBeatLength, NULL )) {
591- return 0 ;
591+ return dThisPosition ;
592592 }
593593 } else {
594594 if (!getBeatContextNoLookup (dThisPosition,
595595 dThisPrevBeat, dThisNextBeat,
596596 &dThisBeatLength, NULL )) {
597- return 0 ;
597+ return dThisPosition ;
598598 }
599599 }
600600
@@ -606,15 +606,15 @@ double BpmControl::getPhaseOffset(double dThisPosition) {
606606 // If not, we have to figure it out
607607 EngineBuffer* pOtherEngineBuffer = pickSyncTarget ();
608608 if (pOtherEngineBuffer == NULL ) {
609- return 0 ;
609+ return dThisPosition ;
610610 }
611611
612612 TrackPointer otherTrack = pOtherEngineBuffer->getLoadedTrack ();
613613 BeatsPointer otherBeats = otherTrack ? otherTrack->getBeats () : BeatsPointer ();
614614
615615 // If either track does not have beats, then we can't adjust the phase.
616616 if (!otherBeats) {
617- return 0 ;
617+ return dThisPosition ;
618618 }
619619
620620 double dOtherLength = ControlObject::getControl (
@@ -624,7 +624,7 @@ double BpmControl::getPhaseOffset(double dThisPosition) {
624624
625625 if (!BpmControl::getBeatContext (otherBeats, dOtherPosition,
626626 NULL , NULL , NULL , &dOtherBeatFraction)) {
627- return 0.0 ;
627+ return dThisPosition ;
628628 }
629629 }
630630
@@ -658,51 +658,55 @@ double BpmControl::getPhaseOffset(double dThisPosition) {
658658 dNewPlaypos += dThisPrevBeat;
659659 }
660660
661- // We might be seeking outside the loop.
662- const bool loop_enabled = m_pLoopEnabled->get () > 0.0 ;
663- const double loop_start_position = m_pLoopStartPosition->get ();
664- const double loop_end_position = m_pLoopEndPosition->get ();
665-
666- // Cases for sanity:
667- //
668- // CASE 1
669- // Two identical 1-beat loops, out of phase by X samples.
670- // Other deck is at its loop start.
671- // This deck is half way through. We want to jump forward X samples to the loop end point.
672- //
673- // Two identical 1-beat loop, out of phase by X samples.
674- // Other deck is
675-
676- // If sync target is 50% through the beat,
677- // If we are at the loop end point and hit sync, jump forward X samples.
678-
679-
680- // TODO(rryan): Revise this with something that keeps a broader number of
681- // cases in sync. This at least prevents breaking out of the loop.
682- if (loop_enabled) {
683- const double loop_length = loop_end_position - loop_start_position;
684- if (loop_length <= 0.0 ) {
685- return false ;
686- }
687-
688- // TODO(rryan): If loop_length is not a multiple of dThisBeatLength should
689- // we bail and not sync phase?
690-
691- // Syncing to after the loop end.
692- double end_delta = dNewPlaypos - loop_end_position;
693- if (end_delta > 0 ) {
694- int i = end_delta / loop_length;
695- dNewPlaypos = loop_start_position + end_delta - i * loop_length;
696- }
697-
698- // Syncing to before the loop beginning.
699- double start_delta = loop_start_position - dNewPlaypos;
700- if (start_delta > 0 ) {
701- int i = start_delta / loop_length;
702- dNewPlaypos = loop_end_position - start_delta + i * loop_length;
661+ if (respectLoops) {
662+ // We might be seeking outside the loop.
663+ const bool loop_enabled = m_pLoopEnabled->toBool ();
664+ const double loop_start_position = m_pLoopStartPosition->get ();
665+ const double loop_end_position = m_pLoopEndPosition->get ();
666+
667+ // Cases for sanity:
668+ //
669+ // CASE 1
670+ // Two identical 1-beat loops, out of phase by X samples.
671+ // Other deck is at its loop start.
672+ // This deck is half way through. We want to jump forward X samples to the loop end point.
673+ //
674+ // Two identical 1-beat loop, out of phase by X samples.
675+ // Other deck is
676+
677+ // If sync target is 50% through the beat,
678+ // If we are at the loop end point and hit sync, jump forward X samples.
679+
680+
681+ // TODO(rryan): Revise this with something that keeps a broader number of
682+ // cases in sync. This at least prevents breaking out of the loop.
683+ if (loop_enabled &&
684+ dThisPosition <= loop_end_position) {
685+ const double loop_length = loop_end_position - loop_start_position;
686+ const double end_delta = dNewPlaypos - loop_end_position;
687+
688+ // Syncing to after the loop end.
689+ if (end_delta > 0 && loop_length > 0.0 ) {
690+ int i = end_delta / loop_length;
691+ dNewPlaypos = loop_start_position + end_delta - i * loop_length;
692+
693+ // Move new position after loop jump into phase as well.
694+ // This is a recursive call, called only twice because of
695+ // respectLoops = false
696+ dNewPlaypos = getNearestPositionInPhase (dNewPlaypos, false );
697+ }
698+
699+ // Note: Syncing to before the loop beginning is allowed, because
700+ // loops are catching
703701 }
704702 }
705703
704+ return dNewPlaypos;
705+ }
706+
707+ double BpmControl::getPhaseOffset (double dThisPosition) {
708+ // This does not respect looping
709+ double dNewPlaypos = getNearestPositionInPhase (dThisPosition, false );
706710 return dNewPlaypos - dThisPosition;
707711}
708712
0 commit comments