-
-
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/Beatjump: use seconds if track has no beats #12961
Looping/Beatjump: use seconds if track has no beats #12961
Conversation
Ah, of course not, they assume no-ops for no beats. |
I expected that Looping tests would fail now, but why on earth do they pass on macOS arm64?? |
aebdb89
to
0e2bed5
Compare
0e2bed5
to
1cfcc1b
Compare
All tests pass 🎉 So it was just that quantize had to be disabled where it is not explicitely expected/required 🙄 |
Thank you for taking care. An alternative solution would be a default of 120 bpm. I have no strong opinion here, I just want to make sure we fix the issue optimal. What are the use-cases? Do we have one, or is it just to do "something" that the buttons not feel broken? I can think of vokal tracks, ambient tracks. Currently Mixxx applies a beat grid to all of them l, so the user has artificial removed and locked the bpm for some reason. |
IMO "1 'beat' = 1 second" makes it predictable. Yes, ambient tracks. Tbh me personally ran into this situation only a few times in live situations when attempting to mix in ambient tracks. The UX is currently like this:
I use a encoder, so I usually press (4 beats) and instantly turn it to adjust the loop as desired (visually, to either constrain the loop to beatless regions, or the way around, avoid a beatless tail). |
FWIW I didn't test with quantize yet. In order to clarify that situation and not snap seconds loops to invisible beats, we may consider to also set a |
A OK since you have a real use case and this works for you, it should be a good choice. |
} else { | ||
m_pBeats = getFake60BpmBeats(); | ||
} | ||
// TODO All "if (m_pBeats)" checks are now obsolete actually... |
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.
Only if we also initialize it in the constructor. This would be the first use case of a not-null smart pointer. A fun project out of the original scope here.
This flag sounds reasonable. |
Added the flag, now waiting curiously how the tests like that... |
Cooool, it works and tests pass. Bugfix or feature? I'd argue for bugfix, but I don't mind moving this to 2.5 in order to increase the chance of getting completed translations. |
My vote is for 2.4 |
not just the fake beats we use for looping/jumping by seconds. This will prevent unexpectedly placing loop markers on (invisible) fake beat markers.
3aaccf6
to
01ed90b
Compare
IMHO, this is a feature with a risk of side effects and should go into Main therefore. |
What type of side effects do you expect?
|
I'm not aware of any particular problem, but information about loop length is used at many different places of our code (mappings, skins, waveforms, vsynthread), therefore the probability to break something is high. |
I don't see what could be broken:
Note I don't mind to move this to 2.5, but only if there are valid concerns. |
At least clockcontrol takes the beat/loop relation into account too. |
Sorry, my phrasing was unclear. |
I do agree with this too. Perhaps we could introduce a user preference for this? This way we can default to 60 BPM but also allow user to have other default depending of the BPM range they usually works with? |
Yup, we can certainly do that. |
Moved this to 2.5-beta |
Do we have a conclusion for the merge target here? @JoergAtGithub? |
This is an enhancement and not fixing a bug. My opinion is still, that this is too risky for a bugfix release! |
m_pBeats = getFake60BpmBeats(); | ||
m_trueTrackBeats = false; | ||
} | ||
// TODO All "if (m_pBeats)" checks are now obsolete actually... |
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.
Than these if (m_pBeats)
need to be removed from the code
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 have the impression that it is used as if (m_pTrack)
.
I'll take a look.
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.
If refined updateBeats() so we now have a Beats nullptr again if no track is loaded, and all if (m_pBeats)
checks can stay.
TEST_F(HotcueControlTest, CueLoopWithoutLoopOrBeats) { | ||
createAndLoadFakeTrack(); | ||
|
||
EXPECT_DOUBLE_EQ(static_cast<double>(HotcueControl::Status::Empty), m_pHotcue1Enabled->get()); | ||
EXPECT_FALSE(mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid( | ||
m_pHotcue1Position->get()) | ||
.isValid()); | ||
EXPECT_FALSE(mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid( | ||
m_pHotcue1EndPosition->get()) | ||
.isValid()); | ||
|
||
m_pHotcue1CueLoop->set(1); | ||
m_pHotcue1CueLoop->set(0); | ||
|
||
EXPECT_DOUBLE_EQ(static_cast<double>(HotcueControl::Status::Set), m_pHotcue1Enabled->get()); | ||
EXPECT_FRAMEPOS_EQ_CONTROL(mixxx::audio::kStartFramePos, m_pHotcue1Position); | ||
EXPECT_FALSE(mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid( | ||
m_pHotcue1EndPosition->get()) | ||
.isValid()); | ||
EXPECT_FALSE(m_pLoopEnabled->toBool()); | ||
} | ||
|
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.
Why did you remove these unit tests? Now we have more cases to test and not less.
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 tests that there is no (cue) loop created if the track has no beats. This situation will not occur anymore (with a track loaded).
We don't need to test "no beats" cases --> less tests.
What new cases are you referring to?
I already assigned it to the 2.5-beta milestone, just need to change the base branch. I'm still curious where you see the risk, please elaborate. |
ping @JoergAtGithub @daschuer I moved it to 2.5-beta since. IMO it's still a bugfix for 2.4 but due concerns I shifted it, so let's try to get it in soonish (i don't see the need to delay this until 2.6). |
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.
LGTM. We have not yet a formal beta so it should be OK to have the string changes included.
Thank you! |
Finally allows looping and beatjumping for tracks with no beats.
If the track has no beats, simply load fake beats: 60 BPM, first beat at track start.
1 'beat' = 1 second
Looping and beatjumping works as desired 🎉
edit: Also sets a
m_trueTrackBeats
flag so loops don't unexpectedly snap to the (invisible) fake beats.For completeness we'd need to add one string to adjust all related tooltips, and one for all items in controlpickermenu.cpp.
If this string freeze viloation is considered not worth for having this nice fix in 2.4.1, or if you think this is definitely a new feature, I'll rebase onto main.
TODO
Fixes #11124