Generated -- do not hand-edit. This file is rendered from the address
map along with Chataigne_Module.mcfg, module.json and the address
constants in liberation.js, so it cannot drift from what the config
actually contains.
This module works as a virtual control surface: Chataigne sends and
receives the exact note and CC numbers that Chataigne_Module.mcfg maps to
Liberation actions. All channels are 1-based.
- A channel is a feature domain, never an index. A family with 128 or fewer members is addressed by note/CC number, not by channel. (v1 used channel-per-clip-property and channel-per-zone; both are gone.)
- Blocks. Within a family,
address = role * STRIDE + index. Blocks never straddle a channel boundary, sochannel = base + role / blocks_per_channelandcc = (role mod blocks_per_channel) * STRIDE + index. - A family occupies a contiguous channel range, and its note family lives on the range's first channel alongside its first CC block. Notes and CCs are separate namespaces, so pairing them costs nothing.
fine/LSB is always explicit. Never rely on thecc + 32default: at stride 32 or 40 it lands inside the neighbouring block. Same forenable_cc, whosecc + 8default caused a real collision in v1.- Channel 1 holds only singletons and small fixed sets. No large grids.
- Display indices are 1-based, wire indices are 0-based. Everything in
this file is a wire index.
module.jsonnames and command parameters are 1-based for slot families (effects, effect params, zones, groups, general params) and 0-based for grid coordinates (clip X/Y, absolute clip X, clip pages).liberation.jsconverts once, at the MIDI boundary.
| Ch | Domain | Notes in use | CCs in use |
|---|---|---|---|
| 1 | Global surface (transport, status, modifiers, paging, groups, zones, general params, global continuous, match LEDs) | 0-20, 24-37, 40-44, 48-71, 96-103 | 0-25 |
| 2 | Clips - relative (notes + clip property blocks) | 0-39 | 0-119 |
| 3 | Clips - relative (continued) | - | 0-119 |
| 4 | Clips - relative (continued) | - | 0-119 |
| 5 | spare - adjacent growth for relative clip properties | - | - |
| 6 | Clips - absolute | 0-79 | - |
| 7 | spare - adjacent growth for absolute clip properties | - | - |
| 8 | Effects - bank-relative (notes + level + parameter blocks) | 0-23 | 0-23, 32-55, 64-87, 96-119 |
| 9 | Effects - bank-relative (reserved for params 3-9) | - | - |
| 10 | Effects - bank-relative (reserved for params 3-9) | - | - |
| 11 | Effects - absolute (notes + level + parameter blocks) | 0-39 | 0-119 |
| 12 | Effects - absolute (continued) | - | 0-39 |
| 13 | spare | - | - |
| 14 | spare | - | - |
| 15 | Fine / LSB pool | - | 0-2, 4-7, 24 |
| 16 | spare | - | - |
Channels carrying traffic: 1, 2, 3, 4, 6, 8, 11, 12, 15. Everything else is free or reserved.
| Note | Binding |
|---|---|
| 0 | tap_tempo |
| 1 | play_pause |
| 2 | toggle_record |
| 3 | stop_all_clips |
| 4 | reset_bar |
| 5 | beat_led (output only) |
| 6 | bar_led (output only) |
| 7 | tempo_multiplier_toggle + led |
| 8 | tempo_nudge_back, note_onoff |
| 9 | tempo_nudge_forward, note_onoff |
| 10 | disarm_all |
| 11 | arm_all -- own note now, no Shift modifier needed |
| 12 | toggle_alt_zones -- own note now, no Alt modifier needed |
| 13 | status_led lasers (output only) |
| 14 | status_led play (output only) |
| 15 | status_led record (output only) |
| 16 | shift |
| 17 | alt_press, note_onoff |
| 18 | clip_zone_delay_chase_toggle + led |
| 19 | clip_zone_delay_chase_mode_cycle + led (velocity-coded: delay=0, chase=127, both=64) |
| 20 | clip_zone_delay_chase_retrigger_toggle + led |
| 24-31 | clip_page 0-7 (absolute) |
| 32 / 33 | clip_page_shift -1 / +1 |
| 34 / 35 | effect_page_shift -1 / +1 |
| 36 / 37 | zone_offset_relative -8 / +8 |
| 40-44 | group 0-4 + led |
| 48-71 | Zones, note = 48 + role * 8 + zone: 48-55 zone, 56-63 zone_flip_x, 64-71 zone_flip_y |
| 96-127 | general_param_match_led presets (32 slots reserved, 8 used) |
| CC | Binding |
|---|---|
| 0-9 | general_param 0-9 coarse |
| 10-19 | general_param enable lanes, set explicitly -- the cc + 8 default would collide (see below) |
| 20 | change_tempo_relative, type=cc_relative |
| 21 | clip_offset_x_relative, type=cc_relative |
| 22 | effect_offset_x_relative, type=cc_relative |
| 23 | effect_offset_y_relative, type=cc_relative |
| 24 | tempo_multiplier + tempo_multiplier_level_led, fine (LSB ch 15 cc 24) |
| 25 | global_brightness |
clip x y, note = 0 + y * 8 + x (notes 0-39), with led.
clip_abs, fixed position: does not move when the deck scrolls. Press,
release and led only -- clip_property_abs is reserved (CC 0-119 on the
same channel) but not yet emitted.
note = 0 + page * 40 + y * 8 + localX; notes 0-39 are page 1
(absolute columns 0-7), 40-79 are page 2 (columns 8-15).
LED feedback reuses the clip_led_mode / clip_led_group config declared
once for the relative block; the scheme is global, not per-directive.
Block-addressed: cc = (role mod 3) * 40 + clip index,
ch = 2 + role / 3. Grid-relative, like clip press/release.
| Property | param= |
Role | Ch | CC range | led |
|---|---|---|---|---|---|
| Shift X | shift_x |
0 | 2 | 0-39 | no (write-only) |
| Shift Y | shift_y |
1 | 2 | 40-79 | no (write-only) |
| Scale X | scale_x |
2 | 2 | 80-119 | yes |
| Scale Y | scale_y |
3 | 3 | 0-39 | yes |
| Zone Delay | zone_delay |
4 | 3 | 40-79 | no (write-only) |
| Chase Pattern | chase_pattern |
5 | 3 | 80-119 | yes |
| Transition In | transition_in |
6 | 4 | 0-39 | no (write-only) |
| Transition Out | transition_out |
7 | 4 | 40-79 | no (write-only) |
| Custom | custom |
8 | 4 | 80-119 | yes |
Shift X/Y and Zone Delay are write-only here; their feedback comes from
general_param 0-2, which reflects the selected clip at 14-bit
resolution and needs no X/Y. The per-cell write path stays because
general_param can only ever target the selected clip.
Press/release + led: note = 0 + lane (notes 0-23).
Continuous controls are block-addressed at stride 32 (24 lanes, 8 spare per
block), 4 blocks per channel: cc = (role mod 4) * 32 + lane.
| Role | Directive | Ch | CC range | Status |
|---|---|---|---|---|
| 0 | effect_level |
8 | 0-23 | emitted |
| 1 | effect_parameter param=1 |
8 | 32-55 | emitted |
| 2 | effect_parameter param=2 |
8 | 64-87 | emitted |
| 3 | effect_parameter param=3 |
8 | 96-119 | emitted |
| 4 | effect_parameter param=4 |
9 | 0-23 | reserved |
| 5 | effect_parameter param=5 |
9 | 32-55 | reserved |
| 6 | effect_parameter param=6 |
9 | 64-87 | reserved |
| 7 | effect_parameter param=7 |
9 | 96-119 | reserved |
| 8 | effect_parameter param=8 |
10 | 0-23 | reserved |
| 9 | effect_parameter param=9 |
10 | 32-55 | reserved |
| 10 | effect_parameter param=10 |
10 | 64-87 | reserved |
Addressed by linear slot index 0-39, not x/y. Fixed position: unaffected by the current effect bank.
Press/release + led: note = 0 + slot (notes 0-39) on channel 11.
| Role | Directive | Ch | CC range | Status |
|---|---|---|---|---|
| 0 | effect_level_abs |
11 | 0-39 | emitted |
| 1 | effect_parameter_abs param=1 |
11 | 40-79 | emitted |
| 2 | effect_parameter_abs param=2 |
11 | 80-119 | emitted |
| 3 | effect_parameter_abs param=3 |
12 | 0-39 | emitted |
| 4 | effect_parameter_abs param=4 |
12 | 40-79 | reserved |
| 5 | effect_parameter_abs param=5 |
12 | 80-119 | reserved |
Coarse on channel 1 CC 0-9. Indices 0, 1, 2, 4, 5, 6, 7 carry fine, with the LSB on
channel 15 at the same CC number. Index 3 (chase_pattern, 4 discrete
values) and 8-9 (unassigned) stay 7-bit.
The Liberation meaning of each slot is fixed and built in, not assignable.
| Index | CC | Liberation target | Scope | fine |
Chataigne value |
|---|---|---|---|---|---|
| 0 | 0 | shift_x |
selected clip | yes, ch 15 cc 0 | Integer -200..200 |
| 1 | 1 | shift_y |
selected clip | yes, ch 15 cc 1 | Integer -200..200 |
| 2 | 2 | zone_delay |
selected clip | yes, ch 15 cc 2 | Integer 0-128 |
| 3 | 3 | chase_pattern |
selected clip | no | Integer 1-4 |
| 4 | 4 | global_spin |
global | yes, ch 15 cc 4 | Float -20.0..20.0, 0.1 steps |
| 5 | 5 | global_spin_3d |
global | yes, ch 15 cc 5 | Float -20.0..20.0, 0.1 steps |
| 6 | 6 | global_scale_x |
global | yes, ch 15 cc 6 | Integer 0-100 |
| 7 | 7 | global_scale_y |
global | yes, ch 15 cc 7 | Integer 0-100 |
| 8 | 8 | unknown |
- | no | Float 0-1 (raw) |
| 9 | 9 | unknown |
- | no | Float 0-1 (raw) |
Slots 0-3 are built-in aliases for the selected clip. Slots 4-7 are a
separate, global feature -- global_scale_x/y is not clip scale_x/y.
They also mirror into the friendlier Global Transformations container.
general_param ... led auto-creates an enable/exists feedback CC that
defaults to cc + 8. In v1 that put outputs on channel 1 CC 8-17,
colliding with general_param 8-9 and effect_level 0-7, which could
receive spurious values. All ten lines now set enable_cc explicitly
(CC 10-19), and the collision check expands this default so it fails on
any recurrence.
general_param_match_led lights a note LED only while general_param 2
(zone_delay, selected clip) matches a target normalized value. Read-only:
a match LED reflects state, it cannot be pushed to a value.
Channel 1, note = 96 + preset index, float = value / 128,
tolerance=0.0005 (hand-tuned and validated against real Liberation output --
exact 0.0 matching did not fire reliably).
| Value (of 128) | float |
Note |
|---|---|---|
| 2 | 0.015625 | 96 |
| 4 | 0.03125 | 97 |
| 6 | 0.046875 | 98 |
| 8 | 0.0625 | 99 |
| 10 | 0.078125 | 100 |
| 12 | 0.09375 | 101 |
| 16 | 0.125 | 102 |
| 24 | 0.1875 | 103 |
off=0 sends a Note On with velocity 0 rather than a literal Note Off, so
the usual velocity > 0 convention already covers both states.
clip_led_mode velocity, one swatch per Liberation clip group.
CLIP_VEL_ACTIVE in liberation.js must list every active value below --
a group missing from that array stays stuck at false on every Note On.
This is enforced automatically on every regeneration.
| Group | idle | active | pressed |
|---|---|---|---|
| 0 | 35 | 90 | 3 |
| 1 | 10 | 60 | 3 |
| 2 | 13 | 15 | 3 |
| 3 | 29 | 62 | 3 |
| 4 | 28 | 63 | 3 |
Empty slots send 0. The pressed velocity is transient and ignored by the
script so it cannot flicker the Boolean before the stable state arrives.
Every regeneration runs four checks:
- Address collisions -- the emitted
.mcfgis parsed and every address Liberation derives implicitly (fineatcc + 32,enable_ccatcc + 8,ledauto-outputs) is expanded before checking for duplicates, per direction, treating Shift/Alt-gated bindings as distinct. - Generated files match disk for the
.mcfg,module.jsonand the generated constants block inliberation.js. - Cross-file consistency -- command callbacks exist, parameter counts
match the JS arity, every
getChildname resolves, clip LED velocities agree. - Round-trip execution -- the real script is run against a stubbed Chataigne API, asserting the exact bytes each command emits and which Value each incoming message sets, against addresses derived from the map by a separate code path. This is the only check that catches an off-by-one in the 1-based display index.
Notes and CCs are separate MIDI namespaces, so the same number on the same channel never collides across message types.
clip_property_abs-- address space reserved on channel 6, not emitted.pitch_bendmessage-type variants for continuous controls.- Per-cell clip property feedback Values for all 40 clips (360 entries);
feedback stays scoped to
Current Clip. fineonclip_propertyand on the genericSet General Param, which is a raw 7-bit passthrough by design.general_param8-9, whose Liberation targets are unknown.