xtc/docs/ARCHITECTURE.md

54 lines
2.6 KiB
Markdown
Raw Normal View History

2026-10-26 22:51:25 +01:00
# Architecture
## Decision: modular engine first
The processing graph is the common model for audio sources, instruments,
effects, mixers, and outputs. The sequencer produces time-based content and
events consumed by graph nodes. The default workspace remains sequencer-first;
the graph editor is an advanced view of the same project.
## Layers
1. **FLTK/C++ GUI:** input, drawing, windows, view state.
2. **C core:** project model, commands, parameters, persistence, validation.
3. **C engine:** prepared processing graph, DSP, transport timing, event delivery.
4. **Backend:** hardware and system audio/MIDI integration.
The GUI must not directly modify engine internals. It calls a stable C API.
## Graph execution
The first implementation should reject cycles. Compile a graph off the audio
thread: validate, topologically sort, determine buffer requirements, allocate
resources, and publish a prepared immutable execution plan. The audio thread
must not traverse a graph being edited.
2026-10-26 23:20:00 +01:00
The offline engine now copies a validated graph into a prepared plan with
stable node IDs, topological order, precomputed input adjacency, per-node mono
buffers and oscillator/meter state. Each plan has one processing owner. Graph
edits and destruction cannot affect an existing plan. All nodes are scheduled,
including disconnected nodes; only explicit output nodes are rendered (or
terminal nodes when no output node exists). See AUDIO_ENGINE.md for contracts.
2026-10-26 23:32:04 +01:00
`xtc_realtime` now provides a one-pending/one-retired handoff around an
exclusively audio-owned active plan. `xtc_backend` is the C backend boundary;
the optional JACK implementation drives that same realtime engine.
2026-10-26 22:51:25 +01:00
## Ownership and threads
- GUI thread owns FLTK widgets and view state.
- Project/control thread owns mutable project data and graph compilation.
- Audio thread owns the active processing plan and DSP state.
- Backend callbacks follow the backend's documented threading contract.
2026-10-26 23:32:04 +01:00
Only acknowledged retired plans are reclaimed during processing. Backend close
synchronizes callbacks before reclaiming remaining plans. See decision 0004
for the release/acquire protocol, bounded resource retention and recovery.
## GUI backend ownership
The Phase 3 window owns one C backend handle and serializes all control calls
on the GUI thread. A GUI timer reads snapshots and collects retired resources;
no audio callback calls FLTK. Successful window close first closes the JACK
client (synchronizing callbacks), then removes the GUI timer and hides the
window. Failed close leaves both handle and window available for retry. View
switching is GUI state only; editors have no domain mutations yet. See GUI.md.