Morph Blog
Rekayasa

Bagaimana kami membangun DAW di browser Anda.

Soundbend berjalan pada WebAssembly, Web Audio API, dan 25 tahun penelitian DSP — semuanya di sisi klien. Cerita teknis lengkap: grafik audio, worklets, port Airwindows, limiter true-peak, host plugin.

OLEH HAYDEN SIMERLY12 MENIT BACAPERBARUI APRIL 2026

Ini adalah posting teknis tentang bagaimana Morph Soundbend — sebuah workstation audio digital lengkap dengan 5 instrumen native, Mixer dengan FX chains dan aux sends, 30+ efek (termasuk 5 port Airwindows Tier-1 dan limiter true-peak), rak efek MIDI, host plugin WAM v2, dan lapisan kolaborasi Yjs CRDT — berjalan sepenuhnya di tab browser.

Pertanyaan praktisnya adalah: apakah ini benar-benar kompetitif dengan Ableton? Jawaban jujur: untuk sebagian besar alur kerja produser, ya. Untuk integrasi Max for Live yang mendalam, belum. Baca perbandingan alternatif Ableton untuk penjelasan tingkat produk. Posting ini adalah bagian teknis.

Tumpukan

1. Grafik audio

Setiap trek di Soundbend melewati rantai: instrumen → rantai FX trek → aux send → strip mixer → bus utama → limiter → tujuan. Setiap panah adalah koneksi Web Audio AudioNode.

Web Audio memberi kita AudioContext, GainNode, BiquadFilterNode, ConvolverNode, AnalyserNode, dan teman-teman. Ini dioptimalkan oleh mesin browser (V8/SpiderMonkey/JSC semua berinvestasi dalam hal ini). Untuk efek standar — EQ, otomatisasi gain, filtering dasar — kami menggunakan node asli. Mereka cepat dan telah diuji.

Untuk efek khusus — port Airwindows, saturasi kami, limiter true-peak kami — kami beralih ke AudioWorkletProcessor, yang berjalan di thread audio, dipastikan prioritas real-time, dan merupakan tempat arsitektur yang tepat untuk DSP non-standar.

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 dikirim dalam public/audio-worklets/*.js dan dimuat melalui audioContext.audioWorklet.addModule(path). Setelah dimuat, bagian mana pun dari grafik dapat menginstansiasi AudioWorkletNode untuk prosesor tersebut. Pemrosesan berjalan di luar thread utama — animasi UI tidak menghambat audio.

2. Port Tier-1 Airwindows 5

Chris Johnson's Airwindows adalah 2.500+ plugin audio, lisensi MIT, DSP yang legendaris rasanya. Kami memindahkan 5 ke AudioWorklets browser untuk kapal Wave 12 Soundbend:

Setiap port adalah sekitar 30-80 LOC matematika dalam AudioWorkletProcessor. Port tidak cocok bit-for-bit dengan Airwindows (penanganan FMA/denormal berbeda antara mesin numerik C++ dan JS) tetapi cocok secara sonik. Uji nol menjaga output ≤ -80 dBFS residual terhadap emas, sehingga perubahan DSP terdeteksi.

3. Limiter true-peak

Platform streaming modern (Spotify, Apple Music, YouTube) menerapkan normalisasi kekerasan true-peak sesuai ITU-R BS.1770-5. Puncak sampel dan puncak inter-sample adalah hal yang berbeda; sinyal dapat mencapai -1 dBFS secara sampel tapi melebihi 0 dBFS true-peak setelah rekonstruksi D/A. Limiter yang bukan true-peak akan memotong di DAC meskipun DAW Anda menunjukkan bersih.

Limiter kami menerapkan spesifikasi ITU lengkap: 4x oversampling, deteksi inter-sample-peak, lookahead, lembut-knee release. Ini dikirim dalam bentuk AudioWorklet di public/audio-worklets/true-peak-limiter-processor.js. Pengukuran terhadap implementasi referensi (Oxford Limiter, iZotope Ozone Maximizer) sesuai dalam 0,1 dB pada LUFS terintegrasi.

4. Komunikasi di luar utama

Grafik audio berjalan di thread audio. Antarmuka pengguna berjalan di thread utama. Perubahan parameter (putar kenop, fade trek) perlu dipropagasi dari UI → audio tanpa mengganggu audio.

Web Audio's AudioParam menangani ini secara bawaan untuk parameter standar (GainNode gain, BiquadFilterNode frequency). Untuk pekerjaan kustom dengan worklet, kami menggunakan MessagePort dengan kloning terstruktur untuk pesan UI, dan SharedArrayBuffer-backed ring buffers untuk data otomatisasi berkecepatan tinggi.

SharedArrayBuffer requires Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp headers. These are set in public/_headers for the /soundbend + /pulse routes. The Tape Delay uses a ring buffer at 96kHz to avoid message-port latency.

5. 5 instrumen bawaan

Soundbend dilengkapi 5 instrumen, semuanya custom:

FM Synth — Sintesis FM 6-operator yang dimodelkan dari DX7 / Operator. Visualisasi algoritma + matriks modulasi lengkap. ~800 LOC JS untuk UI, ~300 LOC worklet untuk alokator suara.

Sintesis Wavetable — sintesis morph-between-tables. Warp spektral + unison + stereo detune. 30+ wavetable pabrik. Menggunakan ConvolverNode untuk crossfade wavetable pada tingkat audio.

Analog Subtractive — polysynth dua-oscillator dengan filter Cytomic SVF. Cytomic adalah topologi filter variabel state yang terdengar tepat; SVF naif memiliki masalah aliasing di atas fc > SR/6. Port Cytomic menangani ini melalui matematika feedback zero-delay.

DrumRack + Sampler — pemutaran sampel berbasis pad dengan envelope pitch/filter/amp per-pad. Sampel disimpan di IndexedDB untuk recall cepat. 5 kit pabrik khusus genre (boombap, trap, house, dnb, afrobeat).

SeedSynth + Geist (di dalam AudioStudioEngine lama — kini digabungkan ke Soundbend sejak Wave 14) — generator patch genetik (Synplant 2-class) dan mesin drum gaya Geist. Ini adalah IP proprietary yang membuat doktrin konsolidasi menjadi besar — kami harus mempertahankan perilaku identik bit melalui penggabungan 30k baris. Uji nol 100-seed berhasil setelah penggabungan.

6. Mixer + pengiriman aux

Mixer yang sebenarnya — bukan hanya fader per trek tetapi juga slot FX per trek, kirim aux sebelum/sesudah fader, bus master — adalah yang membedakan DAW dari sequencer. Mixer kelas Soundbend adalah ~655 LOC (src/audio/mixer.js). Setiap trek adalah grafik AudioNode dengan slot insert, titik tap kirim, dan metering.

Bagian yang rumit adalah pre-fader vs post-fader aux sends. Pre-fader mengirim ke bus reverb terlepas dari volume trek (penggunaan klasik: parallel reverb yang bertahan saat trek diputihkan). Post-fader berbanding lurus dengan volume trek. Keduanya sudah tersedia.

7. MIDI + WAM plugin host

WebMIDI sudah matang — input kontroler dari keyboard USB-MIDI apa pun berfungsi dengan baik. Rak MIDI kami (Arpeggiator, Skala, Kord) berada di antara kontroler dan instrumen, mengubah aliran not.

Untuk plugin, kami menyediakan Web Audio Modules v2 (WAM) — plugin native browser. Ekosistem lebih kecil dibanding VST (keunggulan 25 tahun) tetapi berkembang. Memuat WAM dilakukan dengan getWamHost().load(wamUri) yang mengembalikan AudioNode yang dapat dimasukkan ke dalam rantai apa pun.

WAMs memerlukan CSP per-rute karena memuat JS yang disediakan pengguna secara arbitrer. Kami _headers mengkapsulasi CSP secara ketat untuk /soundbend dengan daftar izin script-src untuk registri WAM terkenal.

8. OfflineAudioContext untuk bounce

Ekspor berjalan melalui OfflineAudioContext — render lebih cepat dari real-time (atau lebih lambat, tergantung kompleksitas rantai) ke AudioBuffer statis, lalu encode ke WAV menggunakan enkoder di browser kami.

Catatan: tidak semua node bekerja di OfflineAudioContext. MediaStreamAudioSourceNode tidak (tidak bisa merekam mikrofon langsung secara offline, tentu saja). Beberapa worklet membutuhkan reset state hati-hati antara transisi online → offline. Kami mengalami hal ini berulang kali dan sekarang Mixer.toJSON() + Mixer.fromJSON(offlineCtx) adalah pola standar: serialisasi status mixer, bangun kembali mixer paralel di konteks offline, render.

9. Kolaborasi via Yjs

Yjs adalah pustaka CRDT yang menangani pengeditan kolaboratif multi-pengguna dengan penyelesaian konflik otomatis. Kelas SoundbendSession kami membungkus Yjs dengan struktur dokumen per trek (Y.Map untuk metadata trek, Y.Array untuk langkah pola, Y.Text untuk lirik/catatan).

Dua hingga empat produser dapat mengedit proyek yang sama secara bersamaan dengan sinkronisasi trek akurat sampai sampel. Ini lebih sulit daripada kolaborasi dokumen teks karena data audio jauh lebih besar — kami berbagi metadata + pola melalui Yjs, bukan audio mentah. Sampel mentah tetap lokal (IndexedDB per pengguna).

10. Anggaran kinerja

Menjalankan DAW lengkap di browser dengan UI 60fps + audio real-time + SharedArrayBuffer + WASM + beberapa worklet memerlukan anggaran ketat. Beberapa angka:

11. Harness pengujian null

Regresi DSP diam — audio terdengar berbeda dengan cara halus yang tidak bisa terdeteksi melalui review kode. Soundbend dilengkapi dengan alat pengujian null yang dikendalikan Puppeteer di tests/audio-null/.

Untuk setiap efek × preset × sinyal uji, harness dirender melalui OfflineAudioContext di dalam Chromium headless, null-test hasil WAV terhadap golden yang telah ditetapkan, dan gagal membangun jika puncak residu melebihi -60 dBFS.

Wave 14F menambahkan 100 seed baselines SeedSynth dan 32 goldens pola drum Geist. Saat kami menggabungkan Soundbend ke AudioStudio (Wave 14B-G), null-test menangkap apa pun yang akan secara diam-diam merusak instrumen proprietary. 96 dari 100 seed SeedSynth lulus bit-identik. 4 kegagalan adalah masalah yang sudah ada sebelumnya pada kelemahan Chromium Web Audio (drift resonansi filter high-Q antara instance OfflineAudioContext) — bukan regresi penggabungan, dan tidak dapat diperbaiki dari JS.

Regresi DSP diam. Tinjauan kode tidak bisa mendengarnya. Alat uji null dapat — itulah mengapa itu menghentikan CI.

12. Mengapa browser + client-side adalah pilihan yang tepat

DAW native (Ableton, Logic, FL Studio) memiliki keunggulan 30 tahun. Mengalahkan mereka fitur demi fitur adalah jalan panjang. Namun harga — itu bisa dimenangkan segera dengan membuat pilihan arsitektur yang berbeda.

WebAssembly melewati ambang kinerja pada 2022-2024. Web Audio AudioWorklets dirilis secara luas sekitar waktu yang sama. SharedArrayBuffer + COOP/COEP stabil. Chromium + Firefox + Safari semua mendukung API yang diperlukan dengan kinerja yang memadai.

Implikasi harga: jika pemrosesan audio berjalan di perangkat pengguna, kami tidak membayar untuknya. Biaya marginal per pelanggan Pro kami mendekati nol. Jadi $4.99/bulan berkelanjutan selamanya. Seorang anak di Lagos dengan Android 2020 mendapatkan DAW lengkap yang sama dengan orang di San Francisco membayar $4.99 yang sama untuk mengakses.

Baca esai arsitektur harga untuk ekonomi. Untuk DSP, itu sebagian besar cerita.

Coba sekarang

Soundbend berada di morph.cool/soundbend. Tier gratis berfungsi tanpa pendaftaran. $4.99/bulan Pro membuka rantai mastering + limiter true-peak + preset tambahan. Keyboard WebMIDI welcome, tidak diperlukan.

Buka Soundbend

— Hayden + tim agen Morph
22 April 2026