Morph Blog
Mühendislik

Tarayıcınızda bir DAW nasıl inşa edildi .

Soundbend, WebAssembly, Web Audio API ve 25 yıllık DSP araştırması üzerinde çalışır — tümü istemci tarafında. Tam mühendislik hikayesi: ses grafiği, worklet'ler, Airwindows portları, gerçek zirve limitleyici, eklenti hostu.

YAZAN HAYDEN SIMERLY12 DAKIKA OKUNMA2026 NİSANINDA GÜNCELLENDİ

This is a technical post about how Morph's Soundbend — a full digital audio workstation including 5 native instruments, a Mixer with FX chains and aux sends, 30+ effects (including 5 Airwindows Tier-1 ports and a true-peak limiter), a MIDI effects rack, a WAM v2 plugin host, and a Yjs CRDT collaboration layer — runs entirely in a browser tab.

Pratik soru şu: bu gerçekte Ableton ile rekabet ediyor mu? Dürüst cevap: çoğu üretici akışı için evet. Derin Max for Live entegrasyonları için henüz değil. Ürün seviyesinde ayrıntılı karşılaştırma için Ableton alternatifi karşılaştırmasına bakın. Bu yazı mühendislik seviyesindedir.

Yığın

1. Ses grafiği

Her ses parçası Soundbend'de bir zincire yönlendirilir: enstrüman → izleme FX zinciri → aux gönderim → Mezat şeridi → ana bant → limitör → hedef. Her ok, bir Web Audio AudioNode bağlantısıdır.

Web Audio bize AudioContext, GainNode, BiquadFilterNode, ConvolverNode, AnalyserNode ve arkadaşlarını verir. Bu, tarayıcı motorları tarafından optimize edilmiştir (V8/SpiderMonkey/JSC hepsi derinlemesine yatırım yapmıştır). Standart etkiler için — EQ, gain otomasyonu, temel filtreleme — yerel düğümleri kullanıyoruz. Hızlı ve iyi test edilmişlerdir.

Özel efektler için — Airwindows portları, doyurma efekti, gerçek zirve sınırlayıcılarımız — AudioWorkletProcessor kullanıyoruz, bu da ses işlenmesi üzerinde çalışır, gerçek zamanlı öncelik garantisiyle ve standart olmayan DSP için doğru mimari yerdir.

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, public/audio-worklets/*.js içinde gönderilir ve audioContext.audioWorklet.addModule(path) aracılığıyla yüklenir. Yüklenen bir kısım, herhangi bir bölüm AudioWorkletNode için bu işlemciyi başlatır. İşleme ana iş parçacığı dışında çalışır — UI animasyonları sesi açmaz.

2. 5 Airwindows Tier-1 portu

Chris Johnson's Airwindows, 2.500+ ses eklentisi, MIT lisanslı, efsanevi lezzetli DSP'dir. Soundbend'in Wave 12 sürümü için 5 tanesini tarayıcı AudioWorklets'a aktardık:

Her port, AudioWorkletProcessor'ta matematikten ~30-80 LOC'dur. Portlar, Airwindows ile bit-for-bit eşleşmez (C++ ve JS sayısal motorları arasında farklı FMA/denormal işleme), ancak ses olarak eşleşir. Null-testler, çıktıları altınlar karşı -80 dBFS kalıntısı ≤ tutar, bu yüzden DSP değişiklikleri yakalanır.

3. Gerçek tepe sınırlandırıcı

Modern akış platformları (Spotify, Apple Music, YouTube) ITU-R BS.1770-5'e göre gerçek zirve seslilik normalizasyonunu zorunlu kılar. Örnek zirveleri ve örnekler arası zirveler farklı şeylerdir; bir sinyal örnek seviyesinde -1 dBFS'ye ulaşabilir ancak D/A dönüştürme sonrası 0 dBFS'i aşabilir. Gerçek zirve sınırlayıcı olmayan bir sınırlayıcı DAC'de kesilebilir, ancak DAW'niz temiz gösterir.

Sınırlayıcı, tam ITU spesifikasyonunu uygular: 4x örnekleme, inter-örnek tepe algılama, öngörü, yumuşak-knee serbest bırakma. AudioWorklet formunda public/audio-worklets/true-peak-limiter-processor.js konumunda gönderilir. Referans uygulamalarına (Oxford Limiter, iZotope Ozone Maximizer) karşı ölçümler, LUFS entegre olarak 0.1 dB içinde eşleşir.

4. Off-main-thread communication

Ses grafiği ses işlenmesi thread'inde çalışır. Kullanıcı arayüzü ana thread'de çalışır. Parametre değişiklikleri (bir düğmeyi döndürmek, bir izi fade etmek) UI → ses arasında glitch olmadan iletilmelidir.

Web Audio'nun AudioParam özelliği, standart parametreler için (GainNode gain, BiquadFilterNode frequency) doğal olarak işler. Özel worklet parametreleri için, UI mesajları için MessagePort kullanıyoruz ve yüksek hızda otomasyon verisi için SharedArrayBuffer tabanlı ring buffer'lar kullanıyoruz.

SharedArrayBuffer, Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp başlıkları gerektirir. Bu başlıklar, public/_headers dosyasında /soundbend ve /pulse rotaları için ayarlanmıştır. Tape Delay, mesaj-port gecikmesini önlemek için 96kHz'de bir ring buffer kullanır.

5. 5 temel enstrüman

Soundbend 5 özel enstrümanla gelir:

FM Sentez — DX7 / Operator üzerinde modellenmiş 6-çıkışlı FM sentezi. Algoritma görselleştirici + tam modülasyon matrisi. UI için ~800 LOC JS, ses ayırıcı için ~300 LOC worklet.

Wavetable Synth — morph-between-tables sentezleme. Spektral çarpma + unison + stereo detune. 30'dan fazla fabrika wavetable'i. Wavetable çapraz geçişi ses hızında yapmak için ConvolverNode kullanır.

Analog Subtractive — 2 osilatörlü polisint, Cytomic SVF filtreleriyle. Cytomic, doğru ses veren durum-değişken filtre topolojisidir; naif SVF, fc > SR/6 üzerinde sese karışıklık yaratır. Cytomic port, bu sorunu sıfır gecikmeli geri besleme matematiği ile çözer.

DrumRack + Sampler — perde tabanlı örnek oynatma, her perde için ses tonu/filtre/güç envanterleri. Örnekler IndexedDB'de saklanarak hızlı çağırma sağlanır. 5 tür spesifik fabrika kiti (boombap, trap, house, dnb, afrobeat).

SeedSynth + Geist (eski AudioStudioEngine'de — Wave 14 ile Soundbend'e entegre edildi) — genetik bir parçalama üretici (Synplant 2-sınıf) ve Geist tarzı davul makinesi. Bu, konsolidasyon doktrini için önemli olan patentli IP'lerdir — 30.000 satırlık bir birleştirmeden sonra bit-aynı davranışı korumak zorundaydık. Birleşmeden sonra 100-seed null-testi başarıyla geçildi.

6. Mixer + yardımcı gönderimler

Bir DAW'ı bir sekansörden ayıran, sadece izleme çubukları değil, her izleme için FX eklemeleri, öncesi/sonrası fader yardımcı gönderimleri ve ana bus olan gerçek bir Mixer'dır. Soundbend'in Mixer sınıfı ~655 LOC (src/audio/mixer.js). Her izleme, eklemeler için slotlar, gönderim noktaları ve ölçümleme ile bir AudioNode grafiğidir.

Zor kısım, ön-fader ve arka-fader aux gönderimleridir. Ön-fader, izleme sesi seviyesi değişse bile bir reverb bus'a gönderir (klasik kullanım: izleme sesi azaldığında bile devam eden paralel reverb). Arka-fader, izleme sesi seviyesiyle orantılıdır. Her ikisi de mevcuttur.

7. MIDI + WAM eklenti sunucusu

WebMIDI olgunlaşmış — her USB-MIDI klavyeden kontrolcü girişi tamamen çalışır. MIDI kütüphanemiz (Arpeggiator, Scale, Chord), kontrolcü ile enstrüman arasında not akışlarını dönüştürür.

Eklentiler için, Web Audio Modules v2 (WAM) barındırıyoruz — tarayıcıya özgü eklentiler. VST'den (25 yıllık başlangıç avantajı) daha küçük bir ekosistem olsa da büyüyor. Bir WAM yüklemek getWamHost().load(wamUri) şeklindedir, bu da herhangi bir zincire ekleyebileceğiniz bir AudioNode döndürür.

WAM'ler, her yol için CSP gerektirir çünkü kullanıcı tarafından sağlanan isteğe bağlı JS yükler. Bizim _headers dosyamız, /soundbend için script-src izin listesiyle CSP'yi sıkı bir şekilde scope'lar ve bilinen WAM kayıt sistemlerine izin verir.

8. OfflineAudioContext için bounce

Export, OfflineAudioContext üzerinden çalışır — zincir karmaşıklığına göre gerçek zamanın üstünde (veya altında) hızla render edilir, statik AudioBuffer’a kaydedilir ve ardından tarayıcı içindeki kodlayıcı ile WAV formatına dönüştürülür.

Kapanış: OfflineAudioContext içinde tüm düğümler çalışmaz. MediaStreamAudioSourceNode çalışmaz (açıkça canlı mikrofon kaydı çevrimdışı olamaz). Bazı çalışmaçıkları, çevrimiçi → çevrimdışı geçişler arasında dikkatli durum sıfırlama gerektirir. Bu sorunu tekrar tekrar yaşadık ve şimdi Mixer.toJSON() + Mixer.fromJSON(offlineCtx) kanonik desen olarak kabul edilir: karıştırıcı durumunu serileştirin, çevrimdışı bağlamda paralel bir karıştırıcı oluşturun, render edin.

9. Yjs ile İşbirliği

Yjs, çoklu kullanıcı işbirliği düzenlemesini otomatik çakışma çözme ile yöneten bir CRDT kütüphanesidir. SoundbendSession sınıfımız, Yjs'i her izleme için belge yapısı (Y.Map izleme meta verisi için, Y.Array desen adımları için, Y.Text sözler/notlar için) ile sarar.

İki ila dört üretici aynı projeyi aynı anda örnek doğruluğunda ses senkronizasyonuyla düzenleyebilir. Bu, metin belgesi işbirliği yapmaktan daha zordur çünkü ses verisi milyonlarca kat daha büyüktür — biz ham sesi değil, meta veri ve desenleri Yjs aracılığıyla paylaşıyoruz. Ham örnekler yerel olarak kalır (her kullanıcı için IndexedDB).

10. Performans bütçesi

Tarayıcıda tam bir DAW çalıştırma, 60fps UI + gerçek zamanlı ses + SharedArrayBuffer + WASM + birden fazla worklet gerektirir, sıkı bütçeler gereklidir. Bazı sayılar:

11. Null-test kütüphanesi

DSP gerilemeleri sessizdir — ses kod incelemesiyle yakalanamayan ince değişikliklerle farklı bir şekilde duyulur. Soundbend, tests/audio-null/ içinde Puppeteer ile çalışan bir null-test kılavuzuyla birlikte gelir.

Her etki × ön ayar × test sinyali için, test aracı OfflineAudioContext kullanarak başsız Chromium içinde render eder, sonuç WAV'yi kayıtlı altın dosyaya karşı null-test eder ve residual tepe -60 dBFS'i aşarsa derlemeyi başarısız kılar.

Wave 14F, 100 SeedSynth tohum temelini ve 32 Geist davul deseni altın temelini ekledi. Soundbend'i AudioStudio (Wave 14B-G) ile birleştirdiğimizde, null-test, özel enstrümanları sessizce bozabilecek herhangi bir şeyi yakaladı. 100 SeedSynth tohumundan 96'sı bit-aynı şekilde geçti. 4 başarısızlık, önceden varolan Chromium Web Audio sorunlarından kaynaklandı (yüksek-Q filtre rezonans kayması OfflineAudioContext örnekleri arasında) — birleştirme gerilemeleri değil, ve JS ile düzeltilmezdi.

DSP gerilemeleri sessizdir. Kod incelemesi onları duyamaz. Null-test kavşağı bunu duyabilir — bu yüzden CI engelleyicidir.

12. Tarayıcı + istemci tarafı doğru seçim oldu

Doğal DAW'lar (Ableton, Logic, FL Studio) 30 yıllık bir başlangıç avantajına sahip. Onları özellikler açısından yenebilmek uzun bir yol. Ancak fiyatlandırma — bu, farklı mimari yatırımlar yaparak hemen kazanılabilir bir alan.

WebAssembly, 2022-2024 yılları arasında performans eşiğine ulaştı. Web Audio AudioWorklets, aynı dönemde yaygın olarak yayınlandı. SharedArrayBuffer + COOP/COEP stabil hale geldi. Chromium, Firefox ve Safari, gerekli API'leri yeterli performansla destekliyor.

Fiyatlandırma etkisi: ses işleme kullanıcı cihazında çalışıyorsa, biz ödeme yapmıyoruz. Pro aboneliğimizin marjinal maliyeti neredeyse sıfırdır. Bu yüzden $4.99/ay sürdürülebilir sonsuzca. Lagos'ta 2020 Android cihazına sahip bir çocuk, San Francisco'da yaşayan birinin aynı $4.99 ödeyerek eriştiği tam bir DAW'a sahip olur.

Ekonomik yapısını anlamak için fiyatlandırma mimarisi makalesini okuyun. DSP için bu, hikayenin çoğudır.

Deneyin

Soundbend, morph.cool/soundbend adresindedir. Ücretsiz sürümü kayıt olmadan çalışır. $4.99/ay Pro, mastering zinciri + gerçek tepe limitörü + ekstra ön ayarları etkinleştirir. WebMIDI klavyesi hoşgeldin, gerekli değildir.

Soundbend'i Aç

— Hayden ve Morph ajan ekibi
22 Nisan 2026