Skip to content

Commit

Permalink
Looping: update loopsize when recalling loop with any size
Browse files Browse the repository at this point in the history
  • Loading branch information
ronso0 committed Jan 4, 2024
1 parent ee1263b commit 9289597
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
34 changes: 26 additions & 8 deletions src/engine/controls/loopingcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1299,15 +1299,33 @@ double LoopingControl::findBeatloopSizeForLoop(
return -1;
}

for (unsigned int i = 0; i < (sizeof(s_dBeatSizes) / sizeof(s_dBeatSizes[0])); ++i) {
const auto loopEndPosition = pBeats->findNBeatsFromPosition(startPosition, s_dBeatSizes[i]);
// First we check if this is one of the preset sizes
const auto beatSizes = getBeatSizes();
for (const auto size : beatSizes) {
const auto loopEndPosition = pBeats->findNBeatsFromPosition(startPosition, size);
if (loopEndPosition.isValid()) {
if (endPosition > (loopEndPosition - 1) && endPosition < (loopEndPosition + 1)) {
return s_dBeatSizes[i];
return size;
}
}
}
return -1;

// No hit. Let's check integer sizes 1 - [max. loop size]
for (unsigned int i = 1; i < beatSizes.last(); ++i) {
if (beatSizes.contains(i)) {
// skip sizes we already checked above
continue;
}
const auto loopEndPosition = pBeats->findNBeatsFromPosition(startPosition, i);
if (loopEndPosition.isValid()) {
if (endPosition > (loopEndPosition - 1) && endPosition < (loopEndPosition + 1)) {
return i;
}
}
}

// Still no hit. Calculate the fractional beat length
return pBeats->numFractionalBeatsInRange(startPosition, endPosition);
}

void LoopingControl::updateBeatLoopingControls() {
Expand Down Expand Up @@ -1449,10 +1467,10 @@ void LoopingControl::slotBeatLoop(double beats, bool keepStartPoint, bool enable

if (!newloopInfo.startPosition.isValid() ||
!newloopInfo.endPosition.isValid() ||
newloopInfo.startPosition >=
newloopInfo.endPosition // happens when the call above fails
|| newloopInfo.endPosition >
trackEndPosition) { // Do not allow beat loops to go beyond the end of the track
// happens when the call above fails
newloopInfo.startPosition >= newloopInfo.endPosition ||
// Do not allow beat loops to go beyond the end of the track
newloopInfo.endPosition > trackEndPosition) {
// If a track is loaded with beatloop_size larger than
// the distance between the loop in point and
// the end of the track, let beatloop_size be set to
Expand Down
21 changes: 21 additions & 0 deletions src/track/beats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,27 @@ int Beats::numBeatsInRange(audio::FramePos startPosition, audio::FramePos endPos
return i - 2;
};

double Beats::numFractionalBeatsInRange(audio::FramePos startPosition,
audio::FramePos endPosition) const {
// find first beat in range
audio::FramePos firstBeatPos = findNextBeat(startPosition);
// always >= 0
audio::FrameDiff_t startBeatOffset = firstBeatPos - startPosition;

// shift range to start at firstBeatPos
audio::FramePos newEnd = endPosition + startBeatOffset;
// find last beat in shifted range
audio::FramePos newEndBeatPos = findPrevBeat(newEnd);
const auto newEndBeat = iteratorFrom(newEndBeatPos);

double intPart = numBeatsInRange(firstBeatPos, newEndBeatPos);

// always >= 0
audio::FrameDiff_t endOffset = newEnd - newEndBeatPos;
double fractPart = endOffset / newEndBeat.beatLengthFrames();
return intPart + fractPart;
}

audio::FramePos Beats::findNextBeat(audio::FramePos position) const {
return findNthBeat(position, 1);
}
Expand Down
2 changes: 2 additions & 0 deletions src/track/beats.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ class Beats : private std::enable_shared_from_this<Beats> {
audio::FramePos snapPosToNearBeat(audio::FramePos position) const;

int numBeatsInRange(audio::FramePos startPosition, audio::FramePos endPosition) const;
double numFractionalBeatsInRange(audio::FramePos startPosition,
audio::FramePos endPosition) const;

/// Find the frame position N beats away from `position`. The number of beats may be
/// negative and does not need to be an integer. In this case the returned position will
Expand Down

0 comments on commit 9289597

Please sign in to comment.