Синтез аудио из двоичного кода любого файла
Демо: https://bs.stranno.su
Видео: https://youtu.be/5LMYiLwfvRg
Веб-синтезатор, генерирующий звук из двоичного кода любых файлов. Может синтезировать звук прямо в браузере, либо быть генератором MIDI-сообщений во внешние устройства или DAW, превращая любой файл в партитуру. Весь код приложения написан на Javascript и вместе со всем необходимым упаковывается в один .html файл размером около 750kb. Синтезатору не нужен интернет, его можно скачать и запускать локально на любом устройстве где есть браузер.
Приложение последовательно читает файл и за счёт высокой скорости чтения и случайной величины отклонения длительности чтения, мы можем получить достаточно непредсказуемую генерацию нюансов тембра, а при определённых настройках перейти в гранулярный синтез.
Вы можете попробовать несколько примеров настроек инструмента, которые будут звучать примерно одинаково для большинства файлов:
- Принцип работы
- Переход в гранулярный режим
- Рекомендации по оптимальной работе
- MIDI
- Интерфейс
- Сохранение настроек
- Запуск локально и сборка проекта
Все данные на любом компьютере или смартфоне представлены в виде файлов (являющихся, по своей сути, текстами). Содержанием этих файлов в конечном итоге являются просто нули и единицы. И эти нули и единицы, в общем-то, все одинаковые, поэтому нам нужен интерпретатор, для того чтобы извлечь смысл из этих текстов. Можно сказать, что формат файла (.mp3, .docx и т.д.) это просто указатель, какому интерпретатору надо передать текст, чтобы из него извлечь смысл.
Но что, если формат файла и интерпретатор не совпадают?
Что касается музыкальных экспериментов, то ранее были, например, попытки "воспроизвести" текстовый или иной файл через аудио-редактор.
Мы могли бы пойти дальше и написать собственный интерпретатор, который смотрел бы на файлы безотносительно формата, использовал собственную "манеру чтения" исходных нулей и единиц и на этой основе предоставлял полноценную систему управляемого синтеза звуков.
- Мы можем интерпретировать файлы как массив чисел. То есть, мы разбиваем непрерывный машинный код на слова некоторой информационной ёмкости (разрядности):
- 8 бит (числа от 0 до 255)
- 16 бит (числа от 0 до 65 535)
-
Тогда, каждое слово есть команда, определяющая частоту звука
-
На уровне всей системы мы задаём глобальные параметры:
- скорость интерпретации
- наличие случайной величины разброса скорости интерпретации
- музыкальный строй (или его отсутствие), диапазон нот/частот; по этому диапазону равномерно сопоставляются частоты по 256 или 65 536 возможным комбинациям нулей и единиц
- зацикленность воспроизведения
- режим MIDI
- плавный или резкий переход между командами
- настройки виртуальных устройств, необходимых для синтеза (осциллятор, фильтр, LFO), либо настройки MIDI
-
Чтобы снизить нагрузку на устройство, делим файл на куски по 500 команд
-
Рекурсивно планируем управление синтезом, читая по 500 команд в итерации и используя глобальные параметры
-
Если дошли до конца файла, прекращаем исполнение, либо начинаем заново
Note: Здесь и далее используются термины интерфейса инструмента. Их описание смотрите ниже в разделе Особенности интерфейса
Гранулярный синтез оперирует мелкими кусочками звуков — акустическими пикселями. Принято считать, что гранулярный синтез "начинается" при оперировании звуками <50мс. При значениях commands range
* reading speed
= <50 мы начинаем оперировать уже акустическими пикселями.
При этом каждую команду из commands range
можно считать "субпикселем", который, при включённом random time gap
, каждый раз уникален, а пиксель, соответственно, уникален кратно количеству субпикселей. В итоге мы получаем мутирующий тембр.
В классическом гранулярном синтезе пиксели играют одновременно и параллельно, и их количество может меняться со временем. В BS же пиксели образуют нить, по которой мы движемся.
То есть, если в обычном гранулярном синтезе на слушателя как бы опрокидывают грузовик с песком, где каждая песчинка это акустический пиксель, то здесь этот песок высыпается через воронку диаметром с одну песчинку и вот эту тонкую струю мы и наблюдаем.
На изображении ниже показано формирование акустического пикселя из двух команд (commands range: from = 0, to = 1
), при скорости чтения 0.005 с. Необходимо учитывать, что у каждой частоты есть период T, равный отношению единицы времени (1 секунды = 1000 миллисекунд) к частоте. Это значит, что мы можем мыслить звук не только через частоту, но и через время, за которое волна делает одно полное колебание. Если волна не успевает сделать полное колебание, такой объект называется "вейвлетом".
- Использовать режим инкогнито при отключённых расширениях
- Браузер не-инкогнито закрыть
- В инкогнито оставить только вкладки с BS
- Использовать отдельный браузер ungoogled-chromium, потребляющий немного меньше CPU и сильно меньше ОЗУ.
BS под нагрузкой требует в среднем до 7.1% CPU, в режиме инкогнито 6%, Firefox 4.2%, но работает менее стабильно. Также открытая консоль/DevTools браузера повышает потребление CPU на каждой вкладке на 10%. Рекомендуется использовать BS в режиме инкогнито без любых других открытых вкладок, кроме вкладок BS, для максимальной эффективности.
Более интересный звук получается при нескольких независимых экземплярах BS в разных вкладках. Теоретически, можно было бы реализовать несколько потоков работы BS в одной вкладке, но это менее оптимально, так как браузеры ограничивают максимальное потребление CPU на вкладку (в Chrome это 10% CPU). Также, у каждой вкладки свой event loop. Для быстрого переключения между вкладками можно использовать ctrl + номер вкладки
.
При включении MIDI-режима автоматически выбирается первый попавшийся порт из доступных и его первый канал. Далее последовательно при чтении посылается сигнал noteOn
, через время reading speed
посылается сигнал noteOff
. В continuous
режиме после каждого noteOn
посылается Pitch
сигнал, чтобы попасть в нужную частоту.
MIDI-сообщения могут посылаться:
- в соседние вкладки и окна браузеров, если они слушают MIDI (например, в веб-аналог DX7)
- в DAW и прочие приложения, где есть виртуальные синтезаторы (то есть BS может управлять, например, синтезатором в Ableton)
- во внешние устройства, поддерживающие MIDI и подключённые к компьютеру
Для передачи MIDI-сообщений в DAW на устройствах Windows можно воспользоваться loopMIDI.
Note: После любых манипуляций с MIDI-портами (подключение/отключение/переподключение) необходимо полностью перезапустить браузер, закрыв все окна браузера если их несколько
Note: MIDI-сообщения генерируются только на десктопе
-
Reading speed
— скорость интерпретации; на высоких скоростях более 0.001 приложение может работать нестабильно -
Bitness
— мы можем разделить двоичный код на слова по 8 или 16 бит, что меняет количество доступных частот (256 или 65536) -
Panner
— панорамирование между левым (-1) и правым (1) каналами -
Frequency generation mode
continuous
— непрерывное распределение частотtempered
— распределение по 12-ступенному равномерно-темперированному строю. Доступны ноты от C-2 до B8
-
Transition type
— переход между частотамиimmediately
— моментально, грубый переходlinear
— линейно до следующей частотыexponential
— экспоненциально до следующей частоты
-
Random time gap
— добавление случайной величины времени до следующего звука в пределах параметраreading speed
. Делает звук менее "роботизированным", так как расстояние до каждого звука немного отличается и это добавляет больше "живости" игре -
Commands range
— позволяет играть не весь файл, а его определённую часть -
Solid Mode
— режим "сплошного нажатия", не посылает командыnoteOff
; если подряд идут одинаковые команды (и как следствие ноты), то даже noteOn не посылается. В конце посылаетсяallSoundOff
. На некоторых синтезаторах позволять осуществить плавные переходы между нотами -
Last noteOn mode
— оставляет нажатой последнюю команду в лупе. Позволяет делать более плавные переходы между повторами паттернов. -
У некоторых полей ввода есть клавиатурное сокращение: при нажатии соответствующей клавиши автоматически наводится фокус на элемент. При зажатии клавиши и одновременном движении мышью можно плавно менять значения. По оси Y при движении мыши располагается "мощность" изменения значения. Курсор при этом пропадает, чтобы иметь возможность бесконечно изменять значения. Для возврата курсора необходимо нажать Esc.
Сохранить настройки можно двумя путями:
- через URL-ссылку. При щелчке в адресную строку браузера приложение автоматически формирует ссылку, в которую записываются настройки. Вы можете скопировать её и при открытии ссылки настройки сразу применятся, вам остаётся только загрузить файл для синтеза звука.
- через файл. В интерфейсе преусмотрены кнопки Save settings и Load settings, которые позволяют сохранить на компьютер или загрузить из него файл с настройками.
Всё необходимое для работы системы заложено в единственный .html
файл, который можно скачать в папке dist
, либо просто перейти на https://bs.strannо.su и, нажав правую кнопку мыши, в меню выбрать Сохранить как.
Tech stack: Vue3 + Pinia + Vite.
- Скачать и установить LTS версию Node.js
- Скачать код напрямую с Github, либо через
git clone
- В папке с проектом в терминале выполнить:
npm i
npm run dev # development-сборка
npm run build # production-сборка, генерирует index.html со всем необходимым
Для тестов MIDI можно пользоваться этим ресурсом https://studiocode.dev/midi-monitor/