Skip to content
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

Traktor Kontrol S3 script improvements, vanilla-like FX behavior, control initialization, better scratching, and more #11199

Conversation

robbert-vdh
Copy link
Contributor

Zullip thread

I've been using this for the last couple months and it's been a joy to use. This PR does depend on #11198 and #4651. The former exposes an option that should be enabled for the new vanilla FX behavior to work as intended, and latter is needed to be able to initialize the quick effect/filter knobs. Otherwise the effects are initialized after the control script has finished initializing and they'll be reset to their default values. This PR makes the following changes to the Traktor Kontrol S3 script:

  • There's a new (enabled by default, but the old behavior is still available) effects implementation that closely matches the Traktor Mixer FX behavior that the controller was designed for (see here for a demonstration). The idea is that each channel has one of five quick effect chain presets assigned. Clicking on the Filter button assigns the first quick effect chain preset, and clicking on the FX 1-4 buttons assigns the next four presets. The quick effect chain can then be controlled and toggled using the FX knob and FX On button on each channel. Holding one of the five FX/Filter select buttons and pressing a channel's FX On button will assign the effect to that channel without modifying the other channels. Everything is color coded and the FX buttons are highlighted just like in the video I linked above (which is for the S4 Mk3, but it works exactly the same here). For this to work best the super knob preservation option from Add super knob adoption option for quick effect chain presets #11198 should be enabled, the first quick effect preset chain should be Moog Filter or Filter, and the next four should be that same filter with an additional effect. I've made a couple of those, so if there's a good place to upload them (here?) I can do so and link them in the control script.
  • When starting Mixxx/when reloading the script, Mixxx now queries the current knob positions for the mixer controls from the controller and initializes Mixxx's controls with them. For the filter/quick effect settings to restore correctly this way Only setup controller devices after UI has loaded to prevent control object dependency loop #4651 needs to be merged first.
  • The default deck colors have been flipped to match the colors used in Traktor. Channels 1/2 are now blue, and channels 3/4 are orange by default.
  • The FX On buttons in the new vanilla FX mode follow the quick effect chain preset assignments, but there's an off-by-default option to have them follow the track colors when the Filter/preset 1 has been assigned to the channel. This follows the current behavior, but in my experience using it it can get a bit confusing.
  • Scratching is now implemented using the scratch2 methods and feels much smoother. Previously it would take about a second after releasing the jog wheel before playback started again.
  • Added options (that don't do anything by default) for initializing deck parameters (sync, quantize, key lock, crossfader assignment). This is more part of my personal config so I can easily have the features I always use enabled when I start Mixxx so I can get going immediately. I can remove these options if desired.
  • The halfway point for sliders/knobs is now correctly reported as 0.5. The S3 has an odd number of ticks for those controls, so setting a knob to the neutral position would actually send a value of 0.4998778998778999 to control object instead of 0.5. This would break certain features that explicitly check for 0.5 values, like the filters.
  • The script has been modernized. Explicit prototypes have been replaced by ES6 classes, all uses of var except for the TraktorS3 object have been removed (lots of variables previously used leaked variable bindings), and a custom bind function has been replaced with fn.bind().

The manual still needs to be updated to mention the new FX behavior. Should I just create a PR in the manual repo?

It's trivial to change this back if you prefer the calmer orange colors
for decks 1 and 2, but it seems like a good idea to stay as close to
stock as possible.
I feel like by default it should just behave like everything else and
releasing the jog wheel should immediately resume playback.
I don't see why anyone would want to use this with scratch2 mode.
Instead of the velocity from this manual velocity calculation.
Mixxx already does this internally.
This makes it so Mixxx's initial state matches the S3.
This makes sure no values can be lost.
This behaves as intended by Native Instruments. Only the input parts
have been implemented, the LEDs still need to be done.
This makes more sense to me than keeping whatever was set last time.
This should now be pretty much done.
And don't highlight the unpressed ones. This doesn't look as cool but it
makes it more obvious which ones are active.
This is the same as `loaded_chain_preset`, except that it preserves the
value when changing presets. Bikeshedding over the name is very welcome.
With lexically scoped const/let bindings. The `var TraktorS3 = ...`
needs to stay a var by design.
This would make it impossible to set the quick effect super knob to
exactly 0.5. This is important for some effects like the Moog filter.
I liked the idea, but it quickly becomes confusing once you start
assigning effects to channels.
This is the original S3 behavior and it's probably less confusing.
As the result of mixxxdj#10859 being
merged. Everything shifted up one spot.
@robbert-vdh
Copy link
Contributor Author

There's nothing that really requires it. It's just that without the option it doesn't behave the way you'd expect it to. And without #4651 some settings are not correctly restored from the device's state.

@robbert-vdh
Copy link
Contributor Author

On a side note, I noticed the other day that some of the LED state isn't synchronized when changing between layers. I noticed that the play/pause button blinking didn't match with the new channel just after switching, and there may be other controls that also don't match. I have not yet had the time to look into this.

@ywwg
Copy link
Member

ywwg commented Mar 10, 2023

are those regressions, or is that the same as the current state? As long as the experience on the controller is strictly better with this PR, I'd like to get it in and keep iterating

@robbert-vdh
Copy link
Contributor Author

I haven't tested the current version but I also didn't touch that part of the code (other than transforming the prototypes to ES6 classes), so it shouldn't be a regression.

@ywwg
Copy link
Member

ywwg commented Mar 10, 2023

yeah then I'd be ok pushing this in (along with the manual changes) and then try to get the other issues cleaned up for 2.4. Can you create Issues for the things you've noticed? that way they get tracked

@robbert-vdh
Copy link
Contributor Author

Yeah they're on my personal todo list. I'll get to them (and perhaps open PRs) after I finish a couple other things.

Comment on lines 295 to 296
TraktorS3.incomingData([2, ...Array.from(report2Values.map(x => ~x))]);
TraktorS3.incomingData([2, ...Array.from(report2Values)]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TraktorS3.incomingData([2, ...Array.from(report2Values.map(x => ~x))]);
TraktorS3.incomingData([2, ...Array.from(report2Values)]);
TraktorS3.incomingData(new Uint8Array([2, ...Uint8Array.from(report2Values.map(x => ~x))]));
TraktorS3.incomingData(new Uint8Array([2, ...Uint8Array.from(report2Values)]));

When incomingData is called from C++, the argument is an array of type Uint8Array. The same type should be used here too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Mar 14, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
@robbert-vdh
Copy link
Contributor Author

robbert-vdh commented Mar 14, 2023

Oh yeah, there's one other thing I was wondering about with this mapping. This line from the previous version of the script creates a link from the [ChannelN],scratch2_enable control object to change the a deck's lighting. Mixxx warns that this control object doesn't actually exist. Was this added in error or was the control object renamed at some point? I think I did a quick git pickaxe search at one point but that didn't turn up anything particularly interesting.

https://github.com/robbert-vdh/mixxx/blob/93fa58a12884998260a2bb91cb3858d5533113d1/res/controllers/Traktor-Kontrol-S3-hid-scripts.js#L1477

// just tell the packet parser the current values so it won't ignore the
// next input.
const report1Values = new Uint8Array(controller.getInputReport(1));
TraktorS3.incomingData([1, ...Array.from(report1Values)]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TraktorS3.incomingData([1, ...Array.from(report1Values)]);
TraktorS3.incomingData(new Uint8Array([1, ...Uint8Array.from(report1Values)]));

This should also be Uint8Array

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The HID parser previously accepted both regular arrays and Uint8Array but after #4894 it only accepts Uint8Arrays.

As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
@robbert-vdh robbert-vdh force-pushed the feature/traktor-kontrol-s3-script-improvements branch from 93fa58a to 29bfd1d Compare March 28, 2023 11:16
robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Mar 28, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
robbert-vdh added a commit to robbert-vdh/mixxx-manual that referenced this pull request Apr 7, 2023
@ywwg
Copy link
Member

ywwg commented Apr 10, 2023

thanks for working on the docs!

robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Apr 11, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Apr 27, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
robbert-vdh added a commit to robbert-vdh/mixxx-manual that referenced this pull request Apr 28, 2023
robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Jun 1, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
@JoergAtGithub
Copy link
Member

As far as I can see the changes to the FX behavior block merging this PR since a while. Would it make sense to move th FX changes to a follow-up PR and merge the other improvements into 2.4?

@robbert-vdh
Copy link
Contributor Author

Without the option from #11198 this would still work. It could just lead to some slightly confusing behavior if you've ever used Pioneer, Denon, NI, or other DJ gear with channel FX selectors before.

@JoergAtGithub
Copy link
Member

@ywwg What is needed to get this merged?

robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Jun 27, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
robbert-vdh added a commit to robbert-vdh/mixxx that referenced this pull request Jul 15, 2023
As suggested in
mixxxdj#11199 (comment). The
function does accept both typed arrays and plain arrays.
robbert-vdh added a commit to robbert-vdh/mixxx-manual that referenced this pull request Jul 16, 2023
@JoergAtGithub
Copy link
Member

Merge this without the super-knob default PR, because this is independent: #11198 (comment)
The text section in the manual PR got adjusted therefore.
Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants