Skip to content

Latest commit

 

History

History
292 lines (237 loc) · 12.4 KB

File metadata and controls

292 lines (237 loc) · 12.4 KB

Liberation <-> Chataigne address map (v2)

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.

Organizing rules

  • 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, so channel = base + role / blocks_per_channel and cc = (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 the cc + 32 default: at stride 32 or 40 it lands inside the neighbouring block. Same for enable_cc, whose cc + 8 default 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.json names 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.js converts once, at the MIDI boundary.

Channel allocation

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.

Channel 1 -- global surface

Notes

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)

CCs

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

Clips

Relative (8 x 5) -- channel 2

clip x y, note = 0 + y * 8 + x (notes 0-39), with led.

Absolute (2 pages x 8 x 5 = 80) -- channel 6

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.

Clip properties (9 types x 40 clips = 360 controls)

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.

Effects

Bank-relative (24 lanes) -- channel 8

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

Absolute (40 slots) -- channels 11-12

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

General params (10)

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.

enable_cc (fixed in v2)

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.

Zone Delay Matching (8 read-only presets)

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 velocities

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.

Collision check

Every regeneration runs four checks:

  1. Address collisions -- the emitted .mcfg is parsed and every address Liberation derives implicitly (fine at cc + 32, enable_cc at cc + 8, led auto-outputs) is expanded before checking for duplicates, per direction, treating Shift/Alt-gated bindings as distinct.
  2. Generated files match disk for the .mcfg, module.json and the generated constants block in liberation.js.
  3. Cross-file consistency -- command callbacks exist, parameter counts match the JS arity, every getChild name resolves, clip LED velocities agree.
  4. 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.

Deliberately left out

  • clip_property_abs -- address space reserved on channel 6, not emitted.
  • pitch_bend message-type variants for continuous controls.
  • Per-cell clip property feedback Values for all 40 clips (360 entries); feedback stays scoped to Current Clip.
  • fine on clip_property and on the generic Set General Param, which is a raw 7-bit passthrough by design.
  • general_param 8-9, whose Liberation targets are unknown.