01 / GUI & control
Qt Widgets owns engine lifecycle, settings, port selection and a 30 Hz status timer. It starts and stops the engine outside audio.
02 / Real-time audio
JACK callbacks run Qt-independent DSP. Prepared state, server-supplied buffers and lock-free scalar atomics carry controls and meters.
03 / Background work
Planned: sample decoding, project I/O and indexing prepare immutable state off the audio thread. Current small settings/log I/O runs on the GUI thread.
The callback has one job.
Produce bounded audio on time. RIVET’s callback avoids dynamic allocation, filesystem access, blocking locks, networking, GUI operations, blocking logging and unpredictable expensive work. DSP state is allocated before activation; JACK supplies the audio buffers.
Shutdown callbacks publish atomic flags. The GUI observes them and closes the client safely. Client deactivation and closure happen before engine storage is destroyed.
MIDI now. Instruments later.
JACK MIDI input validates note on/off, velocity, pitch bend and control changes while retaining frame offsets. A bounded single-producer/single-consumer queue feeds the diagnostic monitor. Queue overflow is counted. There is no playable voice engine, recording or playback yet.
Technology, with its current role.
| Component | Role | Status |
|---|---|---|
| C++20 / CMake 3.22+ | Native application and build system | Implemented |
| Qt 6.7+ Widgets | UI, preferences and lifecycle | Implemented |
| PipeWire / JACK | Stereo output and JACK MIDI; Fedora PipeWire backend tested | Implemented |
| Direct ALSA MIDI | Possible alternate MIDI backend; not linked in Phase 1 | Planned |
| libsndfile | Future sample file I/O and offline WAV export | Planned |
| SQLite | Future browser/index storage where useful; not a current dependency | Planned |
Prepare the graph before it runs.
Devices will expose a unique type ID, an instance ID, a name and type, audio and modulation inputs/outputs, parameters and preset state. Typed connection validation and cycle rejection will produce an acyclic processing graph.
Build execution plans and preallocate graph buffers outside the callback. Publish prepared plans safely and reclaim old plans outside audio. Rack reordering must not override the graph’s DSP execution order.
One DSP contract, live or offline.
The current block processor is independent of JACK. Planned offline rendering will reuse DSP, sample-rate and event-scheduling contracts. Future projects use versioned data with validated ranges, connection types and resource limits; they must never deserialize arbitrary executable code.
Read the architecture reference (Markdown) · Read validation evidence (Markdown)