-
-
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
Add new beats implementation #4255
Conversation
c289f6e
to
603d100
Compare
ping @hacksdump |
FWIW the new implementation is not really related to the old one. @hacksdump used a list of (index, bpm) tuples to define a beatgrid. This implementation uses (position, beatsTillNextMarker) tuples instead. |
791e15c
to
d35d388
Compare
753afde
to
7e6bbd5
Compare
c295621
to
d762f97
Compare
How about splitting out the first commits? For me it looks like they are already mature. |
Isn't this done in #4361 ? |
Oh yes. Thank you for the hint. |
Can you brief describe how the transition from BeatGrid and BeatMap into NewBeats and into a measure based format will work? I like the idea of frame based anchor points, because it is native in then engine. However, we had some voices pro a seconds based format. I am missing the info how measures will be coded. I think we need to to consolidate a plan, for the final format to have the chance to discuss implications before the code is written. |
da8e90a
to
e000ebf
Compare
The last remaining test that fails is
|
This is supposed to combine the beatmap/beatgrid classes into a single, versatile implementation.
The tests fails although the results are roughly in the same ballpark (+/- 4 BPM): src/test/beatmaptest.cpp:249: Failure Expected equality of these values: 63.937645572318047 pMap->getBpmAroundPosition( mixxx::audio::kStartFramePos + 4 * approx_beat_length, 4) .value() Which is: 64.419153961777965 src/test/beatmaptest.cpp:254: Failure Expected equality of these values: 118.96668932698844 pMap->getBpmAroundPosition( mixxx::audio::kStartFramePos + 60 * approx_beat_length, 4) .value() Which is: 122.00000000000068 src/test/beatmaptest.cpp:260: Failure Expected equality of these values: 62.937377309576974 pMap->getBpmAroundPosition(mixxx::audio::kStartFramePos, 4).value() Which is: 60.731050014550149 src/test/beatmaptest.cpp:262: Failure Expected equality of these values: 118.96668932698844 pMap->getBpmAroundPosition( mixxx::audio::kStartFramePos + 65 * approx_beat_length, 4) .value() Which is: 122.00000000000068 Due to the test design it's not possible to verify these floating point results manually (on paper), and it's likely that these issues are caused by rounding the gradually increasing beat lengths. The BPM calculation methods are already tested in `BeatsTest`, so we just remove this.
Without this patch, every beats instance created from a beats vector would be stored a `BeatMap` in the database, even if a `BeatGrid` would suffice. This also "fixes" the broken `EngineSyncTest.HalfDoubleConsistency` test which suffered from a minor rounding issue in `Beats::getBpmAroundPosition`, which is causes by the initial play position of an `EngineBuffer` being set to `std::numeric_limits<double>::lowest()`, which leads to slightly inaccurate floating point results in `getBpmAroundPosition()`. Because this commit makes the beats instance used in the test have a constant tempo, this "fixes" the issue because the `getBpmAroundPosition()` can exit early and just return the (accurate) end marker BPM.
This method should return the predominant BPM value instead.
let me know if you need any help with this enginesync test, I know they can be tricky. |
Thanks. The issue is kind of resolved for now, as explained here: https://mixxx.zulipchat.com/#narrow/stream/109171-development/topic/beat.20grid.20revamp.20re.3A.20pr.20.232961/near/258174413 The root cause we miniscule rounding issues because engine buffer initializes the play position with |
Right now, the conversion is performed on load. The storage format is not touched, it stays the same. We only convert it on load. This is why the chance of breaking something is small, in the worst case we could just revert the merge and not breaking our user's beatgrids.
We can consider that, but as this PR does not change the storage format and still loads/writes legacy beatgrids/beatmaps, this is out of scope here and can be discussed later on.
Measures/downbeats are not supported yet, but could be added by adding support for it using the iterator API. Instead of This will be considerably easier if we enforce that BeatMarkers (consisting of
As discussed previously on Zulip, we should merge the two implementations into a single one first, without changing the stored data format. When that is done, we can add some additional attributes such as downbeats/timeSignature as dummy values in memory, still all without changing the stored data format. Then we can already start working on an editing UI, and detect issues with the in-memory representation early on, without migrating user-data. After (or maybe even in parallel to) the editing UI development, someone could start working on moving away from the legacy storage formats (beatgrid/beatmap) and implement a native data format. Of course, we should only merge that if we are sure that the format suffices, because this is will make people lose their beatgrids if they downgrade to an older mixxx version. So the actual data format change is actually the very last step. Of course this needs to be discussed properly. |
I played around with this branch and it seems to work well! And propagating beats before the beginning for beatmaps is super great :). I don't really have any comments on the technical implementation other than to say thank you for the new tests. |
There are some conflicts now. |
Resolved. |
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 and works also good.
Thank you very much.
This adds a new beats implementation that is supposed to replace the other two implementations (obligatory xkcd).
I'm still experimenting with the design and there's still a bunch of stuff missing or not properly tested, but in case someone already wants to leave some comments, feel free to do so.
To Do:
Fix testReplaced with new tests that are verifyable by hand (e000ebf)BeatMapTest.TestBpmAround
EngineSyncTest.HalfDoubleConsistency
EngineSyncTest.BeatMapQuantizePlay
SeratoBeatGridTest.SerializeBeatMap
getBpmInRange()