Це технічний пост про те, як Morph Soundbend — повний цифровий аудіо-студія, що включає 5 вбудованих інструментів, мікшер з ефектами та допоміжними каналами, 30+ ефектів (включаючи 5 портів Airwindows Tier-1 та справжній лімітер true-peak), розкладку MIDI-ефектів, хост відповідного плагіна WAM v2 та шар спільної роботи на основі Yjs CRDT — працює виключно в вікні браузера.
Практичне питання: чи є це дійсно конкурентоспроможним з Ableton? Щирі відповіді: для більшості робочих процесів продюсерів — так. Для глибоких інтеграцій Max for Live — ще ні. Прочитайте порівняння з Ableton для детального аналізу продукту. Цей пост — інженерний.
Стек
- React + Vite frontend
- Web Audio API для аудіо-графу
- AudioWorkletProcessor для власних DSP (поза головним потоком)
- WebAssembly для високопродуктивної DSP (власні збірки WASM)
- MessagePort + ring buffers для комунікації UI ↔ worklet
- Yjs для CRDT-співпраці
- IndexedDB для зберігання проектів та зразків
- WebMIDI для введення даних з апаратних контролерів
- OfflineAudioContext для bounce/export
1. Аудіограф
Кожна трек у Soundbend проходить через ланцюг: інструмент → ланцюг ефектів треку → aux send → смуга мікшера → головний бус → лімітер → призначення. Кожна стрілка є з'єднанням Web Audio AudioNode.
Web Audio надає нам AudioContext, GainNode, BiquadFilterNode, ConvolverNode, AnalyserNode та інші. Ці компоненти оптимізовані рушіями браузерів (V8/SpiderMonkey/JSC глибоко інвестують у це). Для стандартних ефектів — EQ, автоматизація гучності, базове фільтрування — ми використовуємо вбудовані вузли. Вони є швидкими та добре протестованими.
Для нестандартних ефектів — порти Airwindows, наша насиченість, наш справжній лімітер піків — ми використовуємо AudioWorkletProcessor, який працює на аудіо-потоці, гарантовано з реальним пріоритетом, і є правильним архітектурним місцем для нестандартних DSP.
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 і завантажуються через audioContext.audioWorklet.addModule(path). Після завантаження будь-яка частина графіка може ініціювати AudioWorkletNode для цього процесора. Обробка виконується на окремому потоці — інтерфейс не блокує аудіо.
2. 5 портів Tier-1 Airwindows
Chris Johnson's Airwindows — це 2 500+ аудіо-плагінів, ліцензія MIT, легендарно смаковитий DSP. Ми перенесли 5 до браузерних AudioWorklets для Wave 12 у Soundbend:
- Pressure6 — прозоре стиснення, що дихає
- ToTape9 — моделювання аналогового тапового насичення
- PurestDrive — мінімальна фазова насиченість без різких високих частот
- CreamCoat — тепло + гармонічний екситер
- NotJustAnotherDither — TPDF дітер для зниження глибини біту (мастеринг)
Кожен порт — це ~30-80 рядків коду математики в AudioWorkletProcessor. Порти не відповідають Airwindows біт-за-бітом (різні способи обробки FMA/денормалізації між C++ і JS числовими двигунами), але відповідають звучанню. Тести на нуль зберігають вихідні сигнали ≤ -80 dBFS залишкові від золотих стандартів, тому зміни DSP виявлені.
3. Істинний лімітер піків
Сучасні стрімінгові платформи (Spotify, Apple Music, YouTube) вимагають істинної пікової нормалізації гучності за ITU-R BS.1770-5. Пікові значення і міжпікові піки — це різні речі; сигнал може досягати -1 dBFS по кожному зразку, але перевищувати 0 dBFS істинного пікового після перетворення D/A. Нелімітатор істинного пікового буде обрізати в DAC, навіть якщо ваш DAW показує, що все чисто.
Наш лімітер реалізує повний стандарт ITU: 4x зразування, детекція міжзразкових піків, попереднє виявлення, м'яке відпускання. Він постачається у формі AudioWorklet за шляхом public/audio-worklets/true-peak-limiter-processor.js. Вимірювання відповідно до референсних реалізацій (Oxford Limiter, iZotope Ozone Maximizer) збігаються з точністю до 0.1 dB за LUFS інтегрованого.
4. Комунікація за межами основного потоку
Аудіографічний процесор працює на аудіо-потоці, інтерфейс користувача — на головному потоці. Зміни параметрів (повернути регулятор, змінити гучність треку) повинні передаватися від інтерфейсу до аудіо без перерв у звуці.
Web Audio використовує AudioParam для стандартних параметрів (GainNode gain, BiquadFilterNode frequency) безпосередньо. Для спеціальних робіт з використанням власних вузлів, ми застосовуємо MessagePort зі структурованим клонуванням для повідомлень інтерфейсу, а також SharedArrayBuffer-підтримку для буферів з циклічним записом для високочастотних даних автоматизації.
SharedArrayBuffer вимагає Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp заголовків. Ці заголовки встановлені в public/_headers для /soundbend + /pulse маршрутів. Tape Delay використовує коловий буфер на 96 кГц для уникнення затримки порту повідомлень.
5. 5 нативних інструментів
Soundbend надає 5 інструментів, всі спеціальні:
FM Synth — 6-операторна FM-синтез, моделювана на DX7 / Operator. Візуалізатор алгоритму + повна матриця модуляції. ~800 LOC JS для інтерфейсу, ~300 LOC для робот-коду голосового розподілювача.
Wavetable Synth — синтез, що використовує перехід між таблицями. Спектральне викривлення + унісон + стерео детюн. 30+ заводських вейвтейблів. Використовує ConvolverNode для перехідного змішування вейвтейблів на аудіо-частоті.
Аналоговий віднімний — полісінтез з 2 осциляторами та фільтрами Cytomic SVF. Cytomic — це топологія фільтра змінної частоти, яка звучить правильно; наївний SVF має проблеми з алиасингом при fc > SR/6. Cytomic порт вирішує це за допомогою математики нульового затримки.
DrumRack + Sampler — відтворення зразків за допомогою падів із налаштуванням під кожен пад: висота, фільтр, гучність. Зразки зберігаються в IndexedDB для швидкого виклику. 5 заводських наборів за жанрами (boombap, trap, house, dnb, afrobeat).
SeedSynth + Geist (у спадковому AudioStudioEngine — тепер об'єднано в Soundbend з версії Wave 14) — генетичний генератор патчів (Synplant 2-клас) та барабанна машинка стилю Geist. Це пропрієтарний IP, який зробив консолідаційну доктрину важливою — ми повинні бути зберегти біт-ідентичну поведінку під час об'єднання 30 тис. рядків коду. Пройдено 100-сімейний нуль-тест після об'єднання.
6. Міксер + допоміжні виходи
Справжній Mixer — не просто регулятори гучності на кожній дорозі, але вставки ефектів на кожній дорозі, преред/пост-фейдерні допоміжні відправлення, головний бус — це те, що відрізняє DAW від sequencer. Mixer клас Soundbend ~655 LOC (src/audio/mixer.js). Кожна доріжка є графом AudioNode з точками вставки, точками відправлення та вимірюванням.
Складна частина — це передфейдерні та післяфейдерні допоміжні виходи. Передфейдерні виходи надсилають сигнал на бус звукового ефекту незалежно від гучності треку (класичне використання: паралельний ревербератор, який залишається під час зміни гучності треку). Післяфейдерні змінюються разом з гучністю треку. Обидва типи встановлені.
7. MIDI + WAM-хост плагінів
WebMIDI дозрів — вхідний контролер з будь-якого USB-MIDI клавіатури працює без проблем. Наша MIDI-стійка (Арпеджіатор, Шкала, Аккорд) розташована між контролером та інструментом, перетворюючи потоки нот.
Для плагінів ми хостимо Web Audio Modules v2 (WAM) — плагіни, які працюють безпосередньо в браузері. Екосистема менша, ніж у VST (25-річний головний перевага), але росте. Завантаження WAM відбувається за допомогою getWamHost().load(wamUri), що повертає AudioNode, який можна вставити в будь-яку ланцюг.
WAMs вимагають перерозподілу CSP для кожного маршруту, оскільки вони завантажують довільний користувацький JS. Наші _headers обмежують CSP вузько для /soundbend з дозволом script-src для відомих реєстрів WAM.
8. OfflineAudioContext для bounce
Експорт працює через OfflineAudioContext — відтворення швидше, ніж в реальному часі (або повільніше, залежно від складності ланцюга), до статичного AudioBuffer, потім кодування до WAV за допомогою нашого вбудованого кодувальника.
Підказка: не всі вузли працюють у OfflineAudioContext. MediaStreamAudioSourceNode не працює (нічого не можна записати від живого мікрофона офлайн, звичайно). Деякі ворклети потребують уважного скидання стану під час переходу від онлайн до офлайн. Ми не раз стикалися з цим і тепер Mixer.toJSON() + Mixer.fromJSON(offlineCtx) є канонічним способом: серіалізуємо стан мікшера, створюємо паралельний мікшер у офлайн-контексті, відтворюємо.
9. Спільна робота через Yjs
Yjs — це бібліотека CRDT, яка забезпечує спільне редагування з автоматичним вирішенням конфліктів. Наш клас SoundbendSession обгортає Yjs зі структурою документа на рівні треків (Y.Map для метаданих треку, Y.Array для кроків патерну, Y.Text для тексту пісні/нот).
Два-чотири продюсери можуть одночасно редагувати один і той самий проект із синхронізацією на рівні зразка. Це складніше, ніж спільна робота з текстовими документами, оскільки дані аудіо на порядки більші — ми ділимося метаданими та шаблонами через Yjs, а не сирими аудіофайлами. Сирі зразки залишаються локально (IndexedDB для кожного користувача).
10. Бюджет продуктивності
Запуск повної DAW у браузері з 60fps UI + реальним часом аудіо + SharedArrayBuffer + WASM + кількома worklets вимагає тісного бюджету. Деякі числа:
- Аудіо-потік: ~2ms / буфер 128 зразків при 48kHz (під-фрейм)
- Головний потік: 16,6 мс / 60 кадрів на секунду; обробка аудіо повинна залишатися <1 мс на кадр
- Налаштування Worklet: одноразова вартість ~10-50 мс на завантаження worklet (відправте 15+ worklet — ми групуємо)
- Розподіл SharedArrayBuffer: 4KB кільцеві буфери на кожен динамічний параметр worklet
- Розмір фрагмента Soundbend (після консолідації): ~496 КБ сирого, ~120 КБ gzip
- Повне завантаження проекту (холодний старт): ~800 мс на середньомірному ноутбуці
- Експорт: ~0,3x до 2x реального часу залежно від складності ланцюга ефектів
11. Тестовий інструмент для нуль-тестування
DSP-регресії є тихими — аудіо звучить по-різному в тонких аспектах, які не можна виявити під час перевірки коду. Soundbend постачається з нульовим тестовим комплексом, що працює на Puppeteer, у tests/audio-null/.
Для кожного ефекту × зразка × тестового сигналу, засоби тестування відтворюються через OfflineAudioContext у безголовому Chromium, нуль-тестують отриманий WAV проти збереженого золотого, і завершують будівлю, якщо залишковий пік перевищує -60 dBFS.
Wave 14F додав 100 базових ліній SeedSynth та 32 золотих патернів для барабанів Geist. Коли ми об’єднали Soundbend у AudioStudio (Wave 14B-G), нуль-тест виявив все, що могло б тихо порушити пропрієтарні інструменти. 96 з 100 базових ліній SeedSynth пройшли перевірку збігу бітів. 4 помилки були попередніми помилками Chromium Web Audio (дрейф резонансу високої якості між екземплярами OfflineAudioContext) — не регресії під час об’єднання, і не виправимі з JavaScript.
DSP-регресії тихі. Перегляд коду їх не чує. Нуль-тестовий інструмент може — тому він блокує CI.
12. Чому браузер + клієнтська сторона була правильною вибором
Нативні DAW (Ableton, Logic, FL Studio) мають 30-річний перевагу. Переборювати їх функціонально по-кожній — довгий шлях. Але ціна — це було можливо перемогти відразу, зробивши інші архітектурні ставки.
WebAssembly перетнув поріг продуктивності у 2022-2024 роках. Web Audio AudioWorklets широко випущені приблизно в той самий час. SharedArrayBuffer + COOP/COEP стабілізувався. Chromium, Firefox та Safari всі підтримують необхідні API з достатньою продуктивністю.
Вплив ціноутворення: якщо обробка аудіо відбувається на пристрої користувача, ми не платимо за це. Наша гранична вартість для кожного Pro-користувача наближається до нуля. Тому $4.99/міс є стійким навіки. Хлопчик у Лагосі з Android 2020 року отримує повний DAW, який хтось у Сан-Франциско платить ті ж $4.99 для доступу.
Прочитайте есей про архітектуру цін, щоб зрозуміти економіку. Для DSP це більшість історії.
Спробуйте
Soundbend знаходиться за посиланням morph.cool/soundbend. Безкоштовний рівень працює без реєстрації. $4.99/міс. Pro розкриває доступ до ланцюга майстрового оброблення + справжнього лімітера пікового рівня + додаткових попередньо налаштованих налаштувань. WebMIDI-клавіатура вітається, але не обов'язкова.
— Хейден та команда агента Morph
22 квітня 2026 р.