-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Looping: update loopsize spinbox when recalling loop with any size #12509
base: main
Are you sure you want to change the base?
Conversation
794caed
to
eda03ac
Compare
eda03ac
to
9289597
Compare
a197db1
to
ce02c52
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I have left suggestions.
return -1; | ||
|
||
// No hit. Calculate the fractional beat length | ||
return pBeats->numFractionalBeatsInRange(startPosition, endPosition); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why numBeatsInRange() does not returns factions in the first place.
It could be also required here:
mixxx/src/engine/controls/loopingcontrol.cpp
Line 768 in fe0c530
m_pCOBeatLoopSize->setAndConfirm(pBeats->numBeatsInRange( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch is for when quantize is enabled, we don't need fractional lengths then.
src/track/beats.cpp
Outdated
|
||
// maybe shift range to start at first beat | ||
audio::FrameDiff_t firstBeatOffset = firstBeatPos - startPos; | ||
endPos += firstBeatOffset; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works if the beats have an equal length. For details around a position you may use:
BpmControl::getBeatContext()
. This way you get the beat fraction from before and after the fist and last beat.
We may move this function to this class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That function is helpful, thanks!
Yes, that (and BpmControl::getBeatContextNoLookup
) should be in the Beats
class.
Anyhow, the current implementation works well with constant BPM.
For tracks with variable BPM, the fractional size is just an estimation. Though IMO that doesn't matter since with var. BPM tracks loop_halve/_double
aren't working as expected anyway AFAICT: the loop is simply scaled based on loop_in position and number of beats, i.e. it doesn't consider shorter/longer beats inside or after the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I understand.
What could be a real live use case?
A beat loop with an integer number moved by a half beat and a tempo change inside a loop.
Which beat length is used for moving? Probably the first beat? After moving, the loop will start at the middle of the fist beat and end somewhere else in the last beat.
I think the loop size should be still without a fraction, right?
What happens if the loop is moved fully in the new tempo region?
We need to test this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loops that contain tempo changes are moved correctly: both loop_in and loop_out are moved to the correct fractional position. This works with all loop sizes. 👍
I tested with 4 and 3.5 beats loop moved by 1/2 and 8 beats several times while the tempo changed from ~110 to ~140.
Thanks for you review! This is appearantly not ready since |
This happens when re-activating a saved loop for example, and it's a round-trip that becomes visible with this fix. The |
ce02c52
to
3ab9370
Compare
Alright, I moved some helpers to more suitable classes and picked 1dafd34. The actual loop size fix is on top of it and it's now much simpler and more accurate using "Good" news: the Though
and
I'm not sure why it was decided to not update the spinbox with the manual loop's length and thereby not make halve/double work, but there are even tests for that After skimming #1187 I assume this behaviour should preserve (standart pre-set) loop sizes so From the top of my head I have two real-life use case where it would have been helpful: Forgive me opening this can of worms so soon before the release ; ) |
3ab9370
to
f7bcc28
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the update.
I need time for testing.
VERIFY_OR_DEBUG_ASSERT(isValid()) { | ||
return false; | ||
} | ||
return target.isValid() && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this isValid() also an debug assert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the caller is responsible for testing the position. It may be possible this is called with an invalid FramePos and in that case we simply return false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reminder
@@ -91,6 +91,16 @@ class FramePos final { | |||
return util_isfinite(m_framePosition); | |||
} | |||
|
|||
// returns true if a is valid and is fairly close to target (within +/- 1 frame). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// returns true if a is valid and is fairly close to target (within +/- 1 frame). | |
// returns true if this and target are valid and target is fairly close (within +/- 1 frame). |
I have tested with a changing tempo track and have these issues:
|
This may be due to invalid loop cues. Can you verify it occurs with new tracks? (new in the db, for example a track copy). |
It is required to press Return to confirm the new value. |
yes, see #12522. |
Not sure what you mean. |
@daschuer, quoting you from #10511
Sure. All we have to do is decide about the UX, i.e. how to reset fractional sizes when a new track is loaded so that |
Here my retest results:
Not able to reproduce it exactly. Currently the spinbox does not change. If this is a fractional position from the previous deck, you have hard times to use the double/half buttons in a reasonable way. How about just resetting it to a reasonable default?
Known issues . do we have a bug for it?
Yes, both seems to be the desired behaviour. Unfortunately it is inconsistent with the "feature" of showing the loop size at start up. Did you consider to not adopt non integer beat fractions after loading? This will also solve the first bullet point would feel more consistent.
Yes. Discovered another issue:
Conclusion: There is something fishy with reloading a track after a loop has been removed before. Probably thecause of the glitches I have experienced earlier. |
Yes, this is part of #12522 It seems there are a few issues with loop reset that were noticeable preiously, for example 5606098
I'd even vote for not adopting any loop size after track load. I don't understand why loop halve/double should immediatly affect the existing loop (temp or saved), that's unhandy if I just want to preprare a new loop. |
Sounds good. |
How is the state here? I will put it to draft. Please adjust if this is wrong. |
Yeah I've put this on hold already anyway, currently I'm lacking the motivation to get this ready for 2.5 I'll pick this up at some point after 2.5 is out. |
This PR is marked as stale because it has been open 90 days with no activity. |
f7bcc28
to
feb5fea
Compare
fixes #10511
The loop size is now correctly detected and updated, both when setting a loop with a size not in the preset list (0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8 ... 512) by setting the size with the beatloop size spinbox and when re-activating such a saved loop.
Done with new
Beats::numFractionalBeatsInRange(start, end)
.Note:
Unfortunately this does not work for loops set with IN/OUT buttons (intentionally, see my comment below).
edit: addressed in #12522