2026-11-06 15:20:20 +01:00
|
|
|
|
# Automation and Expressive Control
|
2026-10-27 06:25:30 +01:00
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
Track Gain/Pan lanes in the Mixer apply to audio and scheduled instrument
|
|
|
|
|
|
voices. They use absolute project ticks, linear or hold interpolation,
|
|
|
|
|
|
hold-first/last outside points and the constant project tempo snapshot. A clip
|
|
|
|
|
|
trim/move does not move track or effect automation: lanes belong to the project
|
|
|
|
|
|
timeline. Instrument volume is controlled by its track Gain lane; the current
|
|
|
|
|
|
sine has no timbre parameter. Track gain ramps and boundary fades are described
|
|
|
|
|
|
in AUDIO_QUALITY.md.
|
2026-10-27 06:25:30 +01:00
|
|
|
|
|
|
|
|
|
|
Select a LADSPA node in Modular Graph and use Edit/Selected plugin automation.
|
2026-11-06 15:20:20 +01:00
|
|
|
|
Enter `port tick mode value`: mode 0 interpolates linearly, 1 holds until the
|
|
|
|
|
|
next point, and -1 removes the point at that port/tick (value ignored). Port
|
|
|
|
|
|
names, ranges and current tick are displayed. There are at most 32 points per
|
|
|
|
|
|
plugin; setting an existing port/tick replaces it. Integer/toggle controls
|
|
|
|
|
|
require step mode. Invalid values, ticks, ports or duplicate persisted points
|
|
|
|
|
|
reject the edit or file. Edits are undoable and rebuild on the control thread
|
|
|
|
|
|
while stopped.
|
2026-10-27 06:25:30 +01:00
|
|
|
|
|
|
|
|
|
|
Effect lanes use the project tempo, hold first/last outside their range and
|
|
|
|
|
|
apply before run at each exact sample. Distinct ticks rounding to one sample
|
|
|
|
|
|
resolve to the later tick. Linear curves avoid stepping continuous controls;
|
|
|
|
|
|
intentional step curves may click. The initial implementation calls run(1) while
|
2026-11-06 15:20:20 +01:00
|
|
|
|
any lane exists, with connected preallocated buffers. CPU cost can be
|
|
|
|
|
|
significant; only the documented LADSPA set is qualified. No worker, allocator,
|
|
|
|
|
|
loader or clock is called from the host audio path. Native ABI 2 callers
|
|
|
|
|
|
continue to use sample-offset parameter events, applied before equal-offset MIDI
|
|
|
|
|
|
events.
|
2026-10-27 06:25:30 +01:00
|
|
|
|
|
|
|
|
|
|
Live MIDI input maps CC7 to per-channel volume (0..1), CC10 to pan (64 center),
|
2026-11-06 15:20:20 +01:00
|
|
|
|
and CC64 to sustain (>=64 down). Volume/pan ramp over 5 ms. These default
|
|
|
|
|
|
mappings apply to live sine voices, not track faders or prerecorded clips;
|
|
|
|
|
|
controller capture, automatic learn and plugin MIDI are not supported. CC120/123
|
|
|
|
|
|
and Panic release all live voices and sustain and suppress already-started
|
|
|
|
|
|
scheduled notes. Note-on velocity zero decodes to note-off. Repeated live
|
|
|
|
|
|
note-on on one channel/pitch retriggers one voice; note-off releases it or marks
|
|
|
|
|
|
it pending while sustain is held. Sustain-up releases pending voices, never
|
|
|
|
|
|
newer retriggers. Seek, stop, teardown and disconnect clear live voices; plan
|
|
|
|
|
|
reset returns controller values to unity/center. Equal-offset live events
|
|
|
|
|
|
execute in input order before the sample; arrange note ends precede starts, and
|
|
|
|
|
|
scheduled mixer values are evaluated at that sample. Overlapping arranged notes
|
|
|
|
|
|
are independent.
|
2026-10-27 06:25:30 +01:00
|
|
|
|
|
|
|
|
|
|
Format v6 preserves v5 data plus effect lanes. A v5 plugin migrates with no lane
|
|
|
|
|
|
and the project tempo. Repeated render/save/reopen, odd block partition, exact
|
|
|
|
|
|
endpoints, seek/plan replacement, sustain/retrigger and controller ramp tests:
|
|
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
|
make test test-control test-plugins test-gui-plugins test-plugins-real
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Physical controller devices and listening remain unqualified; no tempo map,
|
2026-11-06 15:20:20 +01:00
|
|
|
|
latency compensation, MIDI capture, pitch bend or plugin crash isolation is
|
|
|
|
|
|
added.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
---
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
## Common Parameter Targets
|
|
|
|
|
|
|
|
|
|
|
|
`xtc_control.h` identifies a parameter by
|
|
|
|
|
|
`(kind, stable owner ID, parameter ID)`. IDs never mean a dense list index and
|
|
|
|
|
|
are not DSP pointers:
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
| Kind | Owner | Parameter IDs | Metadata/reset defaults |
|
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
|
| TRACK | Track or mix-bus stable uint64 ID | 0 gain, 1 pan | Gain 0..4 linear, default 1; pan -1..1 balance, default 0 |
|
|
|
|
|
|
| PLUGIN | LADSPA graph node ID | Actual input-control port | Descriptor name, bounds, default and discrete/logarithmic hints; units unspecified |
|
|
|
|
|
|
| LIVE | MIDI channel 0..15 | 0 volume, 1 pan, 2 sustain | Volume 0..1 default 1; pan -1..1 default 0; sustain boolean default 0 |
|
|
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
`xtc_project_parameter` returns copied metadata, static configuration and
|
|
|
|
|
|
whether a lane exists. LIVE values are reset defaults, not callback-owned
|
|
|
|
|
|
controller readbacks. `xtc_project_set_parameter` changes TRACK/PLUGIN static
|
|
|
|
|
|
configuration without deleting automation. `xtc_project_automate`
|
|
|
|
|
|
sets/replaces/removes points for TRACK/PLUGIN through one C contract. LIVE
|
|
|
|
|
|
static setters and timeline lanes are unsupported: these controls belong to
|
|
|
|
|
|
incoming MIDI events, not the arranged instrument. Plugin metadata/control edits
|
|
|
|
|
|
execute trusted discovery on the control thread; they never run inside audio.
|
|
|
|
|
|
Model-only clients must compile and publish accepted snapshots before rendering;
|
|
|
|
|
|
GUI edits do this transactionally.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
Unknown owners/ports fail without touching the destination model/output. Missing
|
|
|
|
|
|
plugin modules fail discovery rather than guessing ranges or installing a dummy.
|
|
|
|
|
|
Track deletion removes its lanes; plugin deletion removes its embedded lanes.
|
|
|
|
|
|
Compatible plugin replacement resets controls/automation as described in
|
2026-11-06 15:20:20 +01:00
|
|
|
|
PLUGIN_HOSTING.md. Persisted dangling references reject the complete load; the
|
|
|
|
|
|
current project remains intact. The GUI reports rejected edits/Open failures.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Interpolation and Precedence
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
The Mixer Interpolation chooser selects Linear or Hold (step) for the point
|
|
|
|
|
|
being added/replaced. A point owns the segment beginning there. At a hold point,
|
2026-11-06 15:20:20 +01:00
|
|
|
|
its value remains until the next point's exact sample. Linear segments
|
|
|
|
|
|
interpolate between endpoint values without an extra smoothing stage. Hold
|
|
|
|
|
|
first/last before/ after the lane. Gain/pan for tracks and buses support both;
|
|
|
|
|
|
integer/toggle LADSPA controls require hold. Existing files migrate mixer points
|
|
|
|
|
|
to linear.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
Automation is absolute project time, independent of clip starts, ends, trims,
|
2026-11-06 15:20:20 +01:00
|
|
|
|
splits and moves; it neither restarts nor resets at a clip boundary.
|
|
|
|
|
|
Tick-to-sample rounding uses the prepared constant tempo/rate; distinct ticks
|
|
|
|
|
|
landing on the same sample choose the greatest tick. Empty lanes restore the
|
|
|
|
|
|
static value. Static edits while a lane exists change the fallback value, not
|
|
|
|
|
|
the audible lane. GUI changes stop/rebuild snapshots; live mutation of
|
|
|
|
|
|
faders/plugin instances is not introduced. Plugin reset removes lanes only when
|
|
|
|
|
|
explicitly applied.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
At each sample, arranged track/bus and plugin lanes apply to their own targets.
|
|
|
|
|
|
Incoming MIDI volume/pan/sustain affect only live sine voices on that channel,
|
|
|
|
|
|
never those lanes or the static project controls. Equal-offset MIDI events run
|
|
|
|
|
|
in input order before synthesis. A controller event then affects that sample's
|
|
|
|
|
|
ramp; gain/pan reach the target over max(1, rate/200) frames. Sustain changes at
|
|
|
|
|
|
the event sample. Panic CC120/123 remains reserved and also suppresses already
|
|
|
|
|
|
started arranged notes according to the existing panic contract.
|
|
|
|
|
|
|
|
|
|
|
|
Seek/discontinuous positions clear live voices and runtime controllers to their
|
|
|
|
|
|
reset values but retain prepared bindings. Arranged lanes evaluate directly at
|
|
|
|
|
|
the new position. Backward jumps evaluate the earlier timeline again; tests
|
|
|
|
|
|
exercise explicit wraps. There is no loop transport feature or promise to
|
|
|
|
|
|
restore opaque LADSPA delay history across jumps (transport reset retains it).
|
|
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Configurable Live MIDI Bindings
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
Audio → MIDI controller mapping lists the current 16 channels. Enter
|
|
|
|
|
|
`channel volume_CC pan_CC sustain_CC`, for example `2 1 74 11`. Channels are
|
2026-11-06 15:20:20 +01:00
|
|
|
|
zero-based; CCs are 0..127, or 128 to disable a target. Enabled CCs must be
|
|
|
|
|
|
distinct within a channel; CC120 and CC123 cannot be rebound. All channels
|
|
|
|
|
|
default to 7/10/64. Rebinding replaces the old binding; it is not an additional
|
|
|
|
|
|
route. An unmapped CC does nothing. Other channels remain independent. The same
|
|
|
|
|
|
volume, pan and sustain transfer functions apply regardless of the chosen CC
|
|
|
|
|
|
number. Disabling a target leaves it at its runtime reset value until plan
|
|
|
|
|
|
replacement. Changing a map stops/rebuilds playback and is one undoable edit;
|
|
|
|
|
|
maps survive save/Open and undo/redo. Cancel and invalid/duplicate/reserved
|
|
|
|
|
|
bindings retain the prior configuration. There is no automatic learn, arbitrary
|
|
|
|
|
|
plugin/track CC mapping, MIDI capture or write/touch/latch automation mode.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
Plans copy only 48 binding bytes on the control thread. The callback compares at
|
|
|
|
|
|
most three CC numbers per control event, uses existing preallocated ramps/
|
2026-10-27 16:37:59 +01:00
|
|
|
|
voices and the existing 256-event block budget. Decode now accepts all valid
|
2026-11-06 15:20:20 +01:00
|
|
|
|
three-byte CC messages; even unmapped CCs count against that event budget. Mixer
|
|
|
|
|
|
points compile to bounded sorted arrays with binary lane lookup; processing does
|
|
|
|
|
|
no allocation, sort, file/module I/O, locking or GUI work. LADSPA automated
|
2026-10-27 16:37:59 +01:00
|
|
|
|
run(1) cost and native plugin trust limits remain unchanged.
|
|
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Persistence and Verification
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
|
|
|
|
|
Project v10 appends a mixer interpolation field and 16 controller-map records;
|
2026-11-06 15:20:20 +01:00
|
|
|
|
v1–v9 migrate to linear mixer lanes and default 7/10/64 maps. LADSPA point
|
|
|
|
|
|
encoding is unchanged. Public `xtc_automation_point` gains `step`: rebuild
|
|
|
|
|
|
clients and initialize it to 0 (linear) or 1 (hold). See PROJECT_FORMAT.md for
|
|
|
|
|
|
exact grammar.
|
2026-10-27 16:37:59 +01:00
|
|
|
|
|
2026-11-06 15:20:20 +01:00
|
|
|
|
`test_parameters` covers metadata, missing targets, static/automation
|
|
|
|
|
|
precedence, exact hold/linear boundaries, save/reopen, malformed maps, low-rate
|
|
|
|
|
|
sample collisions, odd blocks, seeks and backward jumps. `test_control` compares
|
|
|
|
|
|
default and remapped event streams, stereo pan, disabled/unmapped controls and
|
|
|
|
|
|
immutable plan maps across resets. Plugin tests cover common-target edits and
|
|
|
|
|
|
persistence; GUI tests cover interpolation, map rollback, undo/redo and
|
|
|
|
|
|
save/Open. Existing callback guards and sanitizers verify host ownership
|
|
|
|
|
|
constraints. Physical controller devices, listening and extended high-density
|
|
|
|
|
|
endurance are pending.
|