-
-
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 support for Traktor cues #1411
base: main
Are you sure you want to change the base?
Conversation
Thank you very much for this PR. How are the Traktor cue points map to Mixxx cue points? |
QXmlStreamAttributes attr = xml.attributes (); | ||
int hotcue = attr.value("HOTCUE").toString().toInt(); | ||
//int position = int(attr.value("START").toString().toFloat()/1000.0 * float(samplerate) * 2.0); | ||
int position = int(attr.value("START").toString().toDouble()/1000.0 * 48000.0 * 2.0); |
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.
We need here to use the tack sample rate.
We are moving to a floating point transport engine. This means Mixxx can handle double precision cue points soon, and the code here should use double to not loose info.
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.
The Track sample rate is not available at this point.
It is assumed to be 48kHz at first, but the moment the sample rate is available (on track import [traktorfeature.cpp:59 and 79]), the position is changed to the proper value.
Did I misunderstand the second part of the comment?
Because this code uses double already.
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 mean: int position -> double position
but maybe I have missed something,
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.
Oh ok.
Is the position not denoting the sample?
What exactly would a double value mean in this case?
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.
Ah ... posMultiplier. Can't we just remove the 48000, in all places and user positionMs until it is converted into Mixxx stereo samples playposition?
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.
Yeah it's probably a prettier solution not to do it the current way.
My main motivation was to keep the traktor_cue table in the same scheme as the cue table.
If changing the position in the traktor_cue table to double, we could insert the raw value of Traktor and later convert it.
What do you mean with "and user positionMs until it is converted into Mixxx stereo samples playposition"?
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.
Exactly what you wrote before. The fancy stereo sample position is called "playposition" in the Mixxx code base. The traktor position needs an other name,for example positionMs.
What exactly would a double value mean in this case?
If you play a track at 50 % speed for instance, you are able to set a cue point between two samples.
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 changed the way the traktor cues are saved.
Now I keep the native format for the database.
The conversion is done later and in a single position.
This makes the position conversion more easy and future proof.
(Now you only have to change a single line if the playposition is changed to double)
See library/traktor/traktorfeature.cpp | ||
</description> | ||
<sql> | ||
CREATE TABLE IF NOT EXISTS traktor_cues ( |
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.
Please add a comment to the code, how the table will be used.
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 am descriptive in the file now.
Don't know if this is enough.
The transport from Traktor cue to mixxx cue is done the moment the track is imported to the library. |
That makes sense, because once the user is on Mixxx he will never go back :-P |
QXmlStreamAttributes attr = xml.attributes (); | ||
int hotcue = attr.value("HOTCUE").toString().toInt(); | ||
//int position = int(attr.value("START").toString().toFloat()/1000.0 * float(samplerate) * 2.0); | ||
int position = int(attr.value("START").toString().toDouble()/1000.0 * 48000.0 * 2.0); |
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.
Is START a floating point in Traktor? Please add a comment to 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.
Yes it is in the unit of milliseconds.
QString label = attr.value("NAME").toString(); | ||
switch (type) { //TODO | ||
case 0: | ||
type = 1; |
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.
named constants would be nice here.
bool track_already_in_library = m_pTrackCollection->getTrackDAO().trackExistsInDatabase(location); | ||
TrackPointer pTrack = BaseExternalTrackModel::getTrack(index); | ||
|
||
if (pTrack && !track_already_in_library) { |
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 is the check that has to be removed (besides other minor changes) to be able to import changed Traktor cues.
In order to merge this once it is ready, we need your permission. By the way: next time you should create a feature branch in your local repo before starting a new feature. |
Signed it. |
Nevermind, it it might be an issue on your side though. |
Thanks for working on this! |
@uklotzde: I am unsure if it will be better to have the Traktor Cue table temporary. On one hand the track table is persistent, on the other hand this are temporare data. |
Moved the cue code to a seperate file.
Removed unecessary call to cueDAO
What is the status of this PR? It would be great to have this feature in Mixxx 2.2. |
This would be cool! |
Hi, massive investigation ongoing on: |
Owning Mixed in Key I wanted to use it to redo my library of tracks, and import the exported Traktor collection into Mixxx. I will try this PR and see how well it works. It looks like everything is in order for merging, except maybe some conflicts from the state of fork repo... What's the status on this PR? |
Regarding the traktor time shifts, since January we have made significant efforts to understand this issue in detail. The findings are very clear: unless mixxx uses exactly the same mp3 decoder as Traktor, this problem will appear over and over. Traktor uses FHG decoder, Rekordbox uses mpg123 decoder. Please see results and summary in a project about collection conversion from TK to RB:
|
While the decoders are different and differ in the timestamping, the result are shifted timestamps by the same amount, every time. Since we're talking about converting from Traktor to Mixxx, it should simply be a matter of figuring out the delta and correcting when reading (or importing) Traktor cues. Anyway, I would have loved to test this PR, but I can't get a local build going on my machine and the CI builds are too old and have been removed. Is there a way to trigger a build? |
problem definition
The value of the delta is very clear: this is a 26ms frame The problem is that no two mp3 are the same; they have a variety of control headers in the data stream that the decoders may or may not understand. old files correctionAfter months of of investigation we have produced the following correction table for old files.
2019 files correctionUpdate: We now found that using the latest 2019 FFMPEG produces "case D" files that are false positives. |
I've now made a "give me the numbers" summary of our TK->RB investigation. Please find it in this exact comment |
I just took a brief look at the code and I am doubtful about the approach this is using. Why should Mixxx store Traktors' cues in their own table? Why don't we import them into Mixxx's cue table? |
I see that the other external library integrations take this approach too, so this is a bigger issue. I have started a discussion about this on Zulip. |
This PR is marked as stale because it has been open 90 days with no activity. |
This is unrelated to this branch, please use the forum instead. |
yes sorry! i had my wires crossed. |
Incomplete: No support for other cues then "AutoGrid" (type 4 => type 2) and Hotcues (type 0 => type 1) (but it should be easy to add those)
Not tested: Conversion of Traktor "START" time (in ms) to mixxx "position" (in samples).
My Traktor library is generated from a Rekordbox library and those two position formats don't match well.
Thus I could not really test if original Traktor cue point times match (there might be an offset of 1152 samples).