Skip to content

Dynamic encoders

Encoders in zcx can be mapped to a variety of targets. By using templating we can define many targets at once.

These examples will use the encoders enc_1 through enc_8 in a group. If you're not sure what names to use, check the hardware reference. You may use a different number of encoders, but you may have to tweak some of the values.

Controlling the selected device

By using template strings and targeting best-of-bank device parameters we can control the first eight parameters on any device with only four lines of yaml:

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding: >
    DEV(SEL) B1 P${me.Index}

By adding a shift mode we can access the next eight parameters:

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding:
    default: >
      DEV(SEL) B1 P${me.Index}
    __shift: >
      DEV(SEL) B2 P${me.Index}

Controlling the selected track

Compact mode

This config give us access to the track's volume, pan, first two sends, and first four parameters on the selected device. With the shift mode active we get access to the next two sends and the next four device parameters. In this scenario it's easier to ungroup the first four encoders, but it's possible to keep them grouped if you'd prefer.

encoders.yaml
enc_1:
  binding: >
    SEL / VOL

enc_2:
  binding: >
    SEL / PAN

enc_3:
  binding:
    default: >
      SEL / SEND A
    __shift: >
      SEL / SEND B

enc_4:
  binding:
    default: >
      SEL / SEND C
    __shift: >
      SEL / SEND D

__device_encoders:
  includes: [enc_5, enc_6, enc_7, enc_8]
  binding:
    default: DEV(SEL) B1 P${me.Index}
    __shift: DEV(SEL) B1 P${me.Index + 4}

Sends

This config give us access to the track's first eight sends:

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding: >
    SEL / SEND ${me.index}

Mix mode

In this mode we have access to the track's volume, pan, and first six sends. With shift active we get access to the track's left and right split-stereo panning and the next six sends:

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding:
    default: >
      SEL / SEND ${send_num(me.index - 2)}
    __shift: >
      SEL / SEND ${send_num(me.index - 2 + 6)}
  encoders:
    enc_1:
      binding:
        default: >
          SEL / VOL
        __shift: >
          SEL / PANL
    enc_2:
      binding:
        default: >
          SEL / PAN
        __shift: >
          SEL / PANR

Controlling ring tracks

By using the RING() syntax we can target tracks inside the session ring. Any track target can be used with the RING() syntax:

Volume

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding: >
    RING(${me.index}) / VOL

Pan

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding: >
    RING(${me.index}) / PAN

Sends

encoders.yaml
__encoder_group:
  includes: [enc_1, enc_2, enc_3, enc_4, enc_5, enc_6, enc_7, enc_8]
  binding:
    default: >
      RING(${me.index}) / SEND A
    __shift: >
      RING(${me.index}) / SEND B

See also