don't stop track when loop_in/out is beyond track boundaries

Bug #1799574 reported by ronso0
18
This bug affects 3 people
Affects Status Importance Assigned to Milestone
Mixxx
Confirmed
Medium
ronso0

Bug Description

I create a 8-beat loop loop close to the track end and shift the loop to have loop_in at the beginning of a vocal phrase. I could move the loop let's say 1/8 beat beyond the track end (= loop_out after track end, but no indicator where that end point actually is Bug 1799576) and the loop would stop playing as soon as it reaches the track end.

I see there'a reason to not allow huge loops (unexpecedly) cross tracks' start/end, but there are use cases where this is actually very helpful:
1) I somehow didn't notice the track end is getting closer, and as a quick hack I'd enable a 4-beat loop to gain some more seconds to load and align the next track. I might be very late and that loop would cross the track end. Let it continue playing..
2) 3 beats before the track end there's a vocal I'd like to have in an 8-beat loop to match the next track, and I want that vocal only and cut off the preceeding beats. Same applies to loops crossing the first sample of a track.

2.3.0-alpha-pre

Tags: looping
ronso0 (ronso0)
tags: added: looping
description: updated
summary: - loop close to track end suddenly stops deck after several cycles
+ loop_out should stay within track boundaries ...
description: updated
ronso0 (ronso0)
summary: - loop_out should stay within track boundaries ...
+ let loop_out be beyond track boundaries, ignore track start/end then
description: updated
ronso0 (ronso0)
summary: - let loop_out be beyond track boundaries, ignore track start/end then
+ ignore track start/end when loop_in/out is beyond track boundaries
summary: - ignore track start/end when loop_in/out is beyond track boundaries
+ don't stop track when loop_in/out is beyond track boundaries
description: updated
Changed in mixxx:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Daniel Schürmann (daschuer) wrote :

Ok, the current situation is odd.

I am not sure what the right solution is though.

1.) We may play past the end, which is unfortunately silence.
2.) We may not allow to move a beatloop past the track end, ignoring the beatjump.
3.) We may fix loop out at the track end, falling out of beat.
4.) We may short the loop at the last beat to not go beyond the track end but be in beat.

Unfortunately the engine can play past a track right-now. So 1. involves some refactoring. Is it worth the work, or is the silence part undesired anyway?
Does one of the other solutions suite?

Revision history for this message
ronso0 (ronso0) wrote :

1) would be the winner :) because loop_end after track end would be a feature IMO

The playback should stop at the end only when there's no active loop with loop_end beyond the end.

For rewind it works quite well right now: you can scroll before the track start, when dragging waveforms or with controller wheel in scratch mode. OTOH the rewind stops at the track start when the wheel is in jog mode, which is also a nice feature.

Revision history for this message
mevsme (mevsme) wrote :

Maybe also, as a variant, we can make recursive loop that starts at the end and finish at the start? D

Revision history for this message
ronso0 (ronso0) wrote :

that's just the play direction. use '[group],reverse' '1'

loop_in at end, loop_out at start would create a zero-length loop.
what would happen then? would mixxx create a black hole?

Revision history for this message
Daniel Schürmann (daschuer) wrote :

mevsme's idea is to build a loop that runs bejond the end of the track as if repeat was enabled, by jumping to the beginning and playing the missing samples from there.

Revision history for this message
ronso0 (ronso0) wrote :

ok, I misunderstood 'recursive'.

I think the chance samples from the start fit better than silence is quite low. If I stick to the vocal use case I mentioned above it would probably be fading out anyway, so silence wouldn't be a problem for me.

IMHO, to avoid refactoring or making the loop code more complicated it'd be best (easiest for now) to prevent the loop being shifted beyond the end?

Revision history for this message
ronso0 (ronso0) wrote :

Using samples from the start is problematic IMO as users probably don't expect it, and if the do the result is unprecitable because that range is not visible on the waveform.

Extending the loop-able range beyond the track and filling that space with silence would still be my preferred solution because you would get what you see: silence.
If the engine could do that the remaining question is just:
how far may the loop to span behind the end to avoid long silence?

what about limiting that part to at most the half of the desired loop?
Example:
* X beats before end, X=track_end - play_pos
* attempt to set a loop of N beats
if (X > N/2) {
  beatloop_activate
  return
} else {
  N=N/2
  // repeat
}

Revision history for this message
ronso0 (ronso0) wrote :

Since I ran into this bug repeatedly I'll work on a fix for 2.3

I'll go with
2.) don't allow to move a beatloop past the track end

https://github.com/mixxxdj/mixxx/pull/3117

Changed in mixxx:
assignee: nobody → ronso0 (ronso0)
status: Confirmed → In Progress
milestone: none → 2.3.0
Revision history for this message
Jörg Wartenberg (joerg-ubuntu) wrote :

I would like to add an additional use case, with a loop beyond the track end:
I've some tracks with just beats(drums). These tracks are all exactly 16 or 32 beats long. The analyzer detects the beat period precisely with 1/16th (or 1/32th) of the track length, but because the position of the first beat is not detected in the very first sample of the track, the loop does not fit.

To handle this use case I propse the following behavior:
If the loop has the same number of samples as the track itself, the playposition should jump after the last sample of the track, to the first sample of the track.

ronso0 (ronso0)
Changed in mixxx:
status: In Progress → Confirmed
Revision history for this message
ronso0 (ronso0) wrote :

for reference, this is the place where 'play' is disabled when play_pos passes track_end:
https://github.com/mixxxdj/mixxx/blob/2.3/src/engine/enginebuffer.cpp#L1001-L1019

IMO the looping control should stay as is and shouldn't bother with track_end. Except that (when reverting #3117) we need to set some limit for how far a loop can be set/moved beyond the track's end to avoid long useless silence, right?

when passing track_end EngineBuffer::processTrackLocked() would check if play_pos id within an active loop: if true it wouldn' touch 'play' and the track continues.

Changed in mixxx:
milestone: 2.3.0 → none
Revision history for this message
Swiftb0y (swiftb0y) wrote :

Mixxx now uses GitHub for bug tracking. This bug has been migrated to:
https://github.com/mixxxdj/mixxx/issues/9478

lock status: Metadata changes locked and limited to project staff
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.