How to override X1MK3 Mapping?

Anselm.
Anselm. Member Posts: 30 Member
edited February 29 in Mapping Traktor

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

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod
    Answer ✓

    Overmapping capabilities for the x1 is still TBD and going to be added in a future Traktor update.

«1

Answers

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod
    Answer ✓

    Overmapping capabilities for the x1 is still TBD and going to be added in a future Traktor update.

  • Anselm.
    Anselm. Member Posts: 30 Member

    ... at least ... so I park it or would you say qml modding is a way?

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod

    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.

  • Anselm.
    Anselm. Member Posts: 30 Member

    are there any (unofficial) docs/tuts published somewere? I've seen some example in another post yet didnt find some more specs.

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod
    edited October 2023

    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/

  • Anselm.
    Anselm. Member Posts: 30 Member

    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?

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod

    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
             }
           }
         }
       }
    


  • Anselm.
    Anselm. Member Posts: 30 Member
    edited October 2023

    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
         {
    
    
    
    
  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod

    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).

  • Anselm.
    Anselm. Member Posts: 30 Member

    wohoooo... not until now! thank you! the game has started :D

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod

    The S8/S5/D2 qml files have the biggest number of implementations, so check out those for some ideas as well.

  • Anselm.
    Anselm. Member Posts: 30 Member

    I've already searched there after you hinted me before :) but having the correct terms might help.

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod

    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.

  • Anselm.
    Anselm. Member Posts: 30 Member

    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...

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 2,518 mod
    edited October 2023


    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.

Back To Top