У меня музыкальное образование, и я всегда увлекался синтезом звука. Синтезаторы, сэмплеры и обработка звука всегда были одними из моих любимых вещей, над которыми я возился, и когда я начал программировать, звук был одним из первых, на что я обратил внимание. Когда я узнал больше о веб-разработке, я был очень счастлив узнать о Web Audio API, библиотеке, встроенной в JavaScript для работы со звуком в Интернете! MDN определяет его как «мощная и универсальная система для управления звуком в Интернете, позволяющая разработчикам выбирать источники звука, добавлять эффекты к звуку, создавать аудиовизуализации, применять пространственные эффекты (например, панорамирование) и многое другое». Давайте посмотрим на некоторые строительные блоки для синтеза звука и на то, как мы можем применить эти концепции для создания базового синтезатора с помощью Web Audio API!

СИНТЕЗ АБСТРАКЦИИ

Так как же работает синтез звука? Мы собираемся взглянуть на то, что называется субтрактивным синтезом, но пока не беспокойтесь о том, что это означает. Есть много различных типов синтеза, и я бы посоветовал вам изучить их, если вам интересно. А пока в этом примере давайте рассмотрим несколько отдельных блоков или устройств, каждое из которых будет выполнять свою работу. Чтобы помочь в объяснении, я приведу аналогичный пример простой гитарной установки, состоящей из электрогитары, педали эффектов и усилителя.

ИСТОЧНИК ЗВУКА

Первым шагом в синтезировании звука является источник звука. В нашей аналогии с электрогитарой источником звука является сама гитара. Затем гитара подключалась кабелем к гитарным педалям. Синтезатор работает аналогичным образом, но вместо гитары мы используем так называемый осциллятор.

То, что колеблется, определяется как что-то, что движется или раскачивается назад и вперед с постоянной скоростью, почти так же, как гитарная струна или конус динамика для воспроизведения звука. Осциллятор делает именно это. Это устройство, которое производит звук путем генерации определенной математической формы волны, такой как синусоидальная, квадратная или пилообразная волна, с определенной частотой в герцах (Гц).

ОБРАБОТКА

Следующим шагом в нашем синтезе является обработка необработанного сигнала, созданного генератором. В нашей аналогии с электрогитарой педали гитары являются обработкой. Усиление, искажение, фильтрация и реверберация - все это примеры обработки и эффектов.

В случае синтезатора вам, вероятно, потребуется усилить звуковой сигнал от генератора, чтобы сделать его более слышимым, и, возможно, вы захотите отфильтровать часть гармонического содержания.

МЕСТО НАЗНАЧЕНИЯ

Нам понадобится какой-то способ действительно услышать гитару, на которой мы играем, поэтому давайте подключим последнюю педаль в нашей цепочке обработки до конечного пункта назначения: усилителя / кабинета. Многие классические аппаратные синтезаторы на самом деле не имеют встроенных динамиков, поэтому их нужно усиливать, как на электрогитаре.

ПРИМЕНЕНИЕ ЭТОГО К WEB AUDIO API

При работе с API веб-аудио эти устройства для создания и обработки звука называются аудиоузлами . Все эти узлы будут созданы и подключены к AudioContext. Возвращаясь к нашему примеру с электрогитарой, вы можете думать об AudioContext как о физическом пространстве, в котором существуют наша гитара, педали и усилитель. Эти элементы должны находиться внутри пространства или «контекста».

AudioContext фактически наследуется от BaseAudioContext, базового определения для AudioContexts, в котором есть методы для создания различных узлов. Давайте углубимся в некоторые из этих методов и начнем создавать наш синтезатор!

СОЗДАВАЙТЕ КОНТЕКСТ И УЗЛЫ

Мы говорили об использовании AudioContext и создании различных узлов, теперь давайте посмотрим, как все это выглядит:

Отлично, теперь у нас есть AudioContex, источник звука: osc и 2 узла для обработки.

Примерно так же, как мы бы подключили нашу гитару, педали и усилитель с помощью физических кабелей, нам нужно соединить все эти узлы вместе, а затем подключить их к конечному выходу или назначению «усилителя». Мы будем использовать метод connect () аудиоузлов для подключения каждого узла к следующему и, в конечном итоге, к аудиовыходу браузера, месту назначения.

ПОДКЛЮЧЕНИЕ УЗЛОВ

На этом этапе все подключено, и мы действительно можем слышать шум синтезатора! Если вы следовали инструкциям, попробуйте добавить

а затем запускаем файл.

Привет! Это синусоида на частоте 440 Гц! Прохладный! Вряд ли это музыка, но это начало. Вызов

чтобы остановить осциллятор, или позволяет закрыть файл. (На самом деле мы не можем «запустить» тот же генератор снова, поэтому сейчас давайте просто повторно запустим файл, когда мы захотим запустить его резервную копию.)

ИЗМЕНЕНИЕ НЕКОТОРЫХ ПАРАМЕТРОВ

Давайте посмотрим на некоторые свойства осциллятора, которые мы можем редактировать. Я размещу этот код до того, как будут выполнены подключения.

Тип и частота - это параметры звука узла генератора.

Тип относится к типу колеблющегося математического сигнала. Фактически вы можете создавать собственные формы сигналов, но наиболее распространенными являются синусоидальные, квадратные, пилообразные и треугольные волны.

Частота - это частота в герцах (Гц) колебаний, или высота звука, или ноты, которую мы играем. Мы используем AudioParam.setValueAtTime (value, startTime), чтобы установить значения частоты в определенное время, и, поскольку мы пытаемся изменить высоту звука немедленно, мы использовали audioCtx.currentTime.

Запустив код еще раз, мы можем услышать, что играемая нота на октаву выше и имеет более резкий пилообразный тембр.

Когда мы перейдем к следующим шагам, давайте удалим все, что связано с осциллятором, оставив нам следующее:

СОЗДАНИЕ ИНТЕРФЕЙСА

Все это было очень круто, но я хотел бы немного больше контролировать звук и то, какие ноты воспроизводятся. Давайте создадим простой интерфейс для нашего синтезатора.

МУЗЫКАЛЬНАЯ КЛАВИАТУРА

Было бы здорово играть на клавиатуре компьютера разные ноты в качестве музыкальной. Давайте послушаем нажатия клавиш на нашей странице и назначим их некоторым музыкальным частотам.

Клавиши от Z до M будут белыми клавишами на одну октаву, причем верхний ряд будет назначен черным клавишам, а клавиши от Q до U будут назначены на вторую октаву. Мы создадим объект keboardFrequencyMap с ключами кодов клавиш и значениями соответствующих музыкальных частот в герцах. Затем давайте разместим прослушиватели событий во всем окне, ожидая обоих событий keydown и keyup. Эти события будут вызывать новые функции keyDown () и keyUp () соответственно.

keyDown вызывает дополнительную функцию playNote (), которая обрабатывает создание осцилляторов и устанавливает их частоту и форму волны (была создана новая переменная waveform, чтобы мы могли изменить это на лету позже) . Мы сохраним эти узлы осциллятора как значения в новом объекте activeOscillators, каждый с ключом кода клавиши, который был нажат для его создания. Затем мы подключим этот осциллятор (так сказать, нашу гитару) к первой части нашей цепочки обработки, узлу усиления, и запустим осциллятор.

keyDown () и keyUp () проверяют, была ли нажатая клавиша назначенной музыкальной клавишей, и смотрят в activeOscillators, чтобы увидеть, активна ли эта клавиша уже или нет. Также обратите внимание, что когда клавиша отпускается, осциллятор останавливается, а затем разрушается из-за того, что мы не можем перезапустить осциллятор. Каждое новое нажатие клавиши создает новый осциллятор, который сохраняется в activeOscillators до тех пор, пока он не будет остановлен.

Давайте запустим файл и проверим!

ИНТЕРФЕЙС ПАРАМЕТРОВ СИНТЕРА

Большой! Мы добиваемся хороших результатов, но есть еще несколько параметров, к которым я хотел бы получить доступ для манипуляций, таких как форма волны, усиление, тип фильтра и частота среза фильтра. Давайте перейдем к HTML и добавим несколько вещей в основную часть страницы.

Теперь у нас есть раскрывающиеся списки для формы сигнала и типа фильтра, а также ползунки для усиления (громкости) и частоты фильтра. Диапазон усиления был установлен от 0,0–1,0 или без звука до полной громкости, а диапазон частот был определен от 20 Гц до 10 кГц.

Краткое замечание о фильтрах: фильтр lowpass позволяет только частотам ниже точки среза (частоты фильтра) "проходить" или быть услышанными, эффективно заглушая звук. Фильтр highpass делает с точностью до наоборот, отсекая низкие частоты, так что слышны только высокие частоты, а bandpass срезает как низкие, так и высокие, оставляя только узкие группа.

Давайте сейчас добавим прослушиватели событий для всех этих элементов управления. Сначала нам нужно обернуть весь наш проект в событие DOMContentLoaded, чтобы убедиться, что все созданные нами элементы доступны для поиска.

Милая! Каждый раз, когда обновляются элементы управления усилением или фильтром, параметры их узлов также обновляются, и когда мы меняем форму волны, она обновляет нашу переменную формы волны. Синтезатор, клавиатура и элементы управления на странице теперь должны работать! Давайте проведем рефакторинг, немного упорядочим и вместе посмотрим на все. Я добавил несколько примечаний для ознакомления.

Спасибо за внимание! Вот ссылка на мой код на GitHub, если вам интересно: https://github.com/Maurice-Roy/SynthBlogDemo