# 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 current scaffold is deliberately incomplete: `xt_graph_process_offline()` validates the graph and applies gain nodes in insertion order. It is a test placeholder, not the final graph execution algorithm. ## 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. Do not free an active plan until the audio thread has released it. Pick and document a bounded handoff/reclamation strategy before real-time graph swaps.