Брусофония: как устроен звук в игровой приставке «Брус-16»

Учебная игровая приставка «Брус-16» создавалась как устройство из параллельной реальности начала 1980-х. Проект уже получил аппаратную реализацию на FPGA, а для него были написаны игры. Однако полноценной приставке не хватало важной детали — звука. Поэтому автор проекта Пётр Николаевич Советов разработал собственный звуковой синтезатор.
Перед разработчиками стояла задача получить выразительное звучание на доступных FPGA-платах, не расходуя большие объёмы памяти и не усложняя управление. В качестве ориентиров рассматривались популярные для своего времени чипы вроде AY-3-8910, FM-синтезаторы и таблично-волновой подход, используемый, например, в PICO-8 и TIC-80.
Прямоугольная волна, характерная для AY-3-8910, не подошла из-за алиасинга — наложения спектров, которое трудно качественно устранить в простой аппаратной реализации. FM-синтез оказался слишком сложным для пользователя, а хранение семплов потребовало бы больше памяти, чем обычно есть на бюджетных FPGA-платах. В итоге выбор остановили на аддитивном синтезе: звуковая волна складывается из нескольких простых синусоид.
От одной синусоиды к осциллятору
Самый простой вариант — воспроизвести одну ноту одной синусоидой. Например, частота ноты A2 составляет 110 Гц. В цифровом устройстве непрерывное время заменяется последовательностью измерений амплитуды, или семплов. Для «Брус-16» выбрана частота дискретизации 44 100 Гц.
Вместо хранения постоянно растущего значения времени синтезатор использует фазу колебания. Для каждого семпла фаза увеличивается на фиксированный шаг, рассчитанный по частоте ноты: 2πf/44 100. Осциллятор хранит амплитуду, шаг фазы и текущее значение фазы, а очередной семпл вычисляется как произведение амплитуды на синус текущей фазы.
Одна синусоида звучит чисто, но слишком просто. Чтобы получить более насыщенный тембр, разработчики добавили несколько осцилляторов с разными частотами. Такой принцип напоминает устройство духового органа, где одновременное включение разных регистров формирует более сложный звук. В тестовом варианте использовались основная частота, частота на октаву ниже, а также вторая и третья гармоники.
Огибающая и затухание
Даже при нескольких гармониках звук оставался не слишком похожим на настоящий инструмент: в природе громкость не возникает и не исчезает мгновенно. Для управления этим изменением обычно применяют огибающие, включая ADSR-модель с атакой, затуханием, поддержанием и отпусканием. В «Брус-16» реализовали более простой вариант — экспоненциальное затухание, причём для каждого осциллятора используется собственный коэффициент.
Амплитуда обновляется не на каждом семпле, а раз в 64 семпла. В этот момент она умножается на коэффициент decay, обычно находящийся в диапазоне от 0,99 до 1. Значение 64 подобрали экспериментально: затухание должно быть достаточно плавным, но коэффициент при этом удобно хранить в аппаратной схеме.
Мелодия и защита от щелчков
Следующим этапом стала генерация мелодии. В качестве примера использовали фрагмент «Оды к радости» из Девятой симфонии Людвига ван Бетховена: E4, E4, F4, G4, G4, F4, E4, D4, C4, C4, D4, E4, E4, D4, D4. Частоты нот вычисляются автоматически, после чего синтезатор через заданные интервалы меняет частоту основного осциллятора.
Первоначальная реализация выявила неприятный эффект: при резкой смене ноты возникал щелчок. Пока звучит одна нота, амплитуды осцилляторов постепенно стремятся к нулю, а при переключении мгновенно возвращаются к исходному уровню. Изменение выходной амплитуды за один семпл может оказаться слишком большим.
Для устранения щелчков добавили плавное приближение текущей амплитуды к целевой. На каждом семпле разница делится на 64, благодаря чему переход становится достаточно мягким и при этом не исчезает атака звука. Этот параметр, как и интервал обновления затухания, подобрали эмпирически.
Master и slave осцилляторы
Чтобы упростить описание тембров, в синтезаторе разделили осцилляторы на master и slave. У master абсолютными значениями задаются частота и амплитуда. Slave получают параметры как множители относительно ведущего осциллятора: например, коэффициенты 0,5, 2 или 3 позволяют задать частоты на октаву ниже, а также вторую и третью гармоники.
Финальная концепция синтезатора позволяет собирать более сложные инструменты из нескольких групп осцилляторов. В одном из вариантов используются три тембра — мелодия, бас и гармония, — которые в сумме занимают 16 осцилляторов. Для них задаются собственные амплитуды, коэффициенты затухания и относительные частоты. Создание таких тембров остаётся творческой задачей: одну и ту же музыкальную партию можно описать разными наборами гармоник.
Так «Брус-16» получил не просто генератор отдельных тонов, а компактную систему синтеза, рассчитанную на аппаратную реализацию. Аддитивный подход позволил обойтись без семплов и сложного FM-управления, а сочетание гармоник, затухания и сглаживания переключений сделало звук пригодным для мелодий и игровых эффектов.


