FM синтез звука на Визуал Бейсик в программе Трио
я практически не нашёл ничего. Всё больше общие положения.
Конкретику пришлось пробовать самому.
В Википедии читаем: "FM-синтез (англ. Frequency Modulation, FM - частотно-модуляционный), операторный синтез — способ синтеза звуковых волн, в основе которого лежит частотная модуляция колебания простой (например, синусоидальной) формы... Варьируя параметры можно изменять тембр в широких пределах, получая как гармонические, так и негармонические (например, подобные звучанию колокола или ударных инструментов) колебания."
Действительно, подумал я, как же это я прошёл мимо такого хорошего метода? FM-синтез хвалят, а программа Трио его не использует. И может быть, зря. Возможности новые бы открылись.
Но как внедрить FM-синтез в программу, основанную на принципах вроде бы совсем других?
В FM-синтезе используются непрерывно работающие и воздействующие друг на друга осцилляторы, а программа Трио создаёт звук по отдельным периодам, пристёгивая их к уже созданному звуку. Не слишком ли различаются эти методы?
Оказалось, что "не слишком", и FM-синтез встраивается в программу Трио вполне органично.
О чём и рассказываю.
ОСНОВЫ FM СИНТЕЗА
Физически FM-синтез в музыкальных синтезаторах осуществляют специальные микросхемы. Каждая микросхема содержит внутри себя большое количество цепочек из нескольких осцилляторов каждая. И в каждой цепочке осцилляторы соединены между собой некоторым особенным образом, модулируя частоту генерации один другого, и создавая на выходе цепочки уникальный тембр звучания того или иного музыкального инструмента. Все эти осцилляторы работают одновременно, звуки цепочек суммируются и передаются в динамики, а последовательность нажатия клавиш, если музыкант того захочет, передаются на компьютер в виде последовательности байтов МИДИ формата.
Но у нас-то с Вами таких микросхем в программе нет. И ничего одновременно работающего тоже нет. Мы вынуждены создавать звук последовательно, имитируя работу осцилляторов микросхемы, и переходя от одного осциллятора к другому.
Разумеется, это требует значительно большего времени. Но и программа Трио к динамикам непосредственно не обращается. Она не отвечает на движение пальцев музыканта по клавишам, но она читает партитуру и создаёт файл звуковой записи. И уж этот файл можно будет после прослушать.
Время создания звуковой записи часто оказывается меньше времени её звучания, так что, в принципе, звук и в динамики можно направить, но как это сделать, я не знаю.
Итак, займёмся программной реализацией осцилляторов и их соединением в цепочки.
Заведём в программе Трио отдельный модуль под названием "инструменты" и поместим в него функцию FNS12 - наш инструмент для создания звука путём FM синтеза.
ДЕЛАЕМ ОДИН ОСЦИЛЛЯТОР И ОПРЕДЕЛЯЕМ ШАГ ДВИЖЕНИЯ ПО ФАЗЕ
Колебание осциллятора не обязательно должно быть синусоидой. Синусоида вычисляется не очень быстро, в качестве колебания, представляющего "основу", можно взять функцию
Y = X - X^3 на интервале (-1, 1) см.рисунок к статье
Прежде чем запустить осциллятор, неплохо бы задать частоту колебания F, а также установить "наш маятник" в исходное положение, задав для него X = -1.
Установить максимальную амплитуду и задать "огибающую" звука мы можем сделать средствами Трио, указав параметры AU2=3 и DU2=5.995 в следующем сценарии №12 -
Case 12
MU2 = 0: AU2 = 3: DU2 = 5.995: mod2 = 12
V = FNS12(F) 'тут мы задаём частоту звука
а затем многократно обращаемся к нашей функции, вычисляя очередную амплитуду -
Select Case mod2
...
Case 12: A2 = AA2 * FNS12(0)
...
значение AA2 здесь представляет собой огибающую звука. В течении 5-ти периодов AA2 линейно нарастает, а затем убывает по экспоненте с фактором .995
В результате амплитуда звука A2, формируемая осциллятором функции FNS12, вначале очень быстро нарастает, а затем медленно спадает.
Текст самой функции выглядит так -
Public Function FNS12(F) 'все переменные имеют тип Single
If F > 0 Then
dX = 2 * F / VEL: dXo = dX: X = -1
FNS12 = 0: Exit Function
End If
A = (X - X ^ 3) / 0.385: X = X + dX: If X > 1 Then X = X - 2
FNS12 = A
End Function
'===============
здесь глобальная VEL - скорость раздачи, равная 32000 или 44100 семпл/сек
Никакого FM синтеза пока нет, но заметим, что мы можем постепенно изменять шаг dX, отклоняясь от изначально определённого значения dXo в сторону увеличения или в сторону уменьшения шага.
Насколько мы можем уменьшать шаг, если следовать этому алгоритму?
До очень малых значений, и потом повернуть обратно? А что если зайти в отрицательную область?
В реальной микросхеме это сделать вряд ли можно, не знаю.
Но у нас на компьютере время "потечёт вспять", и эффекты будут очень интересными.
_______
Алгоритм осцилляций, выраженный строкой A =... принято называть оператором.
ДЕЛАЕМ ЦЕПОЧКУ ИЗ ДВУХ ОСЦИЛЯТОРОВ (ОПЕРАТОРОВ)
Попытаемся сделать звук фортепьяно из двух осциляторов. Перепишем сценарий по-другому -
Case 12
MU2 = 0: AU2 = 3: DU2 = 5.995: mod2 = 12
V = FNS12(F, Fm) 'задаём частоту основного и модулирующего осцилятора
Vi = 1.54 'задаём коэффициент связи между ними
рабочее обращение к функции тоже сделаем другим -
Case 12: A2 = AA2 * FNS12(0, Vi)
а сама функция будет содержать два осциллятора -
Public Function FNS12(F, k)
If F > 0 Then
dX1 = 2 * k / VEL: dX1o = dX1: X1 = -1 'настраиваем модулирующий осциллятор
dX2 = 2 * F / VEL: dX2o = dX2: X2 = -1
FNS12 = 0: Exit Function
End If
A1 = (X1 - X1 ^ 3) / 0.385: X1 = X1 + dX1: If X1 > 1 Then X1 = X1 - 2
A2 = (X2 - X2 ^ 3) / 0.385: X2 = X2 + dX2: If X2 > 1 Then X2 = X2 - 2
dX2 = dX2o * (1 + k * A1)
FNS12 = A ' колебания можно обострить, если записать FNS12 = A ^ 3
End Function
'===============
Чтобы получить звук колокола или колокольчиков, в интернете советуют взять соотношение между основной и модулирующей частотами приблизительно равным 1:3, например положить Fm=2.94*F.
Я попробовал сделать это. Действительно, призвуки звона высоких обертонов явственно слышатся, но более интересным мне показался звук при точной настройке - Fm=3*F. Не для всех частот, но для некоторых, получается похоже на звук фортепьяно - см. Пример №2 по ссылке -
http://yadi.sk/d/gr4Ej68w3MYwBk
этот звук куда ярче тусклого звука основы - Пример №1 по этой же ссылке.
Пример №3 записан для колебаний, обострённых возведением в 3-ю степень.
Плавно меняя показатель степени p по формуле FNS12 = Sgn(A) * Abs(A)^p, мы можем легко изменять тембр фортепьянного звука. Правда приличный звук получается не для всех частот, а для небольшого диапазона 1-й октавы, а для перехода к другим частотам схемы генерации придётся как-то менять, причём, делать такое изменение плавным, но это не принципиально. Главное, что звук фортепьяно получен.
То, что коэффициент связи задан через сценарий равным 1.54, то есть, сделан большим единицы, обусловило обратный ход по времени на некоторых участках осцилляции второго оператора. И на осциллограммах (см. две верхние, на рисунке к статье) появились пики третьего обертона. Но это не совсем третий обертон - благодаря плавной перестройке частоты спектральный состав звука побогаче, а звук поинтереснее. То есть, действительно, FM синтез даёт некие хорошие результаты.
Осциллограммы получились строго периодичными, такие же мы могли бы получить, используя группу рельефа программы Трио. Но группа рельефа работает помедленнее, и перестраивается по тембру труднее. Так что, выигрыш на периодических структурах от FM синтеза можно получить. И непериодическую структуру на группе рельефа не создашь, а в FM синтезе - пожалуйста, возьмите для этого соотношение Fm:F не целое, а какое-нибудь дробное. Вы можете даже менять его в сценарии, создавая вибрато.
ЦЕПОЧКА ИЗ 3-х ОСЦИЛЛЯТОРОВ ДЛЯ СОЗДАНИЯ НИЗКОГО ФОРТЕПЬЯННОГО ЗВУКА
В интернете я нашёл пример цепочки из трёх осцилляторов с соотношением частот 1:2:4 и опробовал её. Сделал функцию FNS13, аналогичную FNS12, только с тремя осцилляторами - №1, №2 и №3, и связал эту функцию со сценарием 13.
Положил F3=F, для модулирующего оператора №2 взял F2=F/2. Оператор №2 в свою очередь модулируется оператором №1 с частотой F1=F/4. Получается цепочка, показанная на рисунке -
F/4 =vi=> F/2 =vi=> F ---> выход
Коэффициенты связи между операторами сделал одинаковыми и равными числу Vi.
Результат для Vi=.2, обострённый возведением во вторую степень, можно услышать в Примере №4 по приведённой выше ссылке. Что удивительно?
Слышим мы вовсе не частоту F (первая октава), а слышим частоты F/2 нот, принадлежащих малой октаве. А вот если задать Vi=.4, то звук опустится в большую октаву!
Как это объяснить?
Посмотрите на нижнюю осциллограмму рисунка, записанную для Vi=.3. Осциллограмма имеет неточную периодичность по F, и более точно соблюдаемую периодичность по F/2 - эта периодичность показана на рисунке стрелочками.
И уж совершенно точная периодичность выполняется для стрелочек, имеющих одинаковый цвет - можно заметить, что форма колебания у красной и сиреневой стрелочек чуть различается. И это различие увеличивается по мере увеличения коэффициента связи.
И наше ухо начинает высоту звука идентифицировать в соответствии с той периодичностью, которую оно отслеживает.
Не правда ли, красивые звуки получаются?
Для большей красоты я в примерах добавил эхо, а в последнем примере придал первому коэффициенту связи небольшую вибрацию, вот так -
Case -13
Vi = 0.2 * (1 + 0.9 * FNTIM(7, T))
здесь показана нижняя часть сценария №13. Она обозначена отрицательным номером, и выполняется с периодичностью 1/F в момент перехода основного звука от одного периода к другому. Такая процедура обычно применяется в сценариях Трио для придания звуку естественности звучания.
Функция FNTIM(7, T) создаёт колебания треугольной формы. 7 - частота 7Гц, T - время (сек).
ЦЕНА МЕТОДА
Тот или иной метод создания звука можно оценивать по его быстродействию.
Назовём "ценой метода" отношение времени выполнения алгоритма метода при озвучивании ко времени звучания полученной записи.
Для скорости раздачи 32000 будем обозначать эту величину Щ, а для 44100 - Цм.
Для определения Цм делается озвучивание с применением метода и озвучивание, в котором метод искусственно обходится или блокируется. Из первого времени вычитается второе и делится на время звучания записи. Получены следующие результаты -
Озвучивание пьесы №3 Шумана для альта с фортепьяно, метод целиком - Цм=.733 одновременно работают 3 канала
Озвучивание фортепьянной пьесы "Январь", Времена года Чайковского - Цм=.379 одновременно работают 2 канала
Отдельно, при отсутствии пауз, на тесте с одним работающем канале МУЗа:
алгоритм звука фортепьяно - Цм=.018
алгоритм звука виолы - Цм=.013
алгоритм создания рельефа - Цм=.071
создание эхо в ревербераторе - Цм=.017
метод FM с 3-мя осцилляторами - Цм=.045
обслуживание чтения сценариев и партитур - Цм=.047
аккорды также вносят свою лепту, затягивая время озвучивания.
Цена озвучивания метода целиком складывается тотальным суммированием (по всем работающим каналам) цены обслуживания и цен привлечённых методов (с учётом случающегося повторения этих методов на аккордах). Обычно в канале работают одновременно 2 разных метода, плюс иногда и эхо, а всего каналов 2 или 3. Вот и считайте, на что время уходит, и какой метод выгоднее применять.
ВЫВОДЫ
Алгоритмы FM синтеза вполне успешно могут быть встроены в программу озвучивания Трио, причём методы частотного синтеза и программы Трио удачно поддерживают друг друга. В частности, огибающая для звука осцилляторов делается средствами программы Трио.
В сценариях может быть запрограммирован и тембр звука, и созданы возможности к его изменению, как со временем, так и через указания в партитуре (поскольку обработка партитурных указаний заложена в Трио).
Вместе с тем, описанный алгоритм FM синтеза является итерационным, и не может быть выражен простой формулой с двумя параметрами - частота и время. Поэтому невозможно создать на его базе аккорд с одновременным звучанием разных частот на одном канале, так просто, как это делается в программе Трио. Возможны только звуки одиночных нот FM синтеза для каждого канала.
============================
о синтезе звука в Визуал Бейсике см. ещё тут -
http://www.proza.ru/2017/08/25/2126 http://www.proza.ru/2017/08/27/2000
модули для экспериментов с FM синтезом тут - http://yadi.sk/d/uzcq9Fj8wgfIAQ
___________
Свидетельство о публикации №217090300103