How to override X1MK3 Mapping?
I've gotten my MK3 in time but didnt find the time to try it out yet. Walking through the functions I wanted to re-implement some of my custom overrides from MK2 but it seems not possible to map any button within the MK3 page.
Is this still to come or will I need to use it in midi mode for that? Custom mappings is like THE selling point in Traktor for me...
Just in case you're wondering what I've done in the past:
- have a function to double / half bpm on each track
- switch from internal to dvs control to be able to ride bpm way higher than +/-8% of my turntable for tempo transitions
- change loop-out by beat for those popular 3/4 tempo transitions
- move loop-out marker by encoder for those Swedish House Mafia "One" type effect
- jump to search field
- fix mixer filter, delay filter / rate to specific knobs, set specific values on each param
- select next track in list when loading
I was hoping to utilize the mixer page for further stuff that I find mad... like riding keys...
Best Answer
-
Overmapping capabilities for the x1 is still TBD and going to be added in a future Traktor update.
1
Answers
-
Overmapping capabilities for the x1 is still TBD and going to be added in a future Traktor update.
1 -
... at least ... so I park it or would you say qml modding is a way?
0 -
Depends how willing you are to get into coding without an adequate programming environment providing usable error messages. Simple things (like jumping a line in the browser) are straightforward and easy. Loop out controls are more complex, encompassing for example a calculation of the number of microseconds contained in a single beat depending on the individual track, multiplied by the number (or fraction) of beat(s) in the once case i wanted to go past the 32 beat limit, etc. The plus is that there are fewer constraints than with using the controller editor once it can be used for the x1.
So, it really depends on your requirements and your available time. If you are happy with overmapping available functions in the controller editor, i recommend to wait a bit.
1 -
are there any (unofficial) docs/tuts published somewere? I've seen some example in another post yet didnt find some more specs.
0 -
I haven't found any either. Mainly i learned by reading code (by NI coders and modders) and online qml function lists. I have some previous experience with programming so the basic structure was easy to comprehend.
Edit: Here is one - https://doc.qt.io/qt-6/
1 -
If I may: How do you do more than one function to a button? Just Wire it two times, does that result in a conflict?
0 -
You can wire it twice, or you can use a ButtonScriptAdapter with a 'onPress' and 'onRelease' subsection listing all the assignments you want. Example:
Wire { from: "%surface%.loop.push" to: ButtonScriptAdapter { onPress: { module.coarseTempoStep = true; module.resetTempoEngaged = true; } onRelease: { module.coarseTempoStep = false; if (module.resetTempoEngaged) { // Reset the tempo tempoAdjProp.value = 0.0 } } } }
0 -
Thank you, I've managed to get some of my basic needs covered, which are:
- Play also switches to internal mode, Shift+Play uses dvs relative mode
- Cue now always jumps to 0, Shift+Cue is now tap
- FX Assign buttons now double / halve bpm
I guess that should do the basic stuff for now, I'd like to add in the future:
- Semitone Up/Down for Shift FX Assign: couldnt really find an approach to using these in Native mappings / on the net: any idea?
- Add mixer filter to FX2
- Find a logic for getting my fixed FX params back, lock Delay for FX and specific values for FX1/2/3; use FX3 / Dry Wet, FX4 / Rate
- jump next track upon track load
- Reduce Loop -1 Beat - button still to find; Loop Out Move - Encoder-logic still to find
- jump to search upon a button / encoder press... not too sure which one to take atm
I'd assume that this fine with the EULA as I am only about to "restore the agreed functions of the software purchased" is this a correct assumption?
I have appended a diff just in case it might help somebody (or you have some suggestions :D) Again thank you very much for pushing me into this, seems quite more comfortable than casual mapping... if only there was a documentation of all params :D
diff -bur _new/X1MK3Deck.qml _compare/X1MK3Deck.qml --- _new/X1MK3Deck.qml 2023-10-06 15:43:33.389960100 +0200 +++ _compare/X1MK3Deck.qml 2023-09-13 13:27:30.000000000 +0200 @@ -307,44 +307,31 @@ // FX Assignment AppProperty { id: fxMode; path: "app.traktor.fx.4fx_units" } - AppProperty { id: doubleBPM; path: "app.traktor.decks." + module.deckIdx + ".track.grid.double_bpm" } - AppProperty { id: halfBPM; path: "app.traktor.decks." + module.deckIdx + ".track.grid.half_bpm" } - - // Edit Half / Double BPM FX WiresGroup { enabled: module.active - Wire { from: "%surface%.assign.left"; to: ButtonScriptAdapter { onPress: (halfBPM.value = 1) } } - Wire { from: "%surface%.assign.right"; to: ButtonScriptAdapter { onPress: (doubleBPM.value = 1) } } + + WiresGroup + { + enabled: (fxMode.value == FxMode.TwoFxUnits) || + (!module.shift && (module.fxSectionLayer == FXSectionLayer.fx_primary)) || + ( module.shift && (module.fxSectionLayer == FXSectionLayer.fx_secondary)) + + Wire { from: "%surface%.assign.left"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.1"; color: Color.LightOrange } } + Wire { from: "%surface%.assign.right"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.2"; color: Color.LightOrange } } } + WiresGroup + { + enabled: (fxMode.value == FxMode.FourFxUnits) && + ((!module.shift && (module.fxSectionLayer == FXSectionLayer.fx_secondary)) || + (module.shift && (module.fxSectionLayer == FXSectionLayer.fx_primary))) -// WiresGroup -// { -// enabled: module.active -// -// WiresGroup -// { -// enabled: (fxMode.value == FxMode.TwoFxUnits) || -// (!module.shift && (module.fxSectionLayer == FXSectionLayer.fx_primary)) || -// ( module.shift && (module.fxSectionLayer == FXSectionLayer.fx_secondary)) -// -// Wire { from: "%surface%.assign.left"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.1"; color: Color.LightOrange } } -// Wire { from: "%surface%.assign.right"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.2"; color: Color.LightOrange } } -// } -// -// WiresGroup -// { -// enabled: (fxMode.value == FxMode.FourFxUnits) && -// ((!module.shift && (module.fxSectionLayer == FXSectionLayer.fx_secondary)) || -// (module.shift && (module.fxSectionLayer == FXSectionLayer.fx_primary))) -// -// -// Wire { from: "%surface%.assign.left"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.3"; color: Color.LightOrange } } -// Wire { from: "%surface%.assign.right"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.4"; color: Color.LightOrange } } -// } -// } + Wire { from: "%surface%.assign.left"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.3"; color: Color.LightOrange } } + Wire { from: "%surface%.assign.right"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels." + module.deckIdx + ".fx.assign.4"; color: Color.LightOrange } } + } + } // Browser Browser { name: "browser" } diff -bur _new/X1MK3TransportButtons.qml _compare/X1MK3TransportButtons.qml --- _new/X1MK3TransportButtons.qml 2023-10-06 15:03:50.279879500 +0200 +++ _compare/X1MK3TransportButtons.qml 2023-09-13 13:27:30.000000000 +0200 @@ -33,29 +33,12 @@ SwitchTrigger { name: "sync_inverter" } - // Edit: Absolute/Relative for play / shift+play - SetPropertyAdapter { name: "play_change_internal"; path: "app.traktor.decks." + module.deckIdx + ".playback_mode"; color: Color.Blue; value: PlaybackMode.Internal } - SetPropertyAdapter { name: "play_change_relative"; path: "app.traktor.decks." + module.deckIdx + ".playback_mode"; color: Color.Blue; value: PlaybackMode.Relative } - - WiresGroup - { - enabled: module.active - - WiresGroup - { - enabled: module.active - Wire { from: "%surface%.okay"; to: "play_change_internal" ; enabled: !module.shift} - Wire { from: "%surface%.play"; to: "play_change_relative" ; enabled: module.shift } - } - } - WiresGroup { enabled: module.active - // Edit: Play to absolute / relative, tap to shift cue Wire { from: "%surface%.play"; to: "transport.play" ; enabled: !module.shift } - // Remove: Wire { from: "%surface%.play"; to: "beatgrid.tap" ; enabled: module.shift } + Wire { from: "%surface%.play"; to: "beatgrid.tap" ; enabled: module.shift } Wire { from: "%surface%.sync"; to: "sync_inverter.input" ; enabled: !module.shift } Wire { from: "sync_inverter.output"; to: "transport.sync" ; enabled: !module.shift } @@ -74,14 +57,10 @@ to: "sync_inverter.reset" } - // Remove Cue Functionality, return to zero, tap with shift+cue Wire { from: "%surface%.rev"; to: "transport.flux_reverse" ; enabled: !module.shift } Wire { from: "%surface%.rev"; to: "transport.flux" ; enabled: module.shift } - Wire { from: "%surface%.cue"; to: "beatgrid.tap" ; enabled: module.shift } - // Wire { from: "%surface%.cue"; to: "transport.cue" ; enabled: !module.shift } - Wire { from: "%surface%.cue"; to: "transport.return_to_zero" ; enabled: !module.shift } - // Wire { from: "%surface%.cue"; to: "transport.return_to_zero" ; enabled: module.shift } - Wire { from: "%surface%.cue"; to: "beatgrid.tap" ; enabled: module.shift } + Wire { from: "%surface%.cue"; to: "transport.cue" ; enabled: !module.shift } + Wire { from: "%surface%.cue"; to: "transport.return_to_zero" ; enabled: module.shift } WiresGroup {
1 -
Do you have these?
(Scraped from Traktor.exe):
Type and range are missing, but most are self-explanatory ('X' is almost always the deck number from 1 to 4).
0 -
wohoooo... not until now! thank you! the game has started :D
0 -
The S8/S5/D2 qml files have the biggest number of implementations, so check out those for some ideas as well.
0 -
I've already searched there after you hinted me before :) but having the correct terms might help.
1 -
I've got some more scraped and rather unsorted material somewhere that has helped me in the past. I'll try getting it in shape and throw it up here as well.
1 -
Thanks to your help I was already able to manage most stuff myself, todo is still my remap of:
* Mixer filter to FX2 / On/Off to FX-Button 2 - that should be relatively easy
* Efx 1 Dry/Wet to FX3, Delay Freeze on FX-Button 3, toggle Delay with some default settings on Shift+FX-Button 3 - when I got the logic it shouldnt be a big problem
* I am thinking of creating a Shift2 with the help of FXButton 1 for enabling Encoder 1: Loop Out Move +/- 1, Encoder 2: Loop Out Move Extra Fine - that might be the toughest
Atually during the process I realized that with MK3 the whole interaction starts to lag as Traktor freezes / library flashes appear... Actually that makes the device pretty worthless for me as I mostly use the controller blindly, so if shift is not recognized in time (which it isnt eg. during analyzing) then the controller tends to change loop length before the computer has worked through the fact that shift is enabled... so as fun as this little project is I'd see that as another major design flaw...
0 -
Here is some code i used. You will have to adapt the details (enabled condition, etc.)
// LoopOut Adjust setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.mode"; value: 3 } } // LoopIn Adjust setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.mode"; value: 2 } } // Loop Adjust setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.mode"; value: 1 } } // Beatjump (move) setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.mode"; value: 0 } } // [LoopSize] Move setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.size"; value: 12 } } // 1 beat Move setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.size"; value: 6 } } // xtraFine Move setting Wire { from: "%surface%.encoder.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + deckId + ".move.size"; value: 0 } } // Basic Move Assignment Wire { from: "%surface%.encoder.turn"; to: RelativePropertyAdapter { path: "app.traktor.decks." + deckId + ".move_internal"; step: 1; mode: RelativeMode.Stepped } }
move.mode value 3 is LoopOut, 2 is LoopIn, 1 is Loop, 0 is beatjump
move.size goes from 0-12 and corresponds to the standard move size range in traktor from xtraFine/ 1/64th (i think) at 0 over 1 beat at 6 to 32 beats at 11 and [value=LoopSize] at 12.
This is for use with a stepped encoder, but can be adapted to buttons.
Edit: cleaned the code a bit.
0
Categories
- All Categories
- 19 Welcome
- 1.4K Hangout
- 60 NI News
- 738 Tech Talks
- 3.9K Native Access
- 15.9K Komplete
- 1.9K Komplete General
- 4.2K Komplete Kontrol
- 5.5K Kontakt
- 1.5K Reaktor
- 365 Battery 4
- 817 Guitar Rig & FX
- 419 Massive X & Synths
- 1.2K Other Software & Hardware
- 5.5K Maschine
- 7K Traktor
- 7K Traktor Software & Hardware
- Check out everything you can do
- Create an account
- See member benefits
- Answer questions
- Ask the community
- See product news
- Connect with creators