Phase 15: host trusted LADSPA processors with persisted graph state
This commit is contained in:
parent
c3eadee891
commit
f72314b5a3
24 changed files with 1046 additions and 70 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Project format v4 (reads v1/v2/v3)
|
||||
# Project format v5 (reads v1/v2/v3/v4)
|
||||
|
||||
Phases 5–8 use a bounded text format implemented in C99 without a parser library.
|
||||
Phases 5–15 use a bounded text format implemented in C99 without a parser library.
|
||||
The extension is `.xtc`. File operations run exclusively on the control thread.
|
||||
The project owns its graph, tracks and silent/audio arrangement regions. Audio samples remain in external WAV
|
||||
files; MIDI notes are stored inline.
|
||||
|
|
@ -12,7 +12,7 @@ Fields use ASCII spaces. Integers are unsigned decimal, without signs.
|
|||
Counts determine the number of subsequent records:
|
||||
|
||||
```text
|
||||
XTC_PROJECT 4
|
||||
XTC_PROJECT 5
|
||||
APP 0 1 0
|
||||
TEMPO 120000
|
||||
IDS 1 1
|
||||
|
|
@ -39,30 +39,30 @@ END
|
|||
- `GRAPH`: output-node policy (0/1), next node ID, node count, edge count.
|
||||
Nodes retain stable IDs (limited to the host's size_t range). No pointers or
|
||||
compiled state are serialized.
|
||||
- `NODE`: ID, type (1 gain, 2 oscillator, 3 meter, 4 output, 5 audio source, 6 instrument), and exactly eight
|
||||
- `NODE`: ID, type (1 gain, 2 oscillator, 3 meter, 4 output, 5 audio source, 6 instrument, 8 LADSPA plugin), and exactly eight
|
||||
hexadecimal digits encoding the IEEE binary32 parameter bits, independent
|
||||
of locale and host byte order. Nonfinite values are rejected.
|
||||
- `EDGE`: source and destination node IDs. Port directions are implied
|
||||
by node type; endpoints, duplicates and cycles are validated by the graph API.
|
||||
- `TRACK`: ID and hex-encoded name bytes. In v4 each is immediately followed
|
||||
- `TRACK`: ID and hex-encoded name bytes. In v4/v5 each is immediately followed
|
||||
by `MIX gain_bits pan_bits mute solo`: finite binary32 gain 0..4, pan -1..1
|
||||
encoded as eight hex digits, mute and solo unsigned 0/1.
|
||||
- `CLIP`: ID, track ID, start tick, length tick, source offset tick, source
|
||||
length tick, hex-encoded name bytes. Trimming
|
||||
preserves source bounds, so a region can re-extend only within its original
|
||||
length. Overlaps are allowed and audio clips mix through the audio source node.
|
||||
- `ASSET`: required after each CLIP in v2/v3/v4; "-" means no audio asset, otherwise
|
||||
- `ASSET`: required after each CLIP in v2/v3/v4/v5; "-" means no audio asset, otherwise
|
||||
hex-encoded absolute path bytes, <=511 bytes after decoding, no embedded NUL
|
||||
or ASCII control characters. Each clip directly references a WAV; no sample
|
||||
data, pointers or DSP state are embedded. Paths can contain spaces.
|
||||
- `MIDI`: required after each ASSET in v3/v4; 0 for silent/audio regions, 1 for
|
||||
- `MIDI`: required after each ASSET in v3/v4/v5; 0 for silent/audio regions, 1 for
|
||||
MIDI clips. MIDI clips must have no asset.
|
||||
- `NOTES`: next stable note ID and global note count, followed by that many
|
||||
`NOTE id clip_id start_tick length_tick pitch velocity channel` records.
|
||||
Notes reference MIDI clips; start/length are source-relative, positive length
|
||||
within source bounds. Pitch is 0..127, velocity 1..127, channel 0..15.
|
||||
Note IDs are unique, monotonic uint64 IDs with UINT64_MAX reserved.
|
||||
- `AUTOMATION`: global point count, after the last NOTE and before END in v4.
|
||||
- `AUTOMATION`: global point count, after the last NOTE and before END in v4/v5.
|
||||
Follow with `POINT track_id parameter tick value_bits` for each point.
|
||||
Parameter 0 is gain (0..4), 1 pan (-1..1); values use finite binary32 hex.
|
||||
Track must exist; tick <= MAX_TICK; duplicate track/parameter/tick is invalid.
|
||||
|
|
@ -82,8 +82,8 @@ node types 1..4, migrating their clips to empty asset paths. Version 2 accepts
|
|||
node types 1..5 and ASSET records. Both migrate to MIDI=0 and no notes.
|
||||
Version 3 accepts instrument nodes and MIDI/NOTES records. Versions 1–3 migrate
|
||||
all tracks to unity gain, centered pan, mute/solo off and no automation.
|
||||
Saving always writes v4. Unknown versions are rejected without replacing the destination; older
|
||||
applications cannot read v4. Migration and maximum-path roundtrips are tested.
|
||||
Saving always writes v5. Unknown versions are rejected without replacing the destination; older
|
||||
applications cannot read v5. Migration and maximum-path roundtrips are tested.
|
||||
|
||||
## Ownership and failures
|
||||
|
||||
|
|
@ -108,9 +108,33 @@ changing its IDs or arrangement. See AUDIO_FILES.md for recovery and limitations
|
|||
|
||||
## Phase 9 extension and recovery policy
|
||||
|
||||
Format remains v4. Native processor descriptors are process-local and have no
|
||||
Phase 9 kept format v4. Native processor descriptors are process-local and have no
|
||||
serialized representation; saving a native graph returns UNSUPPORTED and retains
|
||||
the existing destination. Unknown file versions/types remain rejected. See
|
||||
NATIVE_API.md for the extension boundary and RECOVERY.md for write-failure, killed
|
||||
writer and unfinished-recording behavior. Metadata validation is available via
|
||||
`xtc-check --validate PROJECT` without a GUI or server; it does not load assets.
|
||||
|
||||
## Phase 15: version 5 plugin metadata
|
||||
|
||||
The writer now emits `XTC_PROJECT 5`; versions 1–4 still load. All v4 records and
|
||||
order remain the same. Node type 8 is a LADSPA plugin; native pointer-bearing type
|
||||
7 is still unsupported in files. Immediately after each type-8 `NODE id 8
|
||||
00000000` record come:
|
||||
|
||||
```text
|
||||
PLUGIN unique_id descriptor_index mono_inputs control_count hex_label
|
||||
MODULE hex_absolute_module_path
|
||||
CONTROL port_index float32_hex_bits
|
||||
```
|
||||
|
||||
There are exactly `control_count` CONTROL records. Label length is 1–63 bytes,
|
||||
module path 1–511 bytes (absolute), both hex-encoded with no embedded NUL. Index
|
||||
is <1024, mono_inputs 0/1, controls <=16, control port indices <64 strictly
|
||||
increasing, and values finite. Unique ID fits uint32. The one output is implicit.
|
||||
Structural validation never opens libraries. On graph compilation the host checks
|
||||
identity, layout, input control port IDs and rate-adjusted legal ranges against
|
||||
the module. Unknown nodes/versions fail without mutating the current project.
|
||||
Missing modules remain preserved by metadata load/save; GUI installation rejects
|
||||
them with a repair message. No transient DSP state, pointer or plugin binary is
|
||||
stored. See PLUGIN_HOSTING.md and decision 0009 for supported processors/limits.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue