[Из песочницы] Генератор музыки. Web Audio API. Опыт новичка
Контекст и предыстория
Мне 62. Года три назад решил попробовать написать достаточно сложную систему, до этого было только 20 строк на бэйсике в 1981 г., когда нам на 5 курсе радио-факультета (НГТУ, ранее НЭТИ) воткнули 3 месяца информатики. Профессионалом принято считать того, кто предметом владеет и на нем зарабатывает, так что по факту я — новичок.
С другой стороны, я почти всю жизнь занимался относящимися к музыке алгоритмами, застал процесс развития и железа, и ПО и по мере сил участвовал в нем. В 1978 разработал и собрал синтезатор а-ля Mini-Moog (полагаю, 1-й за Уралом), разработал и выпускал 1-ю в СССР звуковую карту с синтезатором для Агат7(9) — советский аналог Apple II, проектировал модуль FM-синтеза для одного из заводов, сотрудничал с Cakewalk (США), PGMusic (Канада), PowerFX (Швеция) — чаще по схеме: «идеи и воплощение от нас, бюджет — от них», участвовал в международных музыкальных выставках MusikMesse (Германия), NAMM (США) и пр. Все это — малая часть, того, что делал, естественно, не один, а с собранной мной на конкретный момент командой.
Плюс к этому принимал активное участие в организации кафедры информатики (1-я в СССР) в Новосибирской консерватории. Там же с 1983 по 2004 преподавал «Музыкальную акустику», «Информатику», «Звукорежиссуру», подготовил диссертационную работу по компьютерному моделированию музыкального исполнения (ISBN 5–9294–0023–7)…
Да, начиналось все с ч/б мониторов, дискет, ОЗУ в 256 кбайт, музыкального ПК собственной сборки… Объяснять музыкантам нужно было все «на пальцах», ибо этот замечательный народ в массе своей далек от всего строгого и упорядоченного. И если тромбонист смог набить страницу текста, он был крут, а виолончелистка, запрограммировавшая «Чижика-пыжика» — просто звезда. К слову, часть педагогов активно сопротивлялась всей этой теме —, а попробуйте сейчас лишить их компьютеров!
Этот опыт стал очень полезным для моего развития, обучения и углубления в предмет. Информатика, как и физкультура, была обязательной для всех факультетов и постоянный поток студентов позволил провести множество тестов, экспериментов по психоакустике, распознаванию образов, пообщаться с музыкантами-теоретиками и… понять, что точных данных и формул у них практически нет. По крайней мере тех, что нужны разработчику музыкального оборудования и программ. Музыковеды, к сожалению, по сути своей — историки, описывающие прошлое. Если бы у них была наука, то… наверное, попасть к ним на консультацию было бы сложение, чем к мэру города-миллионника. Сколько бы известный музыкант заплатил за «формулу хита» и «прогноз продаж»?…
Вот, допустим, нам нужно получить ответы, которые сгодятся для таких, например, алгоритмов:
а) прозвучала мелодия (ну, пусть она уже даже записана «нотами» в MIDI), как определить, где тоника? — Музыкант это сделает легко, но внятный ответ (алгоритм) вам не даст;
б) есть мелодия, как к ней подобрать правильные аккорды?… Да, дирижер-хоровик сделает это, скорее всего, лучше, чем вокалист, но оба, даже если выдадут инструкцию, то не очень ясную. Конечно, с их точки зрения, она будет строгой. Только когда инженер начнет переводить ее в алгоритм, там встретится несколько трудно преодолимых undefined…
в) или вот что-то в меру сложное играет барабанщик, или импровизирует саксофонист — как «снять» размер, сильные / слабые доли, начало / конец музыкальной фразы, выразительное замедление / ускорение? Речь не об EDM (Electronic Dance Music). Музыкант-исполнитель чувствует и соблюдает «правила», переданные педагогом способом «делай, как я», но инженеру нужны числа, графики, пропорции, а все это практически невозможно получить ни от исполнителя, ни от музыковеда-теоретика.
Но именно на подобные вопросы мне хотелось найти ответы. Ведь у реально звучащего произведения может быть грубая модель — музыкальная композиция в формате MIDI, т.е., по сути, «электронная партитура». Это же точные данные, но как с ними работать? В общем, самым интересным для меня в итоге оказался анализ и преобразования MIDI-данных и такие алгоритмы*, как:
Моделирование исполнения 1),
Морфинг 2),
Генерация музыки 3)
И для всего этого определение тональности, авто-гармонизация, авто-фразировка — лишь отдельные подзадачи… Со временем по всем этим темам были получены приемлемые ответы, созданы алгоритмы и программы, что-то попало даже в Cakewalk/Sonar.
* Небольшая расшифровка:
1) анализ квантизированных MIDI-данных, распознавание «музыкальных объектов» (фразы, фигуры) и их изменение в части Velocity, NoteOn, Duration, также наложения Tempo, PitchWeel, Expression, Modulation кривых с целью более полного использования ресурсов синтезатора и достижения большей выразительности.
2) анализ как целого произведения, так и отдельных партий с целью трансформации их из одного размера в другой (например, из 4/4 в 6/8 или в 7/4), из одного лада/гармонии в другие. Причем, чтобы результат был бы «съедобным» — таким, что и на взгляд музыканта является «правильной», без явных нарушений, музыкой.
3) генерация «электронной партитуры» — система, которая, при использовании 1) и 2) и воспроизведении MIDI-данных, давала бы на выходе результат, по звучанию похожий на то, что производит музыкант, аранжировщик, используя компьютер или живой инструмент. Т.е. не что-то абстрактное, порожденное AI, не только для демонстрации в узком кругу специалистов, но вполне «человеческое» и пригодное для использования.
В этой долгой истории было не мало и забавных, если смотреть из настоящего времени, моментов, например, за первый 386 PC пришлось отдать 2 новых москвича «Шиньон» (ИЖ 2715), каждый по 290 тыс.руб. Или как консерватория, чуть не приобрела в Сибирском отделении АН б/у «Минск 32» — я полагаю, этот монстр, слабее смартфона, занимал, кажется, 60–80 м2 и потреблял электроэнергии, наверное, как бар + сауна…
Так вот, сотрудники мои программировали (мы работали с Z80, MOS 6502, «Электроника-60», на первых Win PC из ГДР, с сигнальными процессорами TMS и Analog Devices…), я каждый день видел на экранах «кракозябры» и считал, что все они (программисты) «не от мира сего». Хотя музыкальная партитура то не проще! И ведь некоторые музыканты слышат музыку, глядя в ноты, и даже получают эстетическое наслаждение, если им она нравится! В общем, мне казалось, что все, кто пишет код — гении и это не моё вообще… Но, как показало будущее, я ошибался. Не скажу, что времени много было потеряно, но, наверное, судьба многих проектов сложилась бы совсем иначе…
Первый практический опыт
Из предыдущего опыта я усвоил, что самыми «трудными», «неприятными» для программиста являются 2 вещи: GUI и интерфейсы (т.е. переход из одной среды в другую. Например, принять MIDI-данные от внешнего устройства), особенно, когда подходящих готовых решений нет.
Сначала я взял AutoPlay Media Studio (Indigo Rose Software) — это что-то вроде конструктора для «чайников». Изначально, видимо, предназначенного для быстрого создания CD, DVD меню и autorun.exe. Но, оказалось, что там море функций, а внутри (на LUA) можно сделать почти все: анимацию, проигрывание ogg. Таким образом, большую часть «неприятной» работы (кстати, я думаю, новички именно на подобных моментах и стопорятся) можно было не делать — все готово.
В итоге я за 2 месяца дома в нерабочее время написал аналог обучающей музыкальной программы, которую мы разработали и официально поставляли. Причем, с другим GUI, более интересным функционалом — благо, сделать аудио- и графический контент и протестировать для меня не составляет никакой сложности. Показал в офисе и у одного из ведущих спросил, сколько ему надо времени для того, чтобы сделать такую версию, ответ был — 6 месяцев! Тут, видимо, я первый раз задумался: может мне стоит самому не только баловаться, а начать что-нибудь изучать и попробовать сделать что-то серьезное и… правильно ли я организовал работу. На самом деле, его ответ был честным — просто, «они» не стали бы пользоваться конструктором, а написали бы все сами.
С 2009 часть времени я посвящал работе в студии звукозаписи и созданию видео-рекламы. Как-то одна знакомая спросила, можно ли сделать быстро (и не дорого) сотню 1-минутных роликов (видимо, для раскрутки на YouTube). Ужасно люблю такие задачи! (К слову, давно знаю, что если программиста раза 3 заставить что-то делать не очень творческое, то он напишет скрипт). Спросил у программистов, а если ли такая программа, что может сама «нажимать» кнопки на экране? Wow, это AutoIt!
В общем, ради забавы я написал скрипт, который:
- запускал Opera, открывал сайт какой-то (кажется, голландской), компании, специализирующейся на «text-to-speech»;
- на странице скроллил до RU (озвучка русского);
- открывал *.txt файл в Блокноте, где были заранее из сети скопированы 20–30 анекдотов, абзацами;
- копировал один анекдот, вставлял в поле на сайте;
- запускал SoundForge на запись, а на сайте включал проигрывание;
- записывал и сохранял результат в папочку в mp3 с именем — «порядковый номер + первые 15 символов из текста самого анекдота».
Это работало и я был счастлив, как ребенок. После этого я сказал знакомой — нет проблемы сделать недорого 100 роликов (хорошего качества), только подберите картинки, музыку, заголовки, подзаголовки, описания и пр. — я все приведу в порядок (по размеру, цвету), разложу по папочкам, сделаю шаблон + определю его вариации (random!) и… смогу сделать вам не 100, а 200 таких клипов (в Vegas Pro с AutoIt это легко), сам просматривая их выборочно, а вы уже отберете себе нужное количество… Делать все это не пришлось, но ей за вопрос — спасибо!
Позже я понемногу стал что-то подправлять на сайте, что-то почитывать, что-то пробовать ради спортивного интереса. В частности, делать на JavaScript / CSS скрипты для простой анимации, необходимой в создании видео. Так появились какие-то общие представления и небольшой опыт в PHP, HTML, jQuery, JavaScript, CSS, MySQL. «Кракозябры» почти исчезли и я перестал боятся самой этой темы «программирования». Окончательный перелом в отношении к ней и к своим возможностям произошел, тогда, когда я понял 2 момента:
- вся эта сфера — бесконечный мир и даже сильный программист не всегда ответит на вопрос, если это не его область. Также, как в любой другой сфере. На общий — да, ну, а нюансы — ищите узкого спеца, а лучше копайте сами. Благо есть сеть.
- 99% вопросов, которые у меня возникали по ходу разработки, я решал сам, причем, иногда эффективнее, чем это было в примерах, найденных в интернете. При этом, я понимаю, что по стилю письма, мой код мог быть ужасным.
Генератор музыки
Уже не помню, как я наткнулся на Web Audio API, к этому времени у меня не было ни ООО, ни ИП, ни команды, но после 2–3-х экспериментов, когда «звук пошел», я замахнулся на самый серьезный для меня проект — генератор музыки (который теперь называю AlexAr). Ведь, в Web Audio было все необходимое — генераторы, фильтры, огибающие, микшеры, процессор (на C++), а jQuery, JavaScript и CSS позволяли решить все вопросы с GUI. Фактически в Web Audio можно сделать, как мне кажется, и обработку, и синтез звука любой сложности.
Вот тут началась настоящая работа, почти, как в молодости, когда тебе 25+. Раза 3–4 я начинал сначала, отбросив один вариант системы и собирая новый. Иногда, радикально меняя подход к проектированию того или иного модуля. Параллельно проделал много экспериментов и протестировал новые алгоритмы, которые раньше не применял. Сделал для себя несколько открытий, которые бы не случились без запуска системы. В частности в психоакустике, в восприятии «похожести» музыкальных треков — какие параметры дадут «разную» музыку, а какие, при их формальных различиях, — на слух «одинаковую». Некоторые, очень полезные вещи были найдены в части применения гармонии, в имитации при синтезе щипковых, в фразировке при смене аккордов, лучшем понимании «стилевой точности». Вполне возможно, что все это открыто и описано. Но в жизни часто так бывает, что проще (и полезнее) додуматься самому.
Да, было бы здорово, если бы Web Audio API допускал привязку, использование для синтеза VSTi или чего-то другого, готового. С другой стороны — появился повод вспомнить молодость и написать все необходимые синтезаторы, по-изобретать, по-оптимизировать, как в структуре, так и в алгоритмах и контенте. Почти, как в старину, когда художник не только писал картину, но и краски сам изготовлял…
В итоге после нескольких откатов и переделок, модернизаций (что было хорошей школой и тренировкой мозгов) система стала устойчивой и вполне работоспособной. Ну, не в таком, конечно, виде, когда ее можно передать 3-му лицу. Это, примерно, как самодельный автомобиль, который «слушается» только создателя и если сломается, то починить его будет некому…
В общем, готовую композицию на 4–5 мин, она создает за 40–50 сек. (на Intel Core i5, 2.8GHz, ОЗУ 12ГБ). Я задавал задание, например «сделать 100 Dance треков», переключался на обед или шел прогуляться. Приходил через час и, если система не слетела, слушал и определял %% годности результата. Затем что-то менял в параметрах и запускал снова. Если я вел себя «разумно», т.е. задавал параметры, не приводящие к размыванию стиля (к примеру, это произойдет, если в EDM применить джазовую гармонию), то 90–95% треков звучали вполне прилично, а если нет — то 60–70%% можно было выбросить.
Система заработала, можно радоваться, но тут начались вроде бы смешные, но реальные проблемы: «А как такое количество музыки прослушать?» И осознание еще одного момента: «А кто автор?». Хороший знакомый человек «в теме», сказал, что «автор — компьютер, т.ч. тебе это не принадлежит»… Если так, то обидно, я ведь ввел туда мелодии, фразы, гармонии, формы, настроил пару сотен параметров, где иногда и 5 msec отражаются на результате, а система только сгенерировала результат, опять же по алгоритму, который я в нее вложил… Поискал в сети — не понял, что в подобном случае с авторским правом…
В итоге, я выпустил примерно 3500 композиций с общим временем звучания более 200-х часов и остановился, точнее переключился — планирую запустить SongModeler — онлайн генератор аранжировки на основе подходов, отработанных в AlexAr. Ну, а примеры автоматической генерации музыки в AlexAr можно посмотреть здесь.
Для слишком придирчивых слушателей хочу сказать, что больше времени я уделял программированию, гармонии, мелодии, форме (т.е. нотам), ну, а синтез и сведение, конечно, могут быть намного лучше. В конце концов, идеи, сам подход я проверил — он верный. И для таких проектов нужна команда, одиночки редко берутся за междисциплинарные темы. Правда, с другой стороны, работа становится намного комфортнее, когда «ни над тобой, ни под тобой» никого нет. Но настоящая ирония в том, что когда у меня была команда и ресурсы, я не замахивался на что-то подобное, потому что думал, что это слишком сложно.
Уже где-то в середине работы над AlexAr я понял, что вполне возможно, если бы я начал программировать раньше, то 10 программистов (временами в штате у меня их было значительно больше) можно было бы заменить тремя:
я сам (проектирование, программирование, тестирование, контент);
очень умный — на узкие места, на разведку подходов, новых библиотек, сервисов (сразу после вуза или с 3–4 курса);
продуктивный трудяга на рутинные задачи, без фантазий, у которого не чешутся руки применить сегодня то, что появилось вчера.
Уверен, задача была бы решена быстрее, а сколько нервов и средств было бы сэкономлено! Откуда экономия? Вот, до обеда сел что-то тестить — «ну, не удобно кнопка стоит, да и индикатор бы по-больше и вправо сместить». ОК — сел и через пол-часа сделал, настроение на 5+. А как подобное бы решалось у меня раньше в офисе с командой, когда сам не пишешь? Сначала бы спросил — сколько займет времени, потом нарисовал в PhotoShop, посчитал пикселы, написал ТЗ, включил в план, ждал пару дней или бы… отказался от этого вообще — работает, уже хорошо. И так постоянно.
Выводы и мотивировка
Не знаю, насколько стройно мне удастся сформулировать собственно выводы, да еще не в своей области, но я постараюсь.
- В любой сфере профессионал скептически относится к любителю, новичку и причин для этого достаточно. Однако, сильных профессионалов в любой области не так много и они, как правило, более снисходительны, чем новоиспеченный специалист. Я уверен, что программировать надо пробовать всем и как можно раньше. Вполне возможно, что лет через 10 теорию и практику будут давать в школе, также как родной язык и математику (а может уже дают?).
- Какой язык — НЕ принципиально. Это я раньше думал, что если заказчик просит что-то на macOS или Android, то нужен человек с опытом в этом. Нет, намного важнее навыки структурировать задачу на подзадачи, выстроить архитектуру и способность обучаться. Особенно, если проект сложный.
- Никогда не смешивать в коде GUI с частями, где выполняются алгоритмы и обработка данных — структурировать. Слышал об этом несколько лет подряд, но прочувствовал по-настоящему только когда сам не один раз на эти грабли наступил. Хотя так хочется прямо к слайдеру привязать перевод в экспоненту, запись в массив, вывод на индикатор и еще что-нибудь.
- Как бы не чесались руки по-быстрому что-то слепить, все-таки нужен фундамент — азы, курсы, статьи и пр. Да, когда я заходил в тупик, когда что-то не получалось — я смотрел ролики и сайты. Заработало — тут же бросал учёбу и продолжал «пилить». Но я постоянно ощущал себя учеником 7 класса, который не прошел первые 6 лет обучения. Вроде можно успокоится — ведь оно работает, а почему — неважно. Да, радио-инженер может уже не знать или не помнить закон Ома. Зачем? Все кругом интегральное — домохозяйка может собрать по инструкции усилитель, подключить акустику и устроить гостям праздник. Но у меня все-таки вызывают определенный дискомфорт все случаи, где я «не понимаю физику» — т.е. что именно происходит, когда «работает» эта строка.
- С другой стороны, теперь я понимаю, что достаточно большая часть программистов (software engineer, если быть точным!) вовсе НЕ инженеры. Это механики, часто не очень высокой квалификации, которые могут по аналогии (спасибо им и за это) собрать из готовых модулей что-то, что будет у заказчика прилично выглядеть и работать. И, вполне возможно, если бы они были действительно engineer, они бы решали задачу иначе, поскольку понимали бы «физику, природу», т.е. не только методом «Copy Paste».
- Как и в жизни, в реальном проекте, даже если работа только с текстами по факту «винегрет» из разных языков, библиотек, фрейм-ворков и пр. И это не очень приятно. Было бы здорово изучить что-то одно и не знать о существовании другого… Но если эти языки и средства появились и используются, то значит они работают. Просто для разных задач — разные средства. Я в таких случаях говорю — смиритесь. И, к слову, истинный музыкант, и слушает, и понимает, и может играть разную музыку.
- Что отличает профи от любителя в любой сфере — у него в профессиональный, проверенный инструмент. Надо найти время и выбрать, изучить, настроить IDE, СКВ. Я, к сожалению, до сих пор этого не сделал — NotePad++, инструменты разработчика FireFox и ZIP-архив через день — все, что я использовал. «Наскоком» освоить инструменты не получилось. Попробовал, бросил и продолжил делать «на коленке», но разберусь с этим обязательно.
- Что придает уверенность? Когда ты решил нетривиальную для себя задачу. У меня в проекте такого было много, но понятных, общих момента два — главный таймер и UnDo/ReDo. Штатных функций JavaScript для таймера недостаточно, то что нашел в сети, а хороших решений не много — громоздко. В итоге сделал свой, скорее всего, на основе давнишнего подхода, еще из радиотехники. А с UnDo — честно, я просто не понял, как привязать к своей системе то, что нашел.
В общем, мне кажется, взрослым, особенно с инженерным образованием, не занимавшимся по жизни программированием, стоит пробовать. Если вы знаете свой предмет, то 50% уже сделано. От вас требуется логика, четкое понимание «физики, природы» вашей области, а это, скорее всего, у вас есть. В «кракозябрах» нет ничего страшного и JavaScript намного проще русского или английского языка. В конце концов, вы может не станете истинным software engineer, но эти навыки, даже небольшие, прибавят к вашей инженерной квалификации еще одну опцию. Да, вы тут же перестанете смотреть на айтишников, как на людей с нимбом над головой, и сможете на более компетентном уровне ставить перед ними задачу. Ведь они идут в вашу область, где вы профи. А может вы реализуете свой проект, на своих данных, о чем давно мечтали, но условия для его воплощения так и не сложились — не знаю, я считаю, что мне повезло потому, что я не побоялся попробовать. И по-любому — программирование для инженера, ЭТО СВОБОДА!
Наилучшие пожелания всем.
P.S.: Если кому-то интересна история моей работы по годам в более развернутой форме, то она вот здесь.