Реплики музыкального звука

  В создании хорошего музыкального звука обычно используются семплы. Так называются короткие (до нескольких секунд) отрезки записи звука реального музыкального инструмента.
  Комбинируя семплы, записанные для разных частот, в их непосредственном, или в несколько преобразованном виде, получают синтезированную музыкальную мелодию.

  Хотя, строго говоря, синтезом, этот метод создания музыки назвать нельзя. Устройства, использующие этот метод, называются семплерами. А синтезатор, это нечто другое - он не использует образчики записанного звука, а создаёт звук "с нуля". Вы можете найти в интернете описание разных методов синтеза звука - аддитивный, субтрактивный и проч. И дескать именно синтезаторы, в отличие от семплеров, позволяют достичь очень широкой вариабельности звука, а семплеры принуждены оставаться в ограниченном массиве записанных образцов звука.
  И это - правда.
  Но в то же время я вам скажу, что это ещё и глупости, поскольку хороший звук фортепьяно на синтезаторах пока не получили. И зачем нужна вариабельность компьютерного завывающего звука, если вы благородный звук фортепьяно, даже в одном единичном его образце методом синтеза получить не можете?

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


   ПО-ПЕРИОДНЫЙ МЕТОД СИНТЕЗА МУЗЫКАЛЬНОГО ЗВУКА

  Почему я в формулировке названия раздела употребил слово музыкальный?
  А вот почему.
  Будем различать среди множества разнообразных звуков звуки сложные и звуки простые. Простым звуком мы назовём звук, являющийся в силу своей периодичности подходящим для музыки, - имеющим хорошо ощущаемую на слух частоту звучания. Ощущаемая частота равна 1/период.
  Сложным музыкальным звуком мы назовём звук, получаемый сложением простых звуков.
  Любой звук может быть изображён суммой простых звуков. Это ясно из того, что синусоида и косинусоида также являются простыми звуками. Любой звук можно изобразить рядом Фурье. Разница состоит в количестве слагаемых.

  Фурье составляющих для качественного изображения, например, звука фортепьяно понадобится неимоверное количество. А простой звук, если правильно подойти к его конструированию, может понадобиться для этого только один. Ну, может быть, ещё нужно будет добавить в самом начале развития ещё несколько простых звуков с частотой не кратной частоте основного звука.
  Как сделать такой простой звук? Очень просто - задаёмся строгой периодичностью амплитуд, требуя непременного попадания амплитуды в ноль в начале каждого периода. А сам период наполняем, хотя и однотипным, но меняющимся по некому алгоритму от периода к периоду содержанием.
  Однотипность содержания означает использование одних и тех же формул, для расчёта величин амплитуд внутри каждого периода, а изменение может быть реализовано плавным изменением параметров, входящих в эти формулы.
  Совершенно ясны и требования к алгоритму создания простого звука. Из соображений быстродействия формулы для вычисления амплитуд должны быть как можно более простыми. А вот алгоритм изменения параметров может быть и сложным - тут быстродействие не нужно, коррекция параметров происходит только в промежутке между периодами, то есть в моменты сравнительно редкие.

  Ясно, что программирование всего этого - сугубо интеллектуальная работа. Это не синусоиды тупо складывать и рычажки управления фильтрами на авось двигать. ))
  С другой стороны, оказывается, что и не такой уж большой класс этих самых - простых звуков, требуется. Я прекрасно обхожусь тремя алгоритмическими группами, каждая со своими формулами. Это - группа звуков фортепьяно, группа звуков виолы и группа рельефа. В дополнение к этому набору в программе ТРИО имеется ещё обертонная группа с четырьмя обертонами произвольной частоты и со своей собственной не совсем простой структурой. 
  Всё это позволяет, конструируя сценарии развития звука, получать и звук фортепьяно, и звук аккордеона, и звук альта, и звук трубы, и звук гитары, и звук колоколов практически на одних и тех же формулах. А их, как я говорил, всего лишь три группы, или класса (вместе с обертонами четыре).   Возможности к вариации звука великолепные, и это на таком скудном материале.
  Мне кажется, что по-периодный метод синтеза звука имеет большие перспективы.

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


   СОЗДАНИЕ РЕЛЬЕФА НА ОСНОВЕ РЕПЛИК

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

MU3=0 : AU3=3 : DU3=20.996

  Первое означает, что никакой модуляции звука (амплитудного вибрато) нет, второе - что начальная амплитуда звука равна 3, третье - что эта амплитуда достигается не сразу, а по прошествии 20-ти периодов от начала звука, и в дальнейшем амплитуда затухает с декрементом 0.996 на каждый период.
  Но главным параметром группы рельеф является строка Arr$ - переменная, в которой записаны амплитуды звука для некоторых точек внутри периода.
  Таких точек может быть не очень много, например, десять. Тогда первая точка располагается на расстоянии 1/20 после начальной точки периода, вторая точка - на расстоянии 1/10 после первой, и так далее. Десятая точка располагается на расстоянии 1/20 перед точкой окончания периода.
  Строка рельефа Arr$ формируется в момент начала развития звука, и затем, если это необходимо, корректируется перед началом каждого периода. Таким образом, звук не является монотонно повторяющейся от периода к периоду формой, он, как и реальный звук может быть сделан "живым".

  К изображению рельефа в строке Arr$ можно подойти двумя путями. Первый путь теоретический. Если у нас есть какие либо соображения о том, как должен выглядеть рельеф звука внутри периода, например, хотим мы отобразить в рельефе несколько наложенных друг на друга обертонных колебаний, или изобразить характерную форму, подсмотренную нами в реальном звуке, - пожалуйста, мы можем сделать это. И проверить наши соображения.
  Второй путь полностью прикладной, он аналогичен созданию звукового семпла. Но если звуковой семпл создаётся целиком, в расчёте на длительное звучание, то в переменную Arr$ помещается реплика (упрощённая копия) рельефа реального звука, длительностью в один период.

  Реплика упрощает рельеф реального звука не только в отношении своей длины (недостающие в реплике точки восстанавливаются методом сплайн интерполяции), но и в расквантовке амплитуды - амплитуда звука в реплике представлена в интервале (-1,1) с точностью 2%. Для практики это вполне достаточная точность.
  Благодаря такому упрощению рельеф звука в реплике может быть представлен рядом целых чисел с двумя цифрами, например, так (пробелы в строке можно заменить нулями) -

   Arr$="5160998050 1 0 49" что означает амплитуды .02 .2 .98 .6  0 -.98 -1 -.02

принцип понятен - число 50 символизирует нулевой уровень, а отступления от этого числа – амплитуду.
  На рисунке в начале статьи показаны две строки-реплики Arr$, снятые с разных участков звука певческого голоса - меццо-сопрано, фонема "а", нота Ре второй октавы. Фрагмент реального звука показан на нижнем слайде рисунка.
  И та, и другая реплика, будучи размножена, звучит действительно, как фонема "а", но звучит достаточно бесцветно и монотонно, оно и понятно - звук не "живой".
  Однако если синтез звука построить на нескольких репликах, не только плавно перетекающих одна в другую, но и совершающих вибрато в этом своём перетекании, то есть не перетекающие монотонно, а совершающие ускорения, замедления и обратные движения в перестройке рельефа (перестройке тембра), то получается вполне реальный и красивый на слух звук певческого голоса.
 

   ПОЛУЧЕНИЕ РЕПЛИК

  Разумеется, хочется не писать строки реплик Arr$ вручную, а, имея запись реального звука (хоть тот же семпл, например), автоматизировать этот процесс.
  Построим стратегию наших действий.

  В простом и удобном редакторе Wave Editor можно копировать и вставлять в любое место отдельные фрагменты записи. Давайте запишем в начало записи некую метку, а потом скопируем её и вставим в начало и в конец того периода звука, реплику которого мы хотим получить.
  Затем обратимся к программе на языке Турбо бейсик (текст программы см. ниже), и она поищет в записи наши метки и создаст реплику того, что находится между ними.

  Такова стратегия наших действий.
  В качестве метки я взял 20 нулевых значений амплитуды, десять значений числа 130*32=4160 (вместо 130 можно взять любое число до 1000, число побольше - метка повиднее), и снова - 20 нулевых значений амплитуды.
  Как выглядит метка в окне редактора вы можете видеть на рисунке. Между метками - период реального звука. Вне меток для сравнения показан рельеф, сделанный программой ТРИО по реплике.
  Видно, что сделанный рельеф мало чем отличается от рельефа реального образца.

  Практически работа по созданию реплики делается так -
1. Помещаем файл записи в файл FR.wav
Если запись сделана не в моно, или не в WAV формате, то предварительно нужно её преобразовать. Как из стерео 44100 получить моно 32000, описано в статье "Преобразование WAV файлов".

2. Заменяем в тексте программы 130 на отрицательное значение -130 и запускаем программу. Программа создаёт метку в начале записи.

3. Копируем метку из начала записи (копировать все нулевые значения не обязательно, достаточно скопировать середину метки и часть нулевых значений).

4. Вставляем метку в начало и в конец интересующего нас периода, того периода, из которого мы будем делать реплику

5. Восстанавливаем в тексте программы положительное значение MARK=130 и указываем в переменной LR число точек в реплике. Запускаем программу.   
  Результат получаем в файле REPL.TXT
 
 Хотите повторить процесс для получения другой реплики? Приведите в негодность расставленные ранее метки, для чего достаточно убрать один семпл из середины метки, и повторите процесс от пункта 3.

 Записали три строки, три реплики от интересующего Вас звука - создайте ротацию этих строк, так, как это описывается здесь: http://www.proza.ru/2016/04/22/1982 и Вы получите синтезированный звук, очень похожий на натуральный.
__________
  Программа, которая приведена ниже, в настоящее время включена в состав Манипулятора WAV файлами, и для создания реплик я рекомендую пользоваться им.
Процесс подробно описан тут - http://www.proza.ru/2017/10/20/1279



   ТЕКСТ ПРОГРАММЫ

  Программа для создания строки - реплики периода по данной записи.
  Для работы с меткой используем флаг:
флаг F=1 ждём 0
       2 нашли 0 начала, пропускаем 0, ждём MARK
       29-21 нашли MARK, ожидаем только MARK
       20 ожидаем только 0 конца
       3 ждём <>0
непропускаемое и неожидаемое устанавливает флаг в 1 

 'ZREPL.bas
OPEN "B",#1,"FR.wav"
MARK=130 : LR=30

 SEEK #1,40 : GET$ #1,4,S$ : ND=CVL(S$) : PRINT ND;
IF MARK<0 THEN
  M%=INT(.5-32*MARK) '32000 max
  FOR I=1 TO 20 : PUT$ #1,MKI$(0) : NEXT I
  FOR I=1 TO 10 : PUT$ #1,MKI$(M%) : NEXT I
  FOR I=1 TO 20 : PUT$ #1,MKI$(0) : NEXT I
  CLOSE #1 : PRINT "mark OK" : STOP
  END IF
'===
 M%=INT(.5+32*MARK) '32000 max
 IF FNP(44+50)<0 THEN CLOSE #1 : PRINT "mark1 not found" : STOP
 PB=PPE : IF FNP(PPE)<0 THEN CLOSE #1 : PRINT "mark2 not found" : STOP
 PE=PPB : PRINT "  ";PB;"-";PE;"  f=";32000/(PE-PB-2)
'===
 OPEN "REPL.TXT" FOR OUTPUT AS #2
 K=(PE-PB)/2 : DT2=1/LR : DT1=1/K : R$="" : T1=0 : T2=DT2/2 : maxA=0
 FOR I=1 TO K 'amplitude max
   GET$ #1,2,S$ : B%=CVI(S$) : B=ABS(B%) : IF B>maxA THEN maxA=B
 NEXT I : PRINT "maxA=";maxA;
 SEEK #1,PB+2 : A=0 : GET$ #1,2,S$ : B%=CVI(S$) : B=B%
 FOR I=1 TO LR
   DO WHILE T2>T1+DT1 : A=B : GET$ #1,2,S$ : B%=CVI(S$) : B=B%
   T1=T1+DT1 : LOOP
   C=A+(B-A)*(T2-T1)/DT1 : PRINT #2,C
  A$=STR$(CEIL(C*45/maxA+50)) : IF LEN(A$)>2 THEN A$=MID$(A$,2,2)
  R$=R$+A$
   T2=T2+DT2 : NEXT I : PRINT #2,CHR$(34);R$;CHR$(34)
 CLOSE #1,#2 : PRINT "Ok"
STOP
'=== подпрограмма поиска метки
DEF FNP(NN) 'find mark
  LOCAL F,N
  N=NN : F=1 : SEEK #1,N
 DO WHILE F>0
  IF N-43<ND THEN GET$ #1,2,S$ : C%=CVI(S$) : N=N+2 ELSE F=-1
  IF F=3 AND C%<>0 THEN F=0 : PPE=N-4
  IF F=20 THEN
    IF C%=0 THEN F=3 ELSE F=1
  END IF
  IF F>20 THEN
    IF C%=M% THEN F=F-1 ELSE F=1
  END IF
  IF F=2 AND C%=M% THEN F=29
  IF F=2 AND C%<>0 THEN F=1
  IF F=1 AND C%=0 THEN F=2 : PPB=N-2
 LOOP
 FNP=F
END DEF
'========   







 


Рецензии
Я бы посоветовал автору почитать что-нибудь про FM-синтез. Не поверхностное, а что-то вроде руководства по эксплуатации Yamaha DX7 или книжку Tony Horgan по Korg Volca FM. Всё это, правда, на английском.
Ещё лучше приобрести вышеупомянутый синтезатор (он стоит недорого, 10-12 тыс.руб.) и основательно в нём покопаться. Есть и чисто сотовый бесплатный вариант - Dexer FM.
Треуголку Наполеона сдует наверное, но кипучая энергия автора может быть направится в более продуктивное русло.

P.S. Очень интересных результатов добилась Atary с чипом AMY, реализующим аддитивный синтез. Была у них утилита, автоматически вычисляющая коэффициенты для Фурье. В общем, мир не так глуп как кажется автору и потому велосипед им (миром) был уже давно изобретён.

Инженер Филиппов   31.07.2018 15:23     Заявить о нарушении
Вы знаете, но алгоритмы FM синтеза подробно не публикуются. Вот и приходится изобретать уже ранее, и не мной изобретённый велосипед. Задача-то состоит не в том, чтобы взять готовый синтезатор, и использовать его, а в том, чтобы понять как конкретно в нём создаётся звук. Статья по FM синтезу у меня тоже есть, просто Вы её не читали - http://www.proza.ru/2017/09/03/103
По моим прикидкам метод этот ограничен. Для фортепьянного звука он годится, но скрипичный звук с ним я не знаю, как создать. Кроме того, используя этод, не удаётся создавать аккорды так просто, как это делается в программе ТРИО. Потому я этот метод хоть попробовал, но не использую.

Также Вы с трудом найдёте описание МИДИ формата на достаточно полном уровне, чтобы с ним можно было бы практически работать. Потому некоторые вещи приходится подробно изучать самому. У одного из моих читателей возникли проблемы с коррекцией МИДИ файлов, получаемых им на синтезаторе Ямаха, и только я, с моими "велосипедными" знаниями, помог ему разобраться с его проблемами.

Возможности метода по-периодного синтеза вообще, как я понимаю, нигде не исследованы на должном уровне. Если Вам публикации в сети по этим проблемам известны, то буду Вам благодарен за ссылки на них.

Что касается использования разложения Фурье в деле синтеза музыкального звука, то это действительно то, с чего изучение музыкального звука начиналось и используется для его анализа до сих пор. Однако алгоритмы синтеза, использующие Фурье ряды, требуют длительного времени счёта даже при современном уровне развития вычислительной техники, по той простой причине, что компонент Фурье для вычисления звука с отчётливым тембром нужно, как оказывается, очень много. И кроме того, если приемлемый звук и будет получен, то совершенно непонятно, как тембром такого звука управлять.

Вот только по этим причинам и приходится велосипед самостоятельно изобретать.
Однако велосипед неплохо работает, согласитесь. ))
Спасибо за интерес.

Дмитрий Маштаков   31.07.2018 16:14   Заявить о нарушении
На это произведение написаны 3 рецензии, здесь отображается последняя, остальные - в полном списке.