Docs file normalization.

This commit is contained in:
Johannes Findeisen 2026-11-06 15:20:20 +01:00
commit 619c2d0808
46 changed files with 3587 additions and 2579 deletions

View file

@ -1,21 +1,23 @@
# Internal instruments and effects
# Internal Instruments and Effects
No plugin downloads, search paths or external libraries are needed. The original
built-in sine remains available for existing projects.
Choose **Internal: Soft Keys** or **Internal: Sub Bass** in a MIDI track's
instrument dropdown. Soft Keys blends a sine with a third harmonic; Sub Bass
uses a pure sine. Both have 32 voices, velocity sensitivity,
short attack/release envelopes, sustain pedal, note-off and panic handling.
High harmonics are omitted near Nyquist. The default sounds remain compatible with fixed presets from v13. See the
instrument controls below. A sample library is not provided by these oscillators.
uses a pure sine. Both have 32 voices, velocity sensitivity, short
attack/release envelopes, sustain pedal, note-off and panic handling. High
harmonics are omitted near Nyquist. The default sounds remain compatible with
fixed presets from v13. See the instrument controls below. A sample library is
not provided by these oscillators.
In **Modular Graph**, select a wire and choose **Edit → Insert internal delay on
wire** or **Insert internal reverb on wire**. This preserves the route and inserts
the effect into the signal path. **File → Add internal delay/reverb** creates an
unconnected device for manual wiring. Select its node and use **Edit → Selected
plugin control** to edit it, or **Selected plugin automation** to automate it.
Changes use the existing stopped-engine preparation and undo workflow.
wire** or **Insert internal reverb on wire**. This preserves the route and
inserts the effect into the signal path. **File → Add internal delay/reverb**
creates an unconnected device for manual wiring. Select its node and use **Edit
→ Selected plugin control** to edit it, or **Selected plugin automation** to
automate it. Changes use the existing stopped-engine preparation and undo
workflow.
- **Delay:** time (1–2000 ms), feedback (0–0.95), dry/wet mix (0–1).
- **Reverb:** four parallel damped feedback combs, with decay (0–0.95), damping
@ -28,37 +30,43 @@ Internal effect history resets on transport discontinuities. Configurable export
tails and optional playback stopping after tails are described below.
Project format 13 stores internal devices as format 4 with reserved module path
`/xtc/internal`, stable numeric identity and index (0 keys, 1 bass, 2 delay,
3 reverb). This is a virtual identifier, never an external binary. Effect controls
and automation are saved using the existing plugin records; instruments are fixed
presets. Readers still accept formats 1–12. Older xtc builds reject format 13.
All buffers are allocated during preparation; processing performs no allocation,
file access, library loading, locking or GUI calls.
`/xtc/internal`, stable numeric identity and index (0 keys, 1 bass, 2 delay, 3
reverb). This is a virtual identifier, never an external binary. Effect controls
and automation are saved using the existing plugin records; instruments are
fixed presets. Readers still accept formats 1–12. Older xtc builds reject format
13. All buffers are allocated during preparation; processing performs no
allocation, file access, library loading, locking or GUI calls.
Validation: `make BUILD_DIR=build/builtins all gui test test-gui-instruments
test-gui-modern-plugins test-gui-plugins analyze` (join onto one line).
`test-builtins` checks impulse tails, dry mix, feedback bounds, block partition
consistency, note release/panic and instrument/effect project round trips.
Validation:
`make BUILD_DIR=build/builtins all gui test test-gui-instruments test-gui-modern-plugins test-gui-plugins analyze`
(join onto one line). `test-builtins` checks impulse tails, dry mix, feedback
bounds, block partition consistency, note release/panic and instrument/effect
project round trips.
## Acceptance checks
---
## Acceptance Checks
`make BUILD_DIR=build/builtin-acceptance all gui test test-reliability test-gui builtin-preview`
checks all four device identities and GUI paths without external plugin binaries.
The reliability runner fails each internal preparation allocation in turn and
forbids allocation/free, direct file I/O and blocking locks during processing.
Core tests compare persisted rendering for both instruments and both automated
effects, corrupt an internal module identity transactionally, and cover voice
exhaustion, sustain, repeated notes, partitioning and transport reset/seek/panic.
The existing portability suite verifies older project migrations.
checks all four device identities and GUI paths without external plugin
binaries. The reliability runner fails each internal preparation allocation in
turn and forbids allocation/free, direct file I/O and blocking locks during
processing. Core tests compare persisted rendering for both instruments and both
automated effects, corrupt an internal module identity transactionally, and
cover voice exhaustion, sustain, repeated notes, partitioning and transport
reset/seek/panic. The existing portability suite verifies older project
migrations.
For repeatable manual listening, run `make builtin-preview` and audition
`build/builtin-{0,1,2,3}.wav` at a conservative level: 0 is Soft Keys, 1 Sub Bass,
2 Delay and 3 Reverb. Each six-second file includes held tones or two impulses
followed by silence for tails. Check onset/release, unwanted discontinuities,
finite decay and the documented mono character. Generation is verified;
human listening and physical-device qualification remain pending.
`build/builtin-{0,1,2,3}.wav` at a conservative level: 0 is Soft Keys, 1 Sub
Bass, 2 Delay and 3 Reverb. Each six-second file includes held tones or two
impulses followed by silence for tails. Check onset/release, unwanted
discontinuities, finite decay and the documented mono character. Generation is
verified; human listening and physical-device qualification remain pending.
## Instrument controls and presets
---
## Instrument Controls and Presets
**Edit → Selected instrument controls** edits an assigned internal instrument.
The five ports are harmonic amount (0..1), attack (0.1..2000 ms), release
@ -77,8 +85,8 @@ with no parameters upgrade to defaults when opened in the editor.
are versioned single-instrument `.xtc` containers with no clips. Public C APIs
`xtc_plugin_preset_save/load` provide atomic saving and transactional metadata
loading; they never execute plugin code. Loading into a track is an undoable,
prepared edit. Parameter automation is included. Preset paths are ordinary files;
saving uses the existing project replacement semantics.
prepared edit. Parameter automation is included. Preset paths are ordinary
files; saving uses the existing project replacement semantics.
Live MIDI pitch bend uses standard 14-bit messages (8192 center) and is applied
at the event's sample offset per channel. Panic clears the affected channel's
@ -91,7 +99,9 @@ old fixed internal assignments use their original defaults. Older builds reject
v14. Tests cover legacy-default sound equality, v13 migration, parameter/preset
round trips, pitch-bend offsets, automated block partitions, undo and GUI edits.
## Sample instrument
---
## Sample Instrument
**File → Load sampler WAV** assigns a Sample Player to the selected track or
relinks its existing sample while retaining its controls. Use the instrument
@ -99,8 +109,8 @@ controls editor for root MIDI key (0..127), whole-sample loop (0/1), attack,
release and gain (0..4). One root mapping covers every MIDI key using linear
rate conversion, including source/output sample-rate differences. Loop and root
are integer controls and require hold automation. Live bend spans ±2 semitones.
This initial sampler has no multisample zones, loop-point editor or time stretch.
Extreme transposition can alias; use appropriate source material.
This initial sampler has no multisample zones, loop-point editor or time
stretch. Extreme transposition can alias; use appropriate source material.
The existing WAV reader supports PCM16/24/32 and float32, mono/stereo downmixed
to mono. Each sample is at most 16M mono frames; the combined instrument plan
@ -122,15 +132,17 @@ Tests cover source-rate conversion, one-shot endpoint, looping, release,
partitioning, preset references, missing assets, GUI relinking/undo/reload and
preparation-allocation/callback guards.
## Stereo effects
---
## Stereo Effects
**File → Add stereo delay/reverb** and **Edit → Insert stereo delay/reverb on
wire** add new devices (indices 5/6). Original Delay/Reverb (indices 2/3) retain
their original algorithms, values and saved identities. Existing control and
automation editors, undo and persistence support both generations.
Stereo Delay adds integer **Sync**: 0 milliseconds, 1 quarter, 2 eighth,
3 dotted eighth, 4 eighth triplet. Nonzero sync follows project tempo; changing
Stereo Delay adds integer **Sync**: 0 milliseconds, 1 quarter, 2 eighth, 3
dotted eighth, 4 eighth triplet. Nonzero sync follows project tempo; changing
tempo uses ordinary stopped project preparation. Time changes crossfade two
fractional read heads for 5 ms. A crossfade finishes before adopting the latest
automated target, bounding transition work and avoiding read-head jumps.
@ -139,29 +151,33 @@ Delay storage covers four seconds, sufficient for all divisions at 20..300 BPM.
Stereo Reverb adds **Room** (0..1, scales comb spacing) and **Diffusion** (0..1,
cross-couples damped feedback). The right comb timings differ from the left.
Decay/damping retain 0..0.95 bounds. This is a simple algorithmic reverb, without
physical room simulation or a measured RT60. Room automation can alter coloration.
Decay/damping retain 0..0.95 bounds. This is a simple algorithmic reverb,
without physical room simulation or a measured RT60. Room automation can alter
coloration.
The graph evaluates both channels' inputs before calling a coupled internal
processor. Each stereo device has one prepared state, with no callback allocation.
Mono processing excites both sides and folds the wet output to mono. External
plugins and the original effects retain independent mono instances.
processor. Each stereo device has one prepared state, with no callback
allocation. Mono processing excites both sides and folds the wet output to mono.
External plugins and the original effects retain independent mono instances.
Tests compare whole/split blocks, tempo-synced impulse placement, left-to-right
energy, bounded extreme feedback/diffusion and graph/direct stereo output
(including the engine's subnormal-to-zero policy). GUI tests save/reopen both
identities; callback guards and ASan/UBSan cover processing. `make builtin-preview`
also writes files 5/6 for repeatable listening; human listening remains pending.
identities; callback guards and ASan/UBSan cover processing.
`make builtin-preview` also writes files 5/6 for repeatable listening; human
listening remains pending.
## History and tails
---
## History and Tails
Internal effects reset on a transport discontinuity (seek/loop wrap), stopped
backend, or newly prepared plan. Pause uses backend Stop and therefore also
resets history. Continuous playback retains tails. Reset invalidates delay
history with a valid-frame counter and clears only fixed-size filter/voice state;
it neither allocates nor clears a large delay buffer in the callback. External
plugins retain their existing history contract. MIDI discontinuities continue
to chase notes with fresh envelopes.
history with a valid-frame counter and clears only fixed-size filter/voice
state; it neither allocates nor clears a large delay buffer in the callback.
External plugins retain their existing history contract. MIDI discontinuities
continue to chase notes with fresh envelopes.
**File → Export WAV** renders the song plus the Preferences / transport
`tail_ms` duration (0..60000, default 3000). Output is stereo float32 WAV at the
@ -169,9 +185,9 @@ offline sample rate. The destination must be a new absolute path. Rendering
prepares an independent snapshot, then advances in 256-frame control-thread
steps with a Cancel button; the project and playback instance stay independent.
Only a complete synced file is published, without replacing an existing file.
Cancellation/errors remove the temporary. Missing media rejects export.
RIFF's 32-bit size limit is enforced before rendering. Rendering does not apply
loop preferences, normalize, automatically detect silence or stop infinite
Cancellation/errors remove the temporary. Missing media rejects export. RIFF's
32-bit size limit is enforced before rendering. Rendering does not apply loop
preferences, normalize, automatically detect silence or stop infinite
oscillator/feedback sources early: the configured endpoint always bounds work.
The public `xtc_export_create/step/progress/destroy` API supports incremental
@ -181,8 +197,9 @@ destruction. `xtc_project_render_length` returns the exact sample endpoint.
Set `stop_after_tail=1` in Preferences to stop ordinary playback after the song
and configured tail. Looping and recording disable this automatic stop. Playback
stop is serviced by the GUI refresh timer and normal stop fade, so it can exceed
the endpoint by a refresh interval plus fade; export has the exact sample length.
Uncheck the setting to retain indefinite playback. Stop always remains available.
the endpoint by a refresh interval plus fade; export has the exact sample
length. Uncheck the setting to retain indefinite playback. Stop always remains
available.
Tests compare stereo export against direct rendering in 31-frame blocks, verify
nonzero tails, exact length, cancellation, existing-file retention, tail bounds,