Morph Blog
Phát triển

Làm thế nào chúng tôi xây dựng một DAW trong trình duyệt của bạn.

Soundbend chạy trên WebAssembly, Web Audio API và 25 năm nghiên cứu DSP — tất cả bên phía client. Câu chuyện kỹ thuật đầy đủ: đồ thị âm thanh, worklets, port từ Airwindows, bộ giới hạn đỉnh chính xác, host plugin.

Bởi HAYDEN SIMERLY12 PHÚT ĐỌCCẬP NHẬT THÁNG 4 NĂM 2026

Đây là một bài viết kỹ thuật về cách Morph's Soundbend — một hệ thống sản xuất âm thanh kỹ thuật số đầy đủ bao gồm 5 nhạc cụ bản địa, một Mixer với chuỗi hiệu ứng và gửi aux, 30+ hiệu ứng (bao gồm 5 bản port Tier-1 của Airwindows và một limiter true-peak), một rack hiệu ứng MIDI, một trình chủ plugin WAM v2, và một lớp hợp tác Yjs CRDT — chạy hoàn toàn trong một tab trình duyệt.

Câu hỏi thực tế là: liệu đây có thực sự cạnh tranh với Ableton không? Câu trả lời thành thật: đối với hầu hết quy trình sản xuất, có. Đối với tích hợp sâu với Max for Live, chưa. Đọc so sánh với Ableton để xem phân tích cấp sản phẩm. Bài viết này là về kỹ thuật.

Cơ sở kỹ thuật

1. Đồ thị âm thanh

Mỗi track trong Soundbend đều đi qua chuỗi: instrument → track FX chain → aux send → Mixer strip → master bus → limiter → destination. Mỗi mũi tên là kết nối Web Audio AudioNode.

Web Audio cung cấp cho chúng tôi AudioContext, GainNode, BiquadFilterNode, ConvolverNode, AnalyserNode và các thành phần khác. Những thành phần này được tối ưu hóa bởi các trình duyệt (V8/SpiderMonkey/JSC đều đầu tư sâu). Đối với các hiệu ứng chuẩn — EQ, điều chỉnh âm lượng tự động, lọc cơ bản — chúng tôi sử dụng các nút gốc. Chúng rất nhanh và đã được kiểm thử kỹ lưỡng.

Đối với các hiệu ứng đặc biệt — các bản port của Airwindows, độ bão hòa của chúng tôi, bộ giới hạn đỉnh thực của chúng tôi — chúng tôi sử dụng AudioWorkletProcessor, chạy trên luồng âm thanh, đảm bảo ưu tiên thời gian thực, và đây là vị trí kiến trúc đúng cho DSP không chuẩn.

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 được gửi trong public/audio-worklets/*.js và tải qua audioContext.audioWorklet.addModule(path). Sau khi tải, bất kỳ phần nào của đồ thị cũng có thể khởi tạo một AudioWorkletNode cho bộ xử lý đó. Xử lý chạy ngoài luồng chính — các hoạt động hình ảnh UI không làm chậm âm thanh.

2. Các cổng Tier-1 Airwindows 5

Chris Johnson's Airwindows là 2.500+ plugin âm thanh, cấp giấy phép MIT, xử lý DSP nổi tiếng về tính thẩm mỹ. Chúng tôi đã chuyển 5 plugin này sang AudioWorklets cho Wave 12 trong Soundbend:

Mỗi cổng là ~30-80 LOC toán học trong AudioWorkletProcessor. Các cổng không khớp bit-for-bit với Airwindows (khác biệt trong xử lý FMA/độ chính xác thấp giữa động cơ số học C++ và JS) nhưng khớp về âm thanh. Các kiểm tra null giữ đầu ra ≤ -80 dBFS residual so với goldens, để phát hiện thay đổi DSP.

3. Bộ giới hạn true-peak

Các nền tảng phát trực tuyến hiện đại (Spotify, Apple Music, YouTube) áp dụng chuẩn âm lượng true-peak theo ITU-R BS.1770-5. Đỉnh mẫu và đỉnh giữa các mẫu là hai khái niệm khác nhau; một tín hiệu có thể đạt đỉnh -1 dBFS về mặt mẫu nhưng vượt quá 0 dBFS true-peak sau khi tái tạo D/A. Bộ giới hạn không true-peak sẽ cắt tín hiệu ở DAC ngay cả khi DAW của bạn hiển thị nó sạch.

Bộ giới hạn của chúng tôi tuân thủ đầy đủ tiêu chuẩn ITU: 4x oversampling, phát hiện đỉnh inter-sample, lookahead, giải phóng mềm-knee. Nó được cung cấp dưới dạng AudioWorklet tại public/audio-worklets/true-peak-limiter-processor.js. Đo lường so với các triển khai tham chiếu (Oxford Limiter, iZotope Ozone Maximizer) khớp trong phạm vi 0.1 dB trên LUFS tích hợp.

4. Giao tiếp không chính tuyến

Đồ thị âm thanh chạy trên luồng âm thanh. Giao diện người dùng chạy trên luồng chính. Thay đổi thông số (xoay nút, làm mờ track) cần truyền từ UI → âm thanh mà không làm gián đoạn âm thanh.

Web Audio's AudioParam xử lý điều này một cách tự nhiên cho các tham số tiêu chuẩn (GainNode gain, BiquadFilterNode frequency). Đối với công việc tùy chỉnh, chúng tôi sử dụng MessagePort với việc sao chép cấu trúc cho tin nhắn UI, và SharedArrayBuffer-backed ring buffers cho dữ liệu tự động hóa tốc độ cao.

SharedArrayBuffer yêu cầu Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp headers. Các tiêu đề này được thiết lập trong public/_headers cho các tuyến /soundbend + /pulse. Tape Delay sử dụng bộ đệm vòng ở 96kHz để tránh độ trễ của message-port.

5. 5 nhạc cụ bản địa

Soundbend bao gồm 5 nhạc cụ, tất cả đều tùy chỉnh:

FM Synth — Tổng hợp FM 6 bộ điều khiển mô phỏng trên DX7 / Operator. Trình trực quan hóa thuật toán + ma trận điều chế đầy đủ. ~800 LOC JS cho giao diện người dùng, ~300 LOC worklet cho bộ phân bổ giọng.

Wavetable Synth — tổng hợp morph-between-tables. Warping phổ tần số + unison + stereo detune. 30+ bảng wavetable nhà máy. Sử dụng ConvolverNode để chuyển tiếp wavetable tại tốc độ âm thanh.

Analog Subtractive — polysynth 2-oscillator với bộ lọc Cytomic SVF. Cytomic là kiến trúc bộ lọc biến thể trạng thái (state-variable filter topology) tạo ra âm thanh chính xác; bộ lọc SVF thông thường có vấn đề nhiễu aliasing ở tần số cao hơn fc > SR/6. Cytomic port xử lý điều này bằng toán học feedback không trễ (zero-delay feedback).

DrumRack + Sampler — phát lại mẫu dựa trên pad với các thông số pitch/filter/amp cho từng pad. Mẫu được lưu trữ trong IndexedDB để truy xuất nhanh. 5 bộ mẫu sẵn có theo thể loại (boombap, trap, house, dnb, afrobeat).

SeedSynth + Geist (trong AudioStudioEngine cũ — đã được hợp nhất vào Soundbend từ Wave 14) — một trình tạo patch di truyền (Synplant 2-class) và máy đánh trống kiểu Geist. Đây là IP đặc quyền khiến lý thuyết hợp nhất trở nên nổi bật — chúng tôi phải bảo tồn hành vi giống bit qua việc hợp nhất 30.000 dòng mã. Kiểm thử 100 hạt null thành công sau hợp nhất.

6. Mixer + gửi phụ

Một Mixer chuyên nghiệp — không chỉ là các fader theo track mà còn là các FX insert theo track, gửi aux pre/post-fader, bus master — mới là điểm phân biệt giữa một DAW và một sequencer. Mixer của Soundbend có ~655 LOC (src/audio/mixer.js). Mỗi track là một đồ thị AudioNode với các khe cắm insert, điểm tap gửi, và đo lường.

Phần khó là gửi aux trước fader và sau fader. Gửi aux trước fader gửi đến bus reverb bất kể mức độ volume của track (cách sử dụng cổ điển: reverb song song tồn tại khi track được giảm volume). Gửi aux sau fader thay đổi theo volume track. Cả hai đều được tích hợp sẵn.

7. MIDI + WAM plugin host

WebMIDI đã trưởng thành — đầu vào điều khiển từ bất kỳ bàn phím USB-MIDI nào cũng hoạt động trơn tru. Rack MIDI của chúng tôi (Arpeggiator, Scale, Chord) nằm giữa bộ điều khiển và nhạc cụ, biến đổi luồng nốt.

Đối với plugin, chúng tôi cung cấp Web Audio Modules v2 (WAM) — plugin tích hợp sẵn trong trình duyệt. Hệ sinh thái nhỏ hơn VST (có 25 năm kinh nghiệm) nhưng đang phát triển. Tải WAM bằng cách sử dụng getWamHost().load(wamUri), trả về một AudioNode bạn có thể chèn vào bất kỳ chuỗi nào.

WAMs yêu cầu CSP theo từng tuyến vì chúng tải JS do người dùng cung cấp bất kỳ. Chúng tôi _headers giới hạn chặt chẽ CSP cho /soundbend với danh sách cho phép script-src cho các kho lưu trữ WAM nổi tiếng.

8. OfflineAudioContext cho bounce

Xuất file chạy qua OfflineAudioContext — render nhanh hơn thời gian thực (hoặc chậm hơn, tùy thuộc vào độ phức tạp của chuỗi) thành AudioBuffer tĩnh, sau đó mã hóa thành WAV bằng bộ mã hóa trong trình duyệt của chúng tôi.

Lưu ý: không phải tất cả các nút đều hoạt động trong OfflineAudioContext. MediaStreamAudioSourceNode không hoạt động (không thể ghi âm mic trực tiếp khi offline, tất nhiên). Một số worklet cần đặt lại trạng thái cẩn thận giữa các chuyển tiếp trực tuyến → ngoại tuyến. Chúng tôi đã gặp phải vấn đề này nhiều lần và bây giờ Mixer.toJSON() + Mixer.fromJSON(offlineCtx) là mẫu tiêu chuẩn: tuần tự hóa trạng thái mixer, xây dựng lại một mixer song song trên ngữ cảnh ngoại tuyến, sau đó xử lý.

9. Hợp tác qua Yjs

Yjs là thư viện CRDT xử lý chỉnh sửa hợp tác đa người dùng với giải quyết xung đột tự động. Lớp SoundbendSession của chúng tôi bao bọc Yjs với cấu trúc tài liệu theo từng track (Y.Map cho thông tin metadata track, Y.Array cho các bước pattern, Y.Text cho lời bài hát/ghi chú).

Hai đến bốn nhà sản xuất có thể chỉnh sửa cùng một dự án đồng thời với độ chính xác đồng bộ theo mẫu âm thanh. Điều này khó hơn hợp tác văn bản vì dữ liệu âm thanh lớn hơn hàng triệu lần — chúng tôi chia sẻ thông tin mô tả và mẫu qua Yjs, không phải dữ liệu âm thanh thô. Các mẫu thô được lưu cục bộ (IndexedDB cho từng người dùng).

10. Ngân sách hiệu năng

Chạy một DAW đầy đủ trong trình duyệt với giao diện 60fps + âm thanh thời gian thực + SharedArrayBuffer + WASM + nhiều worklet đòi hỏi ngân sách chặt chẽ. Một số số liệu:

11. Bộ kiểm thử Null

Các hồi quy DSP im lặng — âm thanh nghe khác biệt theo cách tinh tế mà kiểm tra mã không phát hiện được. Soundbend đi kèm với một hệ thống kiểm tra null được điều khiển bởi Puppeteer tại tests/audio-null/.

Với mỗi hiệu ứng × cài đặt trước × tín hiệu kiểm tra, hệ thống sẽ render qua OfflineAudioContext bên trong Chromium không giao diện, kiểm tra null kết quả WAV so với vàng đã commit, và thất bại xây dựng nếu đỉnh dư vượt quá -60 dBFS.

Wave 14F đã thêm 100 cơ sở hạt SeedSynth và 32 mẫu đập Geist vàng. Khi chúng tôi hợp nhất Soundbend vào AudioStudio (Wave 14B-G), kiểm tra null đã phát hiện bất kỳ điều gì có thể làm hỏng các công cụ đặc hữu một cách im lặng. 96 trong số 100 hạt SeedSynth đã vượt qua kiểm tra bit-identical. 4 lỗi là do các lỗi trước đây của Chromium Web Audio (hiện tượng trôi tần số cộng hưởng bộ lọc Q cao giữa các phiên OfflineAudioContext) — không phải là lỗi do hợp nhất, và không thể sửa bằng JS.

Các lỗi DSP không phát ra âm thanh. Việc xem xét mã không thể nghe thấy chúng. Bộ kiểm tra null mới có thể — đó là lý do nó chặn CI.

12. Tại sao trình duyệt + client-side là lựa chọn đúng

Các DAW bản địa (Ableton, Logic, FL Studio) đã có 30 năm đầu tư. Đánh bại chúng từng tính năng là một hành trình dài. Nhưng giá cả — đó là điều có thể giành chiến thắng ngay lập tức bằng cách thực hiện những lựa chọn kiến trúc khác biệt.

WebAssembly vượt qua ngưỡng hiệu năng vào năm 2022-2024. Web Audio AudioWorklets được triển khai rộng rãi cùng thời điểm. SharedArrayBuffer + COOP/COEP được ổn định. Chromium + Firefox + Safari đều hỗ trợ các API cần thiết với hiệu năng đủ tốt.

Hệ quả về giá: nếu xử lý âm thanh chạy trên thiết bị người dùng, chúng tôi không phải trả phí. Chi phí biên cho mỗi khách hàng Pro gần như bằng không. Vì vậy, $4.99/tháng là bền vững mãi mãi. Một đứa trẻ ở Lagos với điện thoại Android 2020 có thể sử dụng một DAW đầy đủ, giống như người ở San Francisco trả cùng $4.99 để truy cập.

Đọc bài luận về kiến trúc giá cả để hiểu về kinh tế. Đối với DSP, đó là phần lớn câu chuyện.

Thử ngay

Soundbend có tại morph.cool/soundbend. Gói miễn phí hoạt động mà không cần đăng ký. Gói Pro $4.99/tháng mở khóa chuỗi mastering + limiter true-peak + cài đặt sẵn bổ sung. Bàn phím WebMIDI được chào đón, không bắt buộc.

Mở Soundbend

— Hayden + đội ngũ agent Morph
22 Tháng 4, 2026