что такое distortion в играх
XNA Draw: улучшаем графику игры
Все мои восемь статьей на хабре — статьи о геймдеве, большая часть из них связана с таким замечательным фреймворком, как XNA. Первым знакомством с XNA была статья о создании музыкальной игрушки, потом сложность статей нарастала, я начал писать об системах частиц, а затем о шейдерах и еще шейдерах.
В целом — на шейдерах я и хотел закончить, однако, стоить немного дополнить их, я расскажу о нескольких алгоритмах для улучшения графики в игре. Примеры улучшений:
Если интересно — под хабракат.
Введение
Затронем мы опять 2D составляющую игр и будем работать только с пиксельными шейдерами.
Эта статья будет немного отличаться от других моих, тут сразу будет идти и теория и практика, подразумевается, что вы уже читали статьи о шейдерах тут и еще тут.
Рассмотрим все эффекты, которые использовались в игре и пару эффектов, которые там отсутствовали, видео довольно старое, а игра уже потерпела качественные изменения с тех пор.
Distortion (искажение)
Самый первый эффект, который бросается в глаза — искажения:
Этот эффект не обрабатывается специальным шейдером, в целом, он такой же, какой и в статье, которую я писал ранее.
Давайте разберем тот эффект взрыва.
Тут используются следующие текстуры:
В самом верхнем левом углу — текстура дыма, дым образует «кольца» вокруг взрыва, яркую область в взрыве, которая быстро гаснет и шлейф от ракеты. Является основной текстурой этого эффекта. Используется как видимая текстура и искажающая текстура.
Далее — точка, рядом с дымом, благодаря ей — есть молнии, которые исходят из центра взрыва. Так же, используется как видимая текстура и искажающая текстура.
Ну и для дополнительной красоты — частицы от взрыва, самая большая текстура на стрипе. Но тут стоит отметить, что игрок её никогда не увидит на прямую. Она является искажающей и довольно быстро исчезает.
HUD Distortion (искажение интерфейса)
Второй эффект, который можно было заметь в ролике — искажение интерфейса.
На этот эффект меня вдохновили такие игры, как, например, Crysis 2 и Deus Ex: Human revolution. Там, при гибели — интерфейсы начинали разнообразно искажаться. Мне это показалось интересным. Так же, я еще усилил искажения интерфейса при простом попадании.
К примеру, гибель игрока:
Этот шейдер очень похож на тот, что был раньше — искажение изображения. Однако, в корню отличается от него. Искажения происходят не от карты искажений, а от математических формул, давайте рассмотрим код шейдер (шейдер максимально упрощен для понимания):
Код довольно прост, а сам по себе результат шейдера смотрится эффектно.
Static texture to dynamic texture
Создание «живых» текстур из менее живых. К примеру, мало кто заметил — мерцания далеких звезд в ролике выше. Хотя, сама текстура — является статической.
Рассмотрим этот шейдер:
Если яркость пикселя (grayscale) больше 20% — создается легкое мерцание, если больше 80% — сильное.
На картинке этого показать нельзя, все видно в ролике.
Ну и рассмотрим еще два эффекта, которых в ролике нет и реализованы они в более новых версиях.
Bloom (эффект свечения)
Эффект свечения знаком всем, так же именуется как Bloom (блюм).
Идея проста, извлекаем из изображения яркие области (введен некоторых порог), затем рисуем нашу сцену и поверх размытую сцену. Яркие области начинают светиться.
Примеры в картинках:
Яркость сцены:
Оригинальная сцена:
Готовая сцена:
Рассмотрим код шейдера, он состоит из двух частей, шейдер который извлекает яркость и шейдер который формирует финальное изображение.
Листинг шейдера, который извлекает яркость:
Листинг шейдера, который дает финальный результат:
Motion Blur (размытие в движении)
Ну и последний эффект, это размытие в движении (motion blur), в совокупности с другими эффектами — придает им «мягкость», резко двигаем мышкой и:
Реализуется он тоже, довольно просто:
Где direction_move — вектор движения.
Заключение
С помощью таких вот вещей — можно придать своей игре большую «изюминку», причем такие вещи делаются довольно просто.
На этом, я думаю, «курс» по 2D играм окончен, через некоторое время — начну писать о создании трехмерных игр.
EAX оказал значительное влияние на развитие звуковых карт, способствовал внедрению многих эффектов для создания неповторимой атмосферы. Знатоки помнят, что одной из ключевых особенностей теперь уже культового проекта Thief была не только уникальная игровая механика, но и потрясающий звук. Именно звуковое сопровождение позволяло позиционировать каждый шорох, грамотно оценивать ситуацию, с головой погружаться в мир воришки Гаррета. По меркам того времени это стало настоящим прорывом.
В современных играх звук занимает значимое место. Безусловно, приятно наблюдать на экране красивую картинку, однако немаловажную роль в создании атмосферы имеет и звук. Ведь пространство не ограничивается областью, попадающей в поле зрения протагониста. Толковая реализация позволяет услышать разницу в выстреле из разных видов вооружения, определить, находится ли враг в помещении или на открытом пространстве. В жанрах вроде ужастиков и сетевых шутеров значимость звукового ряда вовсе трудно переоценить.
Именно о трехмерном звуке, движках, производителях мы поговорим в данной обзорной статье.
3D-звук подразумевает расположение источников звука вокруг слушателя.
Схематическое изображение того, как эффекты реверберации позволяют на слух определять параметры помещения
Для усиления ощущения при восприятии звука слушателем применяются различные технологии. Именно их качественное воплощение заставляет окружающий игрока мир не просто источать яркие краски, но и превращает его в действительно трёхмерное пространство.
На сегодняшний день существует целый ряд различных звуковых API. Мы поговорим о тех, которые либо до сих пор используются, либо представляют историческую ценность.
Актуальные звуковые API
OpenAL (Open Audio Library)
Этот API использует эффекты EAX. Данный интерфейс задействован в движках id Tech 3 и 4 (DOOM 3, Enemy Territory: Quake Wars, Prey, Quake 4, Wolfenstein), некоторых играх, основанных на Unreal Engine 3, а также в ряде множества других проектов (Battlefield 2, S.T.A.L.K.E.R., F.E.A.R., FarCry, Time Shift и прочие).
Интересно, что компания Creative позволила использовать свою запатентованную технологию обработки теней студии id Software только в обмен на поддержку OpenAL в DOOM 3
OpenAL развивался исключительно программистами Creative. Полноценная реализация наиболее значимых функций и возможностей OpenAL существует только для карт Creative под Windows. Для прочих карт и ОС реализация очень упрощенная, базовая. Всё потому, что это требует наличие аппаратной поддержки, а аппаратный процессор есть только у карт Creative.
Таким образом, если игра использует OpenAL, то звучание на интегрированном звуке на звуковой карте Creative будет разительно отличаться. Разумеется, в пользу последнего. Если же у звуковой карты Creative нет аппаратного процессора, то там используется программная эмуляция до EAX 4.0, не доступная картам других производителей. Хотя данную технологию эмуляции можно лицензировать за деньги даже для интегрированного звука. В то же время EAX 5.0 без аппаратной поддержки не существует. Развитие OpenAL остановилось в 2005 году.
DirectSound
Программный интерфейс, являющийся частью DirectX. Самый старый и распространенный API. Данный API позволяет имеет слабую и ресурсоемкую программную реализацию 3D-звука, которую в играх никто не использует, но зато позволяет задействовать аппаратную реализацию имеющихся эффектов. Таким образом, звучание разных DirectSound звуковых карт отличается.
Интересно, что «аппаратные» вызовы у многих карт реализованы программно. Таким образом, интегрированный звук часто имеет «аппаратный» 3D-звук, реализованный в драйверах. Эта реализация по качеству и возможностям сильно отличается от настоящей аппаратной.
C выходом Windows Vista и значительными изменениями в её архитектуре DirectSound лишился поддержки 3D-звука. Тут возникла одна проблема: многие игры, вышедшие до релиза новой операционной системы, остались без звуковых эффектов. В 2007 году компания Creative разработала технологию Creative ALchemy для X-Fi и Audigy, перехватывающую вызовы DirectSound и транслирующие их в аналогичные команды OpenAL. Благодаря этому старые игры имеют поддержку 3D-звука и EAX в операционных системах Windows Vista и Windows 7. Кроме того компания ASUS предлагает Xonar GX2.5, также позволяющий эмулировать DirectSound в несовременных проектах. Эмуляция ASUS предсказуемо уступает из-за отсутствия аппаратных возможностей в картах этого производителя, кроме того, менее стабильно работает.
В свое время покупатели Windows Vista были сильно озадачены отсутствием 3D-звука в играх. Одна из многих причин, почему хардкорные игроки не спешили переходить на новую тогда операционную систему
Кроме звуковых API существуют ещё и звуковые движки. Это примерно как графические движки, которые отвечают за внешний вид игр. Они представляют собой высокоуровневые функции, сильно упрощающие жизнь программистам. На низком уровне звуковые движки используют базовые функции DirectSound или какого-то другого API по выводу звука.
Наиболее популярные звуковые движки
Ещё семь лет назад FMOD считался «молодым и перспективным», а сейчас активно набирает обороты. Одной из особенностей является мультиплаформерность (поддержка Xbox 360, Playstation 3 и Nintendo Wii) и возможность работать с различными форматами на разных платформах. Уже вышло немало проектов использующих FMOD, в том числе такие хиты как World of Warcraft, Bioshock 1 и 2, Starcraft 2: Wings of Liberty, Mafia 2 и прочие. Также заявлены Crysis 2, Deus Ex: Human Revolution, The Witcher 2: Assassins of Kings.
MilesSS
EAX (Environmental Audio Extensions)
Наконец, остановимся на системе EAX (Environmental Audio Extensions). Сейчас разработчикам доступна EAX 5.0, поддерживающая многие возможности. В частности, именно эта система есть в самом распространённом на сегодняшний день движке Unreal Engine 3. Помимо этого EAX разных версий можно встретить во множестве игр. Грамотное использование потенциала этой технологии позволяет создавать потрясающие звуковые эффекты.
Именно EAX оказал значительное влияние на развитие звуковых карт, способствовал внедрению многих эффектов для создания неповторимой атмосферы. Знатоки помнят, что одной из ключевых особенностей теперь уже культового проекта Thief была не только уникальная игровая механика, но и потрясающий звук. Именно звуковое сопровождение позволяло позиционировать каждый шорох, грамотно оценивать ситуацию, с головой погружаться в мир воришки Гаррета. По меркам того времени это стало настоящим прорывом. Thief: The Dark Project стал одной из первых игр, показавших, что у 3D-звука и технологии EAX есть будущее.
Благодаря технологичному звуку Thief обладал потрясающей атмосферой и был одним их главных поводов покупки звуковых карт Creative
Спецификации разных версий EAX стоит рассмотреть отдельно.
EAX 1.0
Функции по отношению к предыдущей версии
Звуковые карты Creative поддерживающие технологию
Примеры игр, поддерживавших технологию
EAX 2.0
Функции по отношению к предыдущей версии
Звуковые карты Creative поддерживающие технологию
Примеры игр, поддерживавших технологию
EAX Advanced HD 3.0
Функции по отношению к предыдущей версии
Звуковые карты Creative поддерживающие технологию
Примеры игр, поддерживавших технологию
EAX Advanced HD 4.0
Функции по отношению к предыдущей версии
Звуковые карты Creative поддерживающие технологию
Примеры игр, поддерживавших технологию
EAX Advanced HD 5.0
Функции по отношению к предыдущей версии
Звуковые карты Creative поддерживающие технологию
Примеры игр, поддерживавших технологию
Вывод из представленного выше материала напрашивается сам собой, а именно: кроссплатформерность и простота в использовании являются необходимыми условиями для успеха. Всё-таки в нынешней ситуации, когда все издатели (кроме Microsoft, Sony и Nintendo) предпочитают выпускать свои игры сразу на трёх (минимум на двух) платформах одновременно, возможность с лёгкостью применить функции и на PC, и на консолях выходит на первый план. Набравший популярность FMOD тому ярчайшие доказательство.
Производители
Creative
Разумеется, когда заходит разговор о звуковых картах игровой направленности, многим на ум сразу приходит именно компания Creative. За почти три десятка лет своего существования производитель неоднократно преподносил любителям звука приятные сюрпризы, хотя и ценовая политика компании вызывала неоднозначную реакцию. Сейчас в ассортименте компании достаточно продуктов серии X-Fi с привычным PCI Express интерфейсом и с USB, от бюджетной ценовой категории до карт премиум класса.
Auzentech
Корейская компания Auzentech выпускает игровые звуковые карты на чипе Creative X-Fi. Эти продукты обладают интересными характеристиками и подходят и для аудиофилов и для игр, но, к сожалению, у нас про эту компанию мало кто знает и данную продукцию не так-то просто найти в магазинах.
Не так давно на рынке звуковых карт появился ещё один игрок, которого трудно не заметить. Речь идет о компании ASUS, имя которой ассоциировалось с материнскими платами, видеокартами, ноутбуками, оптическими приводами.
Эти звуковые карты разрабатывает и производит дружественная тайваньская компания C-Media. ASUS выступает только OEM-заказчиком и спонсором разработки. С этим связана зачастую нестабильная работа карт ASUS и скромные возможности, что нетипично для других продуктов этого производителя.
Называть всех производителей мы не будем. Причин тому предостаточно: и отсутствие должной информации от компаний, и проблемы с доставкой в Россию, и ориентация на узкий круг профессионалов, а не на широкие массы потребителей. Для игроков они не представляют особого интереса.
Distortions
Distortions — красивое сюрреалистичное приключение с видом от третьего лица, в котором главную роль играет музыка. Главная героиня игры. Подробнее
Об игре Distortions
Distortions — красивое сюрреалистичное приключение с видом от третьего лица, в котором главную роль играет музыка. Главная героиня игры путешествует через неизвестную бескрайнюю и сюрреалистическую долину, созданную из её искажённых воспоминаний и минувших отношений. Героине нужно восстановить свою память, а в этом ей поможет скрипка. С её помощью предстоит решать загадки и открывать новые области в игре. В игре вас ожидает открытый мир, красивые пейзажи, три способа игры на скрипке и более 15 часов геймплея. Также героиня может освоить 5 уникальных способностей для приручения или управления местными странными существами.
Скриншоты
Несколько лучших скриншотов из Distortions:
Последние и новые скриншоты смотрите в галерее.
Системные требования
Минимальные системки для игры:
Подробные и рекомендуемые требования к PC ищите на странице системных требований для Distortions.
Даты выхода
Distortions уже вышла на PC.
Полный список дат выхода и платформ смотрите на странице релизов.
Где купить игру со скидкой?
VGTimes ищет и сравнивает цены на Distortions в разных магазинах, чтобы вы могли купить игру дешевле, чем в Steam, PS Store и других официальных сервисах дистрибуции.
Вот некоторые актуальные предложения:
Еще больше скидок и вкусных цен ищите здесь.
Похожие игры
Вот несколько игр, которые больше всего похожи на Distortions:
Смотрите весь список похожих игр здесь и выбирайте, какая из представленных игр больше всех напоминает Distortions. Там же вы сможете добавить новую игру в список похожих.
Программирование&Музыка: Delay, Distortion и модуляция параметров. Часть 4
Всем привет! Вы читаете четвертую часть статьи про создание VST-синтезатора на С#. В прошлых частях мы генерировали сигнал, применяли к нему амплитудную огибающую и фильтр частот.
В этот раз мы рассмотрим эффекты Distortion — искажение сигнала, знакомое любому электрогитаристу и Delay (оно же эхо).
Множество различных интересных звучаний можно получить, если менять (модулировать) значения параметров составляющих частей синтезатора (генератора, фильтра, эффектов) во времени. Рассмотрим вариант, как это можно сделать.
Скриншот VST плагина GClip
Цикл статей
Оглавление
Клиппинг, искажения, овердрайв и дисторшн
Начальные модели гитарных усилителей и звукоснимателей были простыми и низкокачественными, соответственно, добавляли искажения в обрабатываемый сигнал. При использовании аналоговых усилителей сигнал искажался в зависимости от исходящей громкости сигнала. С ростом амплитуды сигнала коэффициент нелинейных искажений возрастает, добавляются различные гармоники. Если вы включите ваши бытовые колонки на максимум, то, уверен, тоже услышите искажения.
Есть история, как в 51’м году гитарист группы Kings of Rhythm использовал усилитель, который был поврежден в пути, и продюсеру понравилось звучание — таким образом, была сделана одна из самых ранних записей искажённой гитары.
Эффект «Дисторшн» — переводится с английского как «искажение». Если сигнал начать жестко ограничивать по амплитуде, будут создаваться нелинейные искажения, появляться новые гармоники. Чем больше ограничение (Theshold), тем больше искажается сигнал.
Почти любая гитара в жанре со словом «рок» обработана эффектом дисторшн или овердрайвом. Линк на аудиопримеры знаменитых эффектов.
Овердрайв отличается более плавным ограничением амплитуды, нежели у дисторшна. Овердрайв еще называют Soft Clipping, а дисторшн, соответственно, Hard Clipping. Овердрайв на гитарах применяют в более «спокойных» жанрах типа инди-рока, поп-рока и тому подобных.
Примерное сравнение эффектов Distortion (Hard Clipping) и Overdrive (Soft Clipping)
Клиппингом называют нежелательные артефакты (щелчки), при превышении цифровой амплитуды в 0 dB. Есть эффекты, реализующий «чистый» (не эмулируя какие-либо аналоговые педальки или преампы) дисторшн сигнала. Например, плагин GClip (в начале статьи как раз его скрин) просто математически обрезает входящий сигнал по амплитуде.
Кодим эффект дисторшн
Из вышесказанного выводим, что, по сути, жесткий дисторшн определяется только параметром максимального абсолютного значения амплитуды — Threshold. У нас абсолютные значения семпла не превосходят 1, значит и Threshold заключен в интервал [0,1].
Чем больше мы ограничиваем сигнал (чем ближе Threshold к нулю), тем он становиться слабее по громкости. Чтобы громкость сигнала не менялась, можно ее восстановить: поделим значение семпла на Threshold.
Получаем простой алгоритм для жесткого дисторшна, который применяется для каждого семпла в отдельности:
Возвращаемся к написанному мной синтезатору (обзор архитектуры классов в первой статье). Класс Distortion будет наследовать класс SyntageAudioProcessorComponentWithParameters и реализовывать интерфейс IProcessor.
Дилэй и реверберация
Дилэй, оно же эхо — эффект повторения сигнала с задержкой. Обычно под дилеем понимают четкое повторение (многократные повторения) сигнала. Войдите в арку, переход — вы услышите, как короткий громкий звук будет отражен несколько раз, теряя громкость. Если же стоять в концертном зале, с гораздо сложной архитектурой и отражающими звук поверхностями, чем арка в доме — вы уже можете не услышать четких повторений, а плавно затухающий звук.
Реверберация — это процесс постепенного уменьшения интенсивности звука при его многократных отражениях. Принятое время реверберации — время, за которое уровень звука уменьшается на 60 dB. В зависимости от устройства комнаты/зала время реверберации и звуковая картина могут очень сильно отличаться.
Слушать всегда лучше, чем читать про звук. А можно и посмотреть.
Следует упомянуть про реализацию эффекта реверберации посредством свертки (Convolution Reverb). Суть в том, что имея на руках специальный файл, «описывающий» нужное нам помещение (импульсный отклик), можно совершенно точно воспроизвести реверберацию от нужного звука в этом помещении.
Для получения импульсных откликов (их называют просто импульсы/impulses, которых очень много в сети) нужно установить микрофон в нужном помещении, включить запись и воспроизвести звук — «импульс» — вернее, максимально приближенное к нему явление: например, какой-нибудь предельно резкий удар; записать эхо нашего импульса.
Мы получили способ полностью воссоздать акустику помещения — по крайней мере в той степени, в какой нам это гарантирует неизменность звука при неизменности импульсной функции. Не все параметры процесса определяются импульсной функцией, но большинство важных для человека — всё же определяется.
Схожим образом делают импульсные отклики гитарных кабинетов, для использования их в реампинге гитар на компьютере.
Кодим эффект дилэя
Эхо — это повторения сигнала с некоторой временной задержкой. То есть, текущее значение сигнала складывается как текущее новое значение плюс значение сигнала t времени назад, t — время задержки.
Простая формула для значения семпла:
Где x — входная последовательность семплов, y — результирующая, T — задержка в семплах.
Нужно хранить последние T рассчитанных семплов. Каждый раз нужно будет получать значение семпла с задержкой и сохранять новое рассчитанное значение. Для этих целей подойдет циклический буфер.
Гитарная педаль Ibanez AD9 Analog Delay
Чтобы регулировать громкость (я бы сказал «количество») дилея, можно в формулу подставить множители. Обычно в плагинах используют термины Dry/Wet — соотношение в миксе необработанного («сухого») и обработанного («мокрого») сигналов. В сумме коэффициенты равны 1, так как обозначают доли. На фотографии педали параметр Wet называется Delay Level.
В данной формуле нет затухания эха, оно будет всегда повторяться с таким же уровнем громкости. Такой параметр обычно называют Feedback (на фотографии параметр называется Repeat), он снижает громкость в зависимости от времени.
Получается, в нашем простом дилее будет 4 параметра:
Чтобы найти T (задержка в семплах, он же размер буфера семплов) нужно умножить частоту дискретизации на параметр Time. Чтобы каждый раз не выделять память под буфер при изменении параметра Time, сразу создадим массив максимальной длины Time.Max * SampleRate.
Напишем вспомогательный класс для циклического буфера:
Функция для рассчитывания семпла:
Модуляция параметров
На данном этапе рассмотрена и закодена следующая цепочка генерирования звука (все это вы найдете в предыдущих статьях):
После эффектов сигнал обычно проходит мастер-обработку (обычно просто регулирование результирующей громкости) и подается на выход плагина.
Имея такую последовательность, уже можно получить самые разнообразные звучания.
Очень много звуков сделаны изменением какого-либо параметра во времени. Например, в звуке выстрела «лазерного пистолета» можно отчетливо слышать, как основная частота меняется с высокой на низкую.
По идее, про все наши параметры (класс Parameter) знает хост, они существуют не только внутри нашей архитектуры. В хосте можно сделать автоматизацию параметра, чтобы менять их со временем.
Автоматизация параметров в FL Studio 12. Сверху трек «Cerbera» — дорожка с нотами для синтезатора Sytrus, ниже треки с графиками изменения параметров (Vocodex, Flangus, Delay, Reverb) добавленных VST-эффектов на данном треке синтезатора
Конечно, такая автоматизация очень удобна и очень часто используется при создании музыки. Но такая автоматизация будет работать только при проигрывании трека, ее сложно настраивать. Если мы хотим, чтобы какой-то параметр менялся при каждом нажатии ноты, или просто постоянно менялся по какому-либо закону? Логичнее сделать автоматизацию уже в самом плагине — будет больший простор для работы создания звука.
Обычно в синтезаторах есть специальная часть/блок/модуль, отвечающий за модулирование параметров. Ее так и называют, блок модуляции или матрица модуляции. Модуляция параметров похожа на модулирование амплитуды ADSR-огибающей из 2-й статьи. Только теперь представьте, что вместо огибающей можно придумать вообще любой закон изменения параметра, и модулировать любой параметр в плагине (который подразумевает, что его можно модулировать).
В качестве «закона» обычно берут огибающие и LFO (Low Frequency Oscillator — по сути, такой же осциллятор, но его семплы используются как множители для модуляции а не как звуковая волна). Во многих синтезаторах можно вручную нарисовать график изменения параметров, или собрать его из заранее заготовленный паттернов.
Блок модуляции в синтезаторе Sylenth1. Есть две ADSR-огибающие, два LFO-генератора и модуляция на основе других источников (типа Velocity от нажатия ноты). Для каждого источника можно указать два модулируемых параметра и «степень модулирования» как промежуточный множитель (крутилка слева от имени параметра).
Матрица модулирования в синтезаторе Serum. Каждая строка описывает пару «источник — модулируемый параметр» с дополнительными настройками (тип модуляции, множитель «количества», кривая и так далее).
Огибающие и LFO в синтезаторе Massive. Можно вручную нарисовать кривую изменения, из отдельных паттернов/кусочков.
Пишем класс LFO
Блок модуляции в написанном мною синтезаторе
Напишем класс LFO: его задача будет заключаться в модулировании параметров. Осциллятор будет генерировать волну с амплитудой в интервале [-1,1], которую мы будем использовать как множитель для параметра. LFO-осциллятор вообще принципиально ничем не отличается от обычного осциллятора, который мы кодили для генерирования простой волны. Приставка «низкочастотный» написана потому, что он может генерировать очень низкие частоты (меньше герца). Так как человек не слышит ноты ниже
20 Герц, то на нотной клавиатуре (соответственно, на основном осцилляторе) нет таких низких частот.
Осциллятор имеет следующие параметры: частота, и тип волны (Sine, Triangle, Square, Noise).
Для удобного генерирования таких сигналов ранее была написана функция WaveGenerator.GenerateNextSample.
Рассмотрим, каким образом будем модифицировать значение семпла. Все параметры (класс Parameter) имеют свойство RealValue, которое отображает значение параметра в интервал [0, 1]. Это-то нам и нужно. Осциллятор генерирует значения в интервале [-1,1]. По сути, мы крутим ручку параметра то до максимума вправо, то до максимума влево.
Есть проблема — допустим, значение параметра равно 0.25. Чтобы одинаково изменять параметр в меньшую и большую сторону, можно менять его только от 0 до 0.5 (-1 соответствует 0, 1 соответствует 0.5, при 0 — параметр не меняется и равен 0.25). Таким образом, возьмем наименьший отрезок, который делит значение параметра r: f=min(r, 1 — r).
Теперь параметр будет меняться в диапазоне [r — f, r + f].
Добавим еще параметр, чтобы контролировать «ширину» изменяемого диапазона значений — Gain, со значениями в интервале [0, 1].
Получаем следующую формулу для модифицированного значения семпла:
Теперь нужно решить, каким образом будет работать осциллятор. Класс LFO не генерирует и не модифицирует массив семплов. Так же, чтобы работал осциллятор, нужно запоминать прошедшее время. Поэтому отнаследуемся от интерфейса IProcessor, в функции Process(IAudioStream stream) будем считать число пройденных семплов. Если поделить его на SampleRate, то получим пройденное время.
В синтезаторах есть опция, чтобы LFO синхронизировался с нажатием клавиши. Для нас это значит, что при нажатии (обработчик MidiListenerOnNoteOn) нужно сбрасывать фазу осциллятора (сбрасывать время на 0). За это будет отвечать параметр-переключатель MatchKey.
Функция, рассчитывающая значение семпла ModifyRealValue будет принимать на вход текущее значение параметра currentValue и текущий номер семпла sampleNumber. Каким образом корректно использовать модифицированное значение будет написано далее. Сейчас нужно понять, что функция ModifyRealValue будет вызвана для каждого семпла во входящем массиве сеплов (который в функции Process).
Получаем следующие методы:
Самый главный параметр в классе LFO — ссылка/имя модулируемого параметра. Для этого придется написать класс ParameterName, который будет отображать список возможных для модулирования параметров. Отнаследуемся от IntegerParameter, значение параметра будеть означать номер в последовательности параметров у ParametersManager. Подводный камень — нужно указывать максимальное значение параметра — общее число параметров, которое в процессе разработки меняется.
Интерфейс IParameterModifier и использование актуального значения параметра
Теперь класс параметра должен определять, возможна ли его модуляция. В закоденном мною синтезаторе рассмотрен простой случай — есть один объект класса LFO, и модулировать можно не более одного параметра.
Поскольку параметр может быть связан с одним IParameterModifier, сделаем ссылку и свойство ParameterModifier. Для получения актуального значения нужно вместо свойства Value использовать метод ProcessedValue, для этого передать текущий номер семпла.
Использование метода ProcessedValue вместо Value немного усложняет программирование из-за параметра sampleNumber, который нужно передать. Когда я написал класс LFO, пришлось во всех классах менять Value у параметров на ProcessedValue. В основном, семплы обрабатывались в цикле, и передать sampleNumber не составило больших проблем.
В классе LFO делаем обработчик изменения параметра ParameterName, и в нем нужно поменять у параметра ParameterModifier на this.
Заключение
На этом цикл статей считаю законченным: я рассказал про самые важные (на мой взгляд, конечно) составляющие синтезатора: генерирование волны, обработка огибающей, фильтрация, эффекты и модуляция параметров. Программирование местами было далеко от идеала, без оптимизаций — я хотел как можно понятнее написать код. Пытливый исследователь может взять мой код и экспериментировать с ним сколько угодно — я буду этому только рад! Есть хороший сайт musicdsp.org с большим архивом исходников различных штук синтеза и обработки звука, преимущественно на С++, дерзайте!
Спасибо всем заинтересовавшимся! Уверен, мои статьи будут видны из гугла и помогут начинающим войти в мир программирования музыки и обработки сигналов. Спасибо за ваши комментарии, в особенности спасибо Refridgerator.
Всем добра!
Удачи в программировании!
Список литературы
Не забывайте смотреть списки статей и книг в предыдущих статьях.