Kadenz

Eine Digital Audio Workstation, von Grund auf in Rust geschrieben. Der Arbeitsablauf ist ein bewusster Hybrid: das lineare Arrangement von Ableton Live neben der Pattern-Playlist von FL Studio, beide gleichberechtigt auf denselben Clip- und Pattern-Objekten statt als zwei Modi.

Gebaut für Filmmusik. Das heißt Expression Maps, CC-Spuren, sehr große Templates und Plugin-Hosting für CLAP und VST3 als Kernfunktion, wobei Kontakt als Fall behandelt wird, der funktionieren muss, und nicht als einer, der zufällig geht.

26 Crates, 212 Quelldateien, rund 48 000 Zeilen. Windows zuerst, der plattformabhängige Code steckt gekapselt in drei Crates. Der erste Meilenstein ist weitgehend fertig: Audiokern, MIDI, ein eingebauter Synthesizer, Plugin-Hosting und ein Editor, der Klang erzeugt.

Quellcode auf GitHub

Das Arrangement waehrend der Wiedergabe: Spuren mit Clips auf der Zeitachse, darunter der Mixer. Die Piano Roll mit Noten auf dem Raster und der Tastatur an der linken Seite. Das Channel Rack mit den Kanaelen des Projekts und ihren Reglern.

Was schon läuft

Audio

Ein eigenes WASAPI-Backend auf IAudioClient3, keine fremde Audio-Bibliothek. 60 Sekunden bei 128 Frames ohne einen einzigen Aussetzer. Die Wiedergabe aus der Oberfläche läuft mit 48 kHz und 512 Frames bei 1,6 Prozent Callback-Last. Der Offline-Export benutzt denselben Graphen wie die Echtzeit und ist 74 bis 80 mal schneller.

Graph und Dokument

Der Audiograph wird topologisch übersetzt, mit Latenzausgleich für Plugins, Wiederverwendung von Pufferplätzen und paralleler Ausführung. Die Ausgabe ist bitgleich für einen, vier und acht Arbeiter. Das Dokumentmodell arbeitet mit umkehrbaren Änderungen und einem transaktionalen Undo, das zusammenfasst. Ein Property-Test wirft zufällige Änderungsfolgen darauf und prüft, dass sie sich exakt zurücknehmen lassen.

Plugin-Hosting

CLAP über einen vollständigen Adapter auf clack. Für VST3 acht selbst implementierte COM-Objekte, Bus-Verhandlung und zweiteiliger Zustand. Das Einlesen läuft außerhalb des Prozesses, ein Plugin, das abstürzt oder hängt, wird isoliert und auf eine Sperrliste gesetzt. Der Projektzustand von Plugins liegt inhaltsadressiert, deshalb öffnet ein Template mit 500 Spuren ohne einen einzigen Zustandsblock zu lesen.

Editor

Ein Dock mit Arrangement, Piano Roll, Channel Rack, Browser, Inspektor und Mixer, alle auf GPU-Flächen gezeichnet. Das Projektformat ist ein JSON-Ordner mit atomarem Speichern und Autosave. MIDI-Eingang über fünf erkannte Hardware-Ports, eine gespielte Note klingt durch den Synthesizer, auch wenn der Transport steht.

Gemessen, nicht geschätzt

Alle Werte auf der Entwicklungsmaschine gemessen, einem Ryzen 3700X mit RTX 3060 Ti und einem Focusrite-Audiointerface.
MessgrößeWert
Callback-Last bei der Wiedergabe1,6 % bei 48 kHz und 512 Frames, 0 Aussetzer
Dauerlauf bei 128 Frames60 s, 0 Aussetzer
Offline-Export74 bis 80 mal schneller als Echtzeit
Editor bei 211 Spuren und 5300 Clips5,8 ms pro Bild
Eingelesene VST3-Module186
Parameter von Kontakt 84145, von Vital 2852
Tests im Workspace294, dazu 15 hinter dem Plugin-Schalter
Umfang26 Crates, 212 Dateien, rund 48 000 Zeilen

Clippy läuft mit -D warnings und rustfmt sauber durch.

Zwei Fehler, die viel gekostet haben

Der Editor machte überhaupt keinen Ton. Die Anwendung benutzte eine Attrappe von Engine, im eigenen Quelltext dokumentiert als Transport nach Wanduhr ohne Audio, und das Binary hing nicht einmal von der Engine-Crate ab. Der Transport zählte hoch, die Aussteuerungsanzeigen zappelten, und an der Soundkarte kam nie etwas an. Die Engine selbst war die ganze Zeit in Ordnung, auf der Kommandozeile spielte sie seit Tagen dasselbe Projekt. Die Lehre daraus: eine Engine, die ihr Gerät nicht öffnen kann, muss das in der Statuszeile sagen können, denn Stille ohne Erklärung ist von einem leisen Projekt nicht zu unterscheiden.

Jede Änderung lud alle Plugins neu. Ein Plugin darf nur einen aktiven Prozessor haben, und der laufende Graph besitzt ihn, während der nächste gebaut wird. Also wurde bei jedem Neuaufbau jedes Plugin erneut erzeugt. Für einen Sampler heißt das, seine Bibliothek erneut von der Platte zu lesen, was das Bearbeiten eines Projekts mit einem großen Kontakt-Instrument unbenutzbar machte.