Morph Blog
Engineering

Wie wir eine DAW in Ihrem Browser erstellt haben.

Soundbend läuft auf WebAssembly, Web Audio API und 25 Jahren DSP-Forschung — alles client-seitig. Die vollständige technische Geschichte: Audio-Graph, Worklets, Airwindows-Ports, True-Peak-Limiter, Plugin-Host.

VON HAYDEN SIMERLY12 MIN LESTEGEÄNDERT APRIL 2026

Dies ist ein technischer Beitrag über die Funktionsweise von Morph's Soundbend — einem vollständigen digitalen Audio-Workstation mit 5 nativen Instrumenten, einem Mixer mit FX-Chains und Aux-Sends, 30+ Effekten (einschließlich 5 Airwindows Tier-1 Ports und einem echten Peak-Limiter), einer MIDI-Effekte-Rack, einem WAM v2-Plugin-Host und einer Yjs CRDT-Kollaborationsschicht — die vollständig in einem Browser-Tab läuft.

Die praktische Frage lautet: Ist dies wirklich mit Ableton vergleichbar? Die ehrliche Antwort: Für die meisten Produktionsworkflows ja. Für tiefe Max for Live-Integrationen noch nicht. Lesen Sie die Vergleich mit Ableton für die Produkt-Ebene. Dieser Beitrag ist die Engineering-Ebene.

Der Stack

1. Der Audio-Graph

Jeder Track in Soundbend wird durch eine Kette weitergeleitet: Instrument → Track-FX-Kette → Aux-Send → Mixer-Streifen → Master-Bus → Limiter → Ziel. Jeder Pfeil ist eine Web Audio AudioNode-Verbindung.

Web Audio gibt uns AudioContext, GainNode, BiquadFilterNode, ConvolverNode, AnalyserNode und Freunde. Diese werden von Browser-Engines optimiert (V8/SpiderMonkey/JSC alle tief engagiert). Für Standard-Effekte — EQ, Gain-Automatisierung, grundlegende Filterung — verwenden wir native Nodes. Sie sind schnell und gut getestet.

Für benutzerdefinierte Effekte — Airwindows-Ports, unsere Sättigung, unseren echten Spitzenlimiter — gehen wir in AudioWorkletProcessor, der auf dem Audio-Thread läuft, garantiert Echtzeitpriorität hat und der korrekte architektonische Ort für nichtstandardisierte DSP ist.

class PurestDriveProcessor extends AudioWorkletProcessor {
  process(inputs, outputs) {
    const input = inputs[0];
    const output = outputs[0];
    // Airwindows PurestDrive port — ~30 LOC of saturation math
    for (let ch = 0; ch < input.length; ch++) {
      for (let i = 0; i < input[ch].length; i++) {
        const s = input[ch][i];
        // [...tape-saturation math...]
        output[ch][i] = processed;
      }
    }
    return true;
  }
}
registerProcessor('purest-drive', PurestDriveProcessor);

Worklets werden in public/audio-worklets/*.js geliefert und über audioContext.audioWorklet.addModule(path) geladen. Sobald geladen, kann jeder Teil des Graphen einen AudioWorkletNode für diesen Prozessor instanziieren. Die Verarbeitung erfolgt außerhalb des Hauptthreads — UI-Animationen stören die Audioverarbeitung nicht.

2. Die 5 Airwindows Tier-1-Ports

Chris Johnson's Airwindows ist 2.500+ Audio-Plugins, MIT-lizenziert, legendär geschmackvoll im DSP. Wir haben 5 davon in Browser AudioWorklets für Soundbend's Wave 12 portiert:

Jeder Port ist ~30-80 LOC Mathematik in einem AudioWorkletProcessor. Die Ports stimmen nicht bit-für-bit mit Airwindows überein (unterschiedliche FMA/denormal Handhabung zwischen C++ und JS numerischen Engines), aber sie stimmen klanglich überein. Null-Tests halten die Ausgaben ≤ -80 dBFS Rest gegen Goldens, sodass DSP-Änderungen erfasst werden.

3. Der echte Spitzenlimiter

Moderne Streaming-Plattformen (Spotify, Apple Music, YouTube) setzen wahre Spitzenlautstärke nach ITU-R BS.1770-5 durch. Beispielhafte Spitzen und Zwischenspitzen sind unterschiedliche Dinge; ein Signal kann beispielsweise sampleweise bei -1 dBFS peaken, aber nach der D/A-Umsetzung über 0 dBFS wahre Spitzenlautstärke überschreiten. Ein nicht-wahrer-Spitzenlautstärke-Limiter wird im DAC abschneiden, auch wenn Ihre DAW es sauber anzeigt.

Unser Limiter implementiert die vollständige ITU-Spezifikation: 4x Oversampling, Inter-Sample-Peak-Erkennung, Lookahead, Soft-Knee-Release. Er wird in AudioWorklet-Form unter public/audio-worklets/true-peak-limiter-processor.js ausgeliefert. Messungen gegen Referenzimplementierungen (Oxford Limiter, iZotope Ozone Maximizer) stimmen innerhalb von 0,1 dB auf LUFS integriert überein.

4. Kommunikation außerhalb des Hauptthreads

Der Audio-Graph läuft auf dem Audio-Thread. Die UI läuft auf dem Haupt-Thread. Parameteränderungen (Drehen eines Reglers, Fade einer Spur) müssen von UI → Audio propagiert werden, ohne das Audio zu stören.

Web Audio's AudioParam behandelt dies native für Standardparameter (GainNode gain, BiquadFilterNode frequency). Für benutzerdefinierte Worklet-Parameter verwenden wir MessagePort mit strukturierter Klonung für UI-Nachrichten und SharedArrayBuffer-backed Ring-Puffer für Hochgeschwindigkeits-Automatisierungsdaten.

SharedArrayBuffer erfordert Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp Header. Diese sind in public/_headers für die /soundbend + /pulse Routen festgelegt. Der Tape Delay verwendet einen Ringpuffer bei 96 kHz, um Nachrichtenport-Latenz zu vermeiden.

5. Die 5 nativen Instrumente

Soundbend enthält 5 Instrumente, alle maßgeschneidert:

FM-Synth — 6-Operator-FM-Synthese, modelliert auf DX7 / Operator. Algorithmus-Visualisierer + vollständiges Modulationsmatrix. ~800 LOC JS für die Benutzeroberfläche, ~300 LOC Worklet für den Voice-Allocator.

Wavetable Synth — Morphing zwischen Tabellen-Synthese. Spektrale Verzerrung + Unisono + Stereo-Detune. 30+ vorgefertigte Wavetables. Nutzt ConvolverNode für Wavetable-Crossfade in Echtzeit.

Analog Subtractive — 2-Oszillator-Polyphonsynth mit Cytomic SVF-Filtern. Cytomic ist die Zustandsvariablen-Filtertopologie, die richtig klingt; naive SVF hat Aliasing-Probleme oberhalb von fc > SR/6. Der Cytomic-Port löst dies über Nullverzögerungs-Rückkopplungsmathematik.

DrumRack + Sampler — pad-basierte Sample-Wiedergabe mit pro-Pad Pitch-/Filter-/Lautstärken-Envelopes. Samples werden in IndexedDB gespeichert, um schnellen Zugriff zu ermöglichen. 5 genre-spezifische Factory-Kits (Boombap, Trap, House, DNB, Afrobeat).

SeedSynth + Geist (im veralteten AudioStudioEngine — jetzt in Soundbend integriert ab Wave 14) — ein genetischer Patch-Generator (Synplant 2-Klasse) und eine Geist-artige Drummaschine. Dies sind das proprietäre IP, das die Konsolidierungslehre zu einem großen Thema gemacht hat — wir mussten bitidentisches Verhalten durch einen 30k-Zeilen-Merge bewahren. 100-Samen-Nulltest nach dem Merge bestanden.

6. Der Mixer + Aux-Sends

Ein echter Mixer — nicht nur Lautstärkeregler pro Spur, sondern FX-Einsätze pro Spur, vor/nach Lautstärkeregler Aux-Sends, Master-Bus — ist das, was eine DAW von einem Sequencer unterscheidet. Der Mixer von Soundbend ist ~655 LOC (src/audio/mixer.js). Jede Spur ist ein AudioNode-Graph mit Einsatzzonen, Send-Einpunkten und Messung.

Der schwierige Teil ist der Unterschied zwischen Pre-Fader und Post-Fader Aux-Sends. Pre-Fader sendet an eine Reverb-Bus unabhängig von der Track-Lautstärke (klassischer Einsatz: paralleles Reverb, das bei einem Track-Fade erhalten bleibt). Post-Fader skaliert mit der Track-Lautstärke. Beide sind enthalten.

7. MIDI + WAM-Plugin-Host

WebMIDI ist reif — Steuerungseingabe von jedem USB-MIDI-Keyboard funktioniert einfach. Unser MIDI-Rack (Arpeggiator, Scale, Chord) sitzt zwischen dem Controller und dem Instrument und transformiert Notenströme.

Für Plugins hosten wir Web Audio Modules v2 (WAM) — browsernative Plugins. Kleinere Ökosystem als VST (25-Jahres-Vorsprung), aber wachsend. Das Laden eines WAM erfolgt mit getWamHost().load(wamUri), was einen AudioNode zurückgibt, den Sie in jede Kette einfügen können.

WAMs erfordern pro-Routen CSP, weil sie beliebigen benutzerbereiteten JS laden. Unsere _headers begrenzen CSP eng für /soundbend mit einem script-src-Erlaubnisliste für bekannte WAM-Registrierungen.

8. OfflineAudioContext für Bounce

Der Export erfolgt über OfflineAudioContext — rendern schneller als Echtzeit (oder langsamer, je nach Kettenkomplexität) in einen statischen AudioBuffer und wird dann über unseren in-Browser-Encoder in WAV codiert.

Hinweis: Nicht alle Knoten funktionieren im OfflineAudioContext. MediaStreamAudioSourceNode funktioniert nicht (kann keine Live-Mikrofonaufnahme offline aufnehmen, offensichtlich). Bestimmte Worklets benötigen eine sorgfältige Zustandsrücksetzung bei Online → Offline-Übergängen. Wir haben dieses Problem wiederholt erlebt und nun ist Mixer.toJSON() + Mixer.fromJSON(offlineCtx) das kanonische Muster: Serialisieren Sie den Mixer-Zustand, bauen Sie einen parallelen Mixer im Offline-Kontext neu auf und rendern Sie.

9. Zusammenarbeit über Yjs

Yjs ist eine CRDT-Bibliothek, die mehrbenutzerkollaborative Bearbeitung mit automatischer Konfliktlösung behandelt. Unsere SoundbendSession-Klasse umschließt Yjs mit pro-Track-Dokumentstruktur (Y.Map für Track-Metadaten, Y.Array für Muster-Schritte, Y.Text für Texte/Notizen).

Zwei bis vier Produzenten können dasselbe Projekt gleichzeitig bearbeiten mit sample-genauer Track-Synchronisation. Dies ist schwieriger als Textdokumente zu kooperieren, da Audio-Daten um Größenordnungen größer sind – wir teilen Metadaten + Muster über Yjs, nicht Rohaudio. Rohproben bleiben lokal (IndexedDB pro Benutzer).

10. Das Leistungsbudget

Ein vollständiges DAW im Browser mit 60fps UI + Echtzeit-Audio + SharedArrayBuffer + WASM + mehreren Worklets erfordert enge Budgets. Einige Zahlen:

11. Null-Test-Harness

DSP-Regressionen sind stumm — Audio klingt auf subtile Weise anders, was Code-Reviews nicht erkennen können. Soundbend wird mit einem Puppeteer-getriebenen Null-Test-Harness in tests/audio-null/ geliefert.

Für jedes Effekt × Voreinstellung × Testsignal rendert das Harness über OfflineAudioContext in einem headless Chromium, testet das resultierende WAV gegen ein festgelegtes Golden-File und schlägt den Build fehl, wenn der Restgipfel -60 dBFS übersteigt.

Wave 14F fügte 100 SeedSynth-Seed-Baselines und 32 Geist-Drum-Pattern-Golden hinzu. Als wir Soundbend in AudioStudio (Wave 14B-G) integrierten, erfasste der Null-Test alles, was möglicherweise stillschweigend die proprietären Instrumente beschädigt hätte. 96 von 100 SeedSynth-Samen bestanden den bitidentischen Test. Die 4 Fehler waren vorbestehende Chromium Web Audio-Quirks (hoch-Q-Filter-Resonanzschwankung zwischen OfflineAudioContext-Instanzen) — keine Merge-Regressionen und nicht von JS aus behebbar.

DSP-Regressionen sind stumm. Code-Reviews können sie nicht hören. Der Null-Test-Harness kann — deshalb ist er CI-blockierend.

12. Warum Browser + Client-seitig die richtige Wahl war

Native DAWs (Ableton, Logic, FL Studio) haben einen 30-jährigen Vorsprung. Die Übernahme aller Funktionen ist ein langer Weg. Aber Preisgestaltung — das war sofort gewinnbar, indem andere architektonische Entscheidungen getroffen wurden.

WebAssembly hat 2022-2024 die Leistungsschwelle überschritten. Web Audio AudioWorklets wurden etwa zur gleichen Zeit weit verbreitet. SharedArrayBuffer + COOP/COEP stabilisiert. Chromium, Firefox und Safari unterstützen alle die benötigten APIs mit ausreichender Leistung.

Die Preisimplikation: Wenn Audioverarbeitung auf dem Gerät des Nutzers läuft, bezahlen wir dafür nicht. Unsere Grenzkosten pro Pro-Abonnent sind nahezu null. Daher ist $4.99/mo nachhaltig für immer. Ein Kind in Lagos mit einem Android-2020 erhält eine vollständige DAW, die jemand in San Francisco für denselben $4.99 nutzt.

Lesen Sie den Preisarchitektur-Essay für die Wirtschaftsgründe. Für den DSP ist das größtenteils die ganze Geschichte.

Probieren Sie es aus

Soundbend ist unter morph.cool/soundbend verfügbar. Der kostenlose Tarif funktioniert ohne Anmeldung. $4,99/Monat Pro entsperrt die Mastering-Kette + True-Peak-Limiter + zusätzliche Voreinstellungen. WebMIDI-Tastatur willkommen, nicht erforderlich.

Soundbend öffnen

— Hayden + das Morph-Agententeam
22. April 2026