X1MK3: Community Performance MOD (qml coding)

13738394042

Comments

  • spinlud
    spinlud Member Posts: 36 Member

    Actually I was suggesting a different behaviour:

    First knob/button → High & Mid

    means that you are controlling High & Mid at the same time, no SHIFT button required.

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod

    I see. I should make a complete overhaul then, so that every position can be customized in this way and the other with a combination of two parameters, at the same time or separated by the SHIFT layer. That sounds like a project for another update. :)

  • spinlud
    spinlud Member Posts: 36 Member

    o_O sounds complicated!

    For now I have just edited these lines in X1MK3FXSectionSide.qml for all decks , it seems to do the trick 😆:

    Wire { enabled: !shift; from: "softtakeover1.output"; to: ValuePropertyAdapter { path: "app.traktor.mixer.channels.1.eq.high"; ignoreEvents: PinEvent.WireEnabled | PinEvent.WireDisabled } }

    Wire { enabled: !shift; from: "softtakeover1.output"; to: ValuePropertyAdapter { path: "app.traktor.mixer.channels.1.eq.mid"; ignoreEvents: PinEvent.WireEnabled | PinEvent.WireDisabled } }


    Wire { enabled: !shift; from: "%surface%.buttons.1"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels.1.eq.kill_high"; color: Color.Blue } }

    Wire { enabled: !shift; from: "%surface%.buttons.1"; to: TogglePropertyAdapter { path: "app.traktor.mixer.channels.1.eq.kill_mid"; color: Color.Turquoise } }

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod

    Yup. It's just the grouping according to several variables that makes the structure more complicated. And then doing it again for the screen feedback. Well, you now have a quick solution. Good for you! 😉

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod
    edited June 12

    UPDATE: X1MK3 - Community Performance MOD Version 11 TP 4.2.0 :

    New Features:

    • If deck is synced (and the global clock is tempo master), SYNC(Hold)+LoopEncoder(Turn) adjusts clock BPM. SYNC(Hold)+LoopEncoder(Push) will reset clock BPM to track base BPM.
    • Engaging Cue Monitor for one channel automatically deactivates Cue Monitor for the other three channels. This is a global effect for the software and works not just on the X1, as long as a mapping file for the X1 is loaded. A custom toggle for this behaviour is in setup.
    • Optional BeatsToCue display instead of Remaining Time. Time display will be visible on SHIFT layer in the top left corner of KEY display.
    • 3 page Setup for custom toggles.

    New Stem/Remix Controls:

    • SHIFT+Loop Encoder (Turn): Select Capture Source (Screen Feedback)
    • SHIFT+Loop Encoder (Push): Toggle Quantization
    • SHIFT+Loop Encoder (Push)+Loop Encoder(Turn): Adjust Quantization (Screen Feedback)
    • Additional Quantization Display on Screen when holding SHIFT. FX Buttons control Stem/Remix channel Mute (FX Send with SHIFT).
    • Capture Source and Quantization do not work when LegacyEncoder + Beatjump/Move is set for SHIFT+Loop Encoder. You have to select Key Adjust for the SHIFT+Loop Encoder. This is done automatically if you use Browser Mode.
    • Remix Deck Beat Counter.

    Edit: I updated page 1 with the new 3-page setup and all the changes. Next will be a mini update for a MinimalMod with BeatsToCue. I also expanded the credits section. If i failed to mention your contribution, please send me a pm. Credit where credit is due.

  • pixel
    pixel Member Posts: 418 Pro
    edited June 17

    Great😎, your mod made me realize that I need a second X1.😄

  • DjShene
    DjShene Member Posts: 1 Newcomer

    Good day! It does not work with my Traktor 4.2.0 34. I replaced files but when I opened program x1 does not wake up. Mode button is on only. Thanks!

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod

    Try this:

    1. return the qml files to their original 4.2 state.
    2. test if it works now (default mapping); if not, there is your problem.
    3. now put the mod files on top. Your OS will ask to replace 15 files.
    4. test if it works now.
  • spinlud
    spinlud Member Posts: 36 Member
    edited June 19

    Hi, I am trying to assign loop in/out functionality to the shift+encoders push (instead of the key lock).

    First attempt:

    WiresGroup
    {
    enabled: module.shift && !browserModeProp.value
    Wire { from: "%surface%.loop.push"; to: "loop.in" } Wire { from: "%surface%.browse.push"; to: "loop.out" }
    }

    Problems: loop in works but for all decks, instead of the specific deck; loop out does not work at all.

    Other attempts:

    WiresGroup
    {
      enabled: module.shift && !browserModeProp.value
      Wire { from: "%surface%.loop.push"; to: "app.traktor.decks." + module.deckIdx + ".loop.set.in" }     
      Wire { from: "%surface%.browse.push"; to: "app.traktor.decks." + module.deckIdx + ".loop.set.out" }
    }
    
    WiresGroup
    {
      enabled: module.shift && !browserModeProp.value
      Wire { from: "%surface%.loop.push"; to: TogglePropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.set.in" } }    
      Wire { from: "%surface%.browse.push"; to: TogglePropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.set.out" } }
    }
    

    Not working at all and crash 😅

    Any hint?

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod

    Use 'TriggerPropertyAdapter' or the general and most versatile of them all, 'ButtonScriptAdapter'. I'll post a few examples soon.

  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod

    Here are the triggers i used for the S4:

    Wire { from: "%surface%.record"; to: TriggerPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.set.in"; output: false } }
    Wire { from: "%surface%.record"; to: ButtonScriptAdapter { onPress: brightness = 1.0; onRelease: brightness = 0.0; brightness: 0.0 } }
    Wire { from: "%surface%.mute"; to: TriggerPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.set.out"; output: false } }
    Wire { from: "%surface%.mute"; to: ButtonScriptAdapter { onPress: brightness = 1.0; onRelease: brightness = 0.0; brightness: 0.0 } }
    

    If you set output to 'true' (or leave it out) you can dispense with the ButtonScriptAdapters i only used to override the LED's because the LED's are also triggered by other functions.

    The first attempt looks correct. Not sure what the problem is. The third attempt fails because setting the loop markers is not a toggle but a trigger.

    You may have caused a syntax error somewhere else in the code. Revert to a working (not crashing) baseline and restart your attempts from there.

  • spinlud
    spinlud Member Posts: 36 Member

    Thank you! I was just playing with TriggerPropertyAdapter and it solved the issue:

      WiresGroup {
        enabled: module.active
    
        WiresGroup {
          enabled: module.shift && !module.syncModifier && !browserModeProp.value
          
          Wire { from: "%surface%.browse.push";   to: TriggerPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.set.in"; output: false } }
          Wire { from: "%surface%.loop.push";   to: TriggerPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.set.out"; output: false } }
        }
      }   
    

    I have moved enable/disable key lock feature to SYNC+SHIFT+LOOP_PUSH (instead of SHIFT+LOOP_PUSH):

    WiresGroup
        {      
          // enabled: module.shift && !browserModeProp.value && customBrowserModeProp.value && (deckTypeProp.value != DeckType.Remix)
          enabled: module.shift && module.syncModifier && !browserModeProp.value && customBrowserModeProp.value && (deckTypeProp.value != DeckType.Remix)
          Wire { from: "%surface%.loop"; to: "key_control.coarse"; }
        }
    

    Not sure about this part though, it doesn't seem to do anything so I left it unchanged:

    WiresGroup
        {
          // enabled: module.shift
          enabled: module.shift && !browserModeProp.value && !customBrowserModeProp.value
    
          Wire { from: "%surface%.loop"; to: "loop.move"; enabled: loopShiftAction == beatjump_loop }
          // Wire { from: "%surface%.loop"; to: "key_control.coarse"; enabled: (loopShiftAction == key_adjust) }
          Wire { from: "%surface%.loop"; to: "key_control.coarse"; enabled: (loopShiftAction == key_adjust) && (deckTypeProp.value != DeckType.Remix) }
        }
    

    I have also disabled the CUP trigger on SHIFT+BROWSE_PUSH to avoid conflict:

    WiresGroup {
            enabled:  module.shift
            Wire { from: "%surface%.browse.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".move.size"; value: 6 } } // Move Size = 1 Beat
            Wire { from: "%surface%.browse.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".move.mode"; value: 0 } enabled: !loopActiveProp.value || ( activeCueTypeProp.value != 5 ) } // Move
            Wire { from: "%surface%.browse.is_turned"; to: SetPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".move.mode"; value: 1 } enabled: loopActiveProp.value && ( activeCueTypeProp.value == 5 ) } // Move Loop
            Wire { from: "%surface%.browse.turn"; to: RelativePropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".move_internal"; step: 1; mode: RelativeMode.Stepped } }
            // Wire { from: "%surface%.browse.push";   to: TriggerPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".cup"; output: false } }
            Wire { from: "%surface%.browse.push";   to: SetPropertyAdapter { path: "app.traktor.decks." + module.deckIdx + ".loop.active"; value: true; output: false } enabled: ( activeCueTypeProp.value == 5 ) }
          }
    
  • spinlud
    spinlud Member Posts: 36 Member

    Ah for adding beat counter with phrase_length=0, something like this mixing your and mine implementation could do the trick I think:

    function computeBarsBeatsFromPosition(beat) {
        // phrase.bars.beats
        if (customBeatCounterPhraseLength > 0) {
          var phraseLen   = Math.pow (2, customBeatCounterPhraseLength) // 8 // 4
          var rawInt      = parseInt(beat+0.0001); //value 0.0001 to counter rounding error offset
          var prefix      = (beat < 0) ? "-" : " ";    
          var absBeats    = Math.abs(rawInt);    
          var phrases     = parseInt(absBeats / (phraseLen * 4) ) + 1; 
          var bars        = parseInt((absBeats / 4) % phraseLen) + 1;
          var phrasesBars = (customBeatCounterPhraseLength == 0) ? phrases + "." : phrases + "." + bars + "."
          var beatInBar   = parseInt(absBeats % 4) + 1;
          // return prefix + phrases + "." + bars + "." + beatInBar;
          return prefix + phrasesBars + beatInBar;  
        }
        // bars.beats
        else {
          var sign = (beat < 0) ? "-" : "";
          var nearestBeat = Math.abs(Math.round(beat));
          var bars = Math.ceil(nearestBeat / 4);
          var beatInBar = (nearestBeat - 1) % 4 + 1;
          return sign + bars + "." + beatInBar;  
        }    
      }
    
  • Sûlherokhh
    Sûlherokhh Member, Traktor Mapping Mod Posts: 3,596 mod

    Happy to hear you managed to get it to work. The part you are not sure about is about adjusting quantization for remix decks (done somewhere else) when using LegacyEncoderMode instead of the browser mode.

    I used Phrase Length = 1 (in code: it's Math.pow (2, 0), meaning 2 to the power of 0 equals 1) to remove Phrase completely.

    So, the in-code integer values of Phrase Length are, 0, 1, 2, 3, 4, 5, which convert to the actual count of 1, 2, 4, 8, 16, 32.

    With value 0 (Phrase Length 1), the segment for Phrase Length Text on screen will be left out.

  • spinlud
    spinlud Member Posts: 36 Member

    Ah ok great! I saw 1 as minimum in the setup so I thought phrase length 0 was still not supported 😅

    What do you think about this loop in/out mapping and moving key lock to another combination, makes sense?

Back To Top