Skip to content

Overview

Marbble is a Cargo workspace with three crates plus a React frontend:

Part Path Role
vst3-host crates/vst3-host VST3 hosting on the vst3 bindings: module loading, scanning, host COM objects, the real-time processing wrapper, editor windows.
daw-engine crates/engine The audio engine: the project model, the real-time graph, the session controller, device I/O, recording, MIDI, rendering. No UI code.
daw src-tauri The Tauri 2 application: commands, the native menu, settings and recent files, the timers that drive plug-in idle and UI ticks. The binary is called daw; packages also install it as marbble.
frontend src React 19 + TypeScript, built with Vite. Canvas for the tracks area, ruler, editors and meters.

The engine is split into two halves that never share mutable data directly:

  • Session (crates/engine/src/session.rs and session/) is the non-real-time controller. It owns the Project document, the loaded audio clips, the plug-in controllers, the undo history and the recorder. Every edit goes through it.
  • Engine (crates/engine/src/dsp.rs and dsp/) is the real-time graph. It owns one TrackDsp per track and runs Engine::process on the audio thread. It learns about edits only through Cmd messages.
flowchart LR
  UI["React UI<br/>(src/)"] -- "invoke(cmd, args)" --> CMD["Tauri commands<br/>(src-tauri/src/commands/)"]
  CMD -- "lock" --> S["Session<br/>(project, clips, controllers, undo)"]
  S -- "Cmd (rtrb ring)" --> E["Engine::process<br/>(audio thread)"]
  E -- "Garbage (rtrb ring)" --> S
  E -- "EngineStatus atomics,<br/>meters, rings" --> S
  S -- "Snapshot (return value / 'project' event)" --> UI
  S -- "Tick ('tick' event, ~30 Hz)" --> UI