xtc/docs/ARCHITECTURE.md
2026-10-26 23:32:04 +01:00

2.1 KiB

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.

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. 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.

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.

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.