Старый добрый Бейсик DOS-овских времён вовсе не умер. Он позволяет сделать то, что в современной среде программирования повторить не то, чтобы сложно, но непривычно - это уж точно. Преимуществом Бейсика является простота и наглядность записи текста программы.
В среде Турбо Бейсик мною сделана программа, успешно синтезирующая музыкальный звук методом по-периодного синтеза. Метод этот использует оригинальные алгоритмы, позволяющие приблизить звук к звуку реального инструмента и придать этому звуку естественность.
Весь сценарий развития звука фортепьяно умещается в довольно лаконичной записи, которую я потом подробно прокомментирую -
CASE 8 'f-no 2 tembr => UDa=0 UDc=0 Ar=0 UEa=0 -2
MU1=0 : AU1=1.5 : IF UD3a>0 THEN DU1=UD3a ELSE DU1=3.995
V=INT(DU1) : DU1=DU1-V : IF UEA3=0 THEN UEA3=.3
DU1=1-(1-DU1)*260/FS : DU3=1-(1-DU1)*2 : DU1=V+DU1
MU3=0 : AU3=5 : IF UD3c>0 THEN DU3=UD3c
IF FS>260 THEN AU3=AU3*260/FS
IF ARE3=0 THEN A33r$="7550604565304035"
IF ARE3=0 THEN A32r$="6560505555403045"
IF ARE3=0 THEN A31r$="5560605545404045"
Apm$="505050707050505560657035504744433857" : Dpm=.98
R(0)=0 : V=FNR1(0,1006.4) : V=FNR1(0,2006.4) : V=FNR1(30,-9)
CASE -8 : E0=1.25*(1+.2*FNTIM(4,T)) : EA=UEA3*(1+.2*FNTIM(8,T))
E1=1.3*(1+.2*FNTIM(10,T)) : E2=1.3*(1+.2*FNTIM(7,T))
V=(FNTIM(9,T)+FNTIM(13,T))/3 : Arr$=FNRE$(AU3/2-1+V,3)
После этого идёт несложный алгоритм, использующий заданные в сценарии переменные, и строящий форму звука фортепьяно в одном отдельно взятом периоде.
Всё сделано для того, чтобы вычисления амплитуды звука внутри периода шли по наиболее простому и быстрому алгоритму. Синусоида аппроксимируется отрезками параболы, при этом синусоида немного ( в соответствии с переменной EA) обостряется добавлением четвёртой степени от неё же, только что вычисленной.
Кроме того фаза X внутри периода претерпевает изменения, она чуть-чуть расширяется в первом полупериоде и сжимается во втором. Или наоборот - в соответствии с тем, насколько отличается от единицы переменная E0. И точно так же фаза несколько перераспределяется по четверть периодам внутри каждого полупериода. На эти перераспределения указывают переменные E1 и E2.
Общий алгоритм вычисления выглядит так -
IF X<E0 THEN V=X*2/E0-1 : B=1-E1 : ELSE V=(2-X)*2/(2-E0)-1 : B=1-E2
IF V<-B THEN V=(V+B)/(1-B) ELSE V=(B+V)/(1+B)
ZZ=V*V : A1=(1-ZZ) : A1=EA*A1+(1-EA)*A1^4 : A1=AA1*A1
В этих трёх строках, вплоть до самого последнего оператора, вычисляется "начинка" звука. Амплитуда "начинки" A1 зависит от фазы колебания X и от параметров, которые остаются постоянными в течении цикла вычислений внутри периода колебаний. Фаза находится в сегменте от 0 до 2-х, и вычисляется так:
X=2*(T/TT-int(T/TT)), где T-время TT-период int-целое от аргумента
В последнем операторе A1 умножается на амплитуду огибающей звука, тоже постоянную величину для всего периода.
Итак, амплитуды звука в течении всего периода вычисляются по быстрому алгоритму, использующему некие неизменные на протяжении всего периода параметры.
А собственно в сценарий, которым началась эта статья, и в котором эти параметры задаются и изменяются, программа заглядывает редко.
Верхняя часть сценария «CASE 8» выполняется один только раз, в самом начале перед появлением звука, на скорость выполнения этой части можно внимание не обращать. Нижняя часть сценария «CASE -8» выполняется каждый раз перед началом нового периода и задерживает ход вычисления первого семпла периода, зато последующие семплы вычисляются без задержки.
В этом-то разделении общего алгоритма на части – начальную, редкую и быструю, состоит прелесть по-периодного метода синтеза звука.
Обратимся теперь к подробному объяснению того, что написано в сценарии.
В принципе, то, что написано в сценарии как раз и создаёт нужную форму звука внутри периода. Приведённый выше сценарий создаёт звук фортепьяно, другой, похожий на него сценарий, создаст звук трубы, третий – звук певческого голоса.
Однако, просто создать нужную форму в отдельно взятом периоде недостаточно, звук должен ещё и развиваться. Даже при резком ударе молоточка о струну звук не возникает сразу в полную громкость. В течении нескольких периодов он нарастает, проходя так называемую фазу атаки, а затем начинает постепенно спадать в своей громкости.
Диссипативный фактор DU1=3.995 задаваемый в верхней части сценария, своей целой частью указывает на число периодов, в течении которых происходит атака.
Во время развития атаки первый период проходит с амплитудой AA1=.5, второй - с AA1=1, а третий - с AA1=AU1=1.5 - достигнув максимального значения AU1, заданного в верхней части сценария.
Ну, а затем перед каждым новым периодом происходят следующие изменения AU1=AU1*.995 и AA1=AU1 – и амплитуда звука постепенно уменьшается. Кстати сказать, сценарий способен к внешней регулировке - глобальная переменная UD3a способна изменить значение диссипативного фактора.
Этими изменениями развитие звука не ограничивается. Чтобы звук был естественным и воспринимался как красивый, нужны некие отклонения от полученной формы, плавно перетекающие от одного периода к другому.
Эти изменения делаются в нижней части сценария путём девиации параметров около их средних значений с помощью периодической функции по времени FNTIM(частота,T) - форма этой функции - треугольник, амплитуда - единица. Для девиации используются низкие частоты.
Несмотря на то, что девиация звука от периода к периоду является исключительно важным фактором, конкретный вид девиации оказывается не важным - для девиации можно выбрать и другие частоты, и другие аналогичные способы, на качество звука конкретный вид девиации заметно не влияет, следует только избегать иногда возникающих вибрато.
Не следует также использовать для девиации случайных параметров или шумовых функций - наш слух, по видимому, умеет отличать гармонию от шума. Я много раз пытался применить псевдослучайные числа для целей синтеза музыкального звука, с самыми разными целями, и в самых разных вариантах, но ни разу удовлетворительных результатов не получил.
Звук развивается и в другом плане. В начальной фазе колебаний струн фортепьяно сильны обертоны, особенно третий, четвёртый и пятый. Для того, чтобы присоединить эти колебания к звуку, используется Группа параметров рельефа. Называется эта группа так, потому что использует рельеф, заданный в строке Arr$ для вычисления амплитуд колебаний внутри периода. Строка относительно короткая, а период длинный, поэтому при вычислении значений амплитуд внутри периода используется сплайн интерполяция.
Рельеф строки Arr$ тоже не остаётся постоянным, он испытывает девиацию и постепенно переходит от рельефа строки A33r$, указанной в сценарии верхней, к нижней строке A31r$.
При этом происходят изменения обертонного состава звука фортепьяно. Обертоны постепенно сходят на нет - начальная амплитуда обертонных колебаний AU3 и диссипативный фактор DU3 работают аналогично описанному выше.
Что касается мнемоники строк, то она состоит из двузначных чисел, причём 50 означает нулевую амплитуду, 60 означает 10, а 40 означает -10. Амплитуда рельефа таким образом шифруется в пределах от -50 до +49, такой градации вполне хватает.
Но это не всё. Используется отдельная техника, создающая неровность звука. Строка Apm$ описывает процесс "тяни в плюс, толкай в минус" - процесс опускающий и поднимающий на начальной стадии некоторые периоды колебаний, создавая призвук удара молоточка о струну. Мнемоника строки та же, только числа относятся к последовательности периодов, строка зацикливается, и задаётся диссипативный фактор для этого процесса.
Наконец, созданный звук проходит через ревербератор, в который эхо, как можно видеть из сценария, забрасывается на 1006 и на 2006 семплов вперёд. Заброс осуществляется обращением к функции FNR1. Дробная часть при указании точки заброса определит ослабление – 0.4 означает, что заброшено будет 40% пришедшей к ревербератору амплитуды. Кроме того 30% вернувшегося из ревербератора эха, вновь забрасывается в него, на это тоже указывается в сценарии. Таким образом создаётся многократное эхо.
Через некоторое время всё заброшенное эхо слышится, и воспринимается ухом, как резонанс коробки фортепьяно. Весь процесс проводится раздельно для звуков правой и левой руки, а результат записывается в WAV файл.
Результат можно послушать по общей ссылке на музыкальные записи - http://yadi.sk/d/poMxlrBuxendv
И, заметьте, это не семплированный, а целиком синтезированный звук.
Интересно и то, что для получения музыкальной записи МИДИ формат не понадобился. Основой для неё послужил обычный текстовый файл – партитура, в которой записаны в столбик частоты и длительности нот, длительности пауз, а также некоторые пометки, указывающие на аккорды, на общую громкость звучания, на продления и укорочения звучания нот.
Этот путь может составить простую альтернативу методам, принятым в МИДИ протоколах, и ориентированным на поток событий.
_______
29 марта 2017 Дмитрий
В настоящее время сценарий развития звука фортепьяно несколько усложнён, с тем, чтобы он более ярко звучал на низких частотах, а также лучше отображал некие нюансы исполнения. Об этом тут - http://www.proza.ru/2017/04/25/939
ДОПОЛНЕНИЕ
Как я только что с удовольствием выяснил, в своих экспериментах со звуком я иду вполне в тренде развития цифрового звука. Так, технология SuperNATURAL Piano, заложенная в синтезатор Roland близка к алгоритмам, описанным выше. Цитирую -
//Звук ... не записывается с акустического пианино, а создается с помощью дискретных компьютерных математических алгоритмов.//
//... модель ... обычно имеет несколько параметров, некоторые из которых являются константами, ... а другие представляют собой зависящие от времени функции, описывающие взаимодействие исполнителя с инструментом.//
При обычном синтезе звука //...по мере затухания никак не меняется тембр, в то время как на рояле основной тон звучит гораздо дольше, чем быстро затухающие верхние обертоны.
В противоположность такому поведению технология SuperNATURAL Piano позволяет воссоздать затухание с естественным развитием тембра ..., как и на настоящем акустическом фортепиано.//
А я о чём? Посмотрите, что написано выше - "При этом происходят изменения обертонного состава звука фортепьяно. Обертоны постепенно сходят на нет..."
Нет, всё же приятно, что я иду в общем тренде.