This media is not supported in your browser
VIEW IN TELEGRAM
Переделывал выбирательные виджеты, стараясь прорваться к выпадающим спискам. Но список можно сделать таблицей, отчего менял и таблицы тоже. Дилемма: список - таблица с 1 столбцом, или же таблица - список со множеством столбцов.
Виджеты составные: для отладки нужны GUI-инструменты, а для инструментов нужны эти виджеты, что замкнутый круг, в котором смысла сейчас их причёсывать особого нет. Они используют отсечение - клиппинг. У SDL он из коробки, хотя в движке пылятся алгоритмы Коэна-Сазерленда и Лианга-Барски. В нём есть класс коварных багов в получении событий скрытыми узлами сцены, к чему нужно быть готовым. Простые алгоритмы работают по прямоугольнику, пришлось убрать скругления у таблиц.
Таблицы бывают разными: с переиспользованием строк (т.н. виртуальные) и без, со своими плюсами\минусами. Первые быстрее, но разная высота строк и сложная компоновка могут стать проблемой. Пока разделил их, быть может позже появится какой-то гибрид.
#graphics_engine #dlang #dm #программирование
Виджеты составные: для отладки нужны GUI-инструменты, а для инструментов нужны эти виджеты, что замкнутый круг, в котором смысла сейчас их причёсывать особого нет. Они используют отсечение - клиппинг. У SDL он из коробки, хотя в движке пылятся алгоритмы Коэна-Сазерленда и Лианга-Барски. В нём есть класс коварных багов в получении событий скрытыми узлами сцены, к чему нужно быть готовым. Простые алгоритмы работают по прямоугольнику, пришлось убрать скругления у таблиц.
Таблицы бывают разными: с переиспользованием строк (т.н. виртуальные) и без, со своими плюсами\минусами. Первые быстрее, но разная высота строк и сложная компоновка могут стать проблемой. Пока разделил их, быть может позже появится какой-то гибрид.
#graphics_engine #dlang #dm #программирование
This media is not supported in your browser
VIEW IN TELEGRAM
Завершал перестройки более сложных виджетов, среди которых родился улучшенный цветовыбиратор. На первых этапах я копировал значения цвета из палитр, особенно MD2 (https://m2.material.io/design/color/the-color-system.html). Усложнение демок потребовало процедурной генерации цвета с более тонкими его настройками. В движок завезлось HSV, а позже в рандомном туторе было подсмотрено и HSL.
У HSL есть пара недостатков и я несколько раз спотыкался об контринтуитивный максимум яркости посередине (0.5 или 50%) диапазона светлоты, что заставило изучить альтернативы, например, LCH. На хабре есть неплохое сравнение с HSL: https://habr.com/ru/companies/ruvds/articles/496966
Потестировал несколько реализаций LCH в RGB и обратно, грубо замерив их скорость. Увы, она оказалась на порядки ниже в сравнении с таковой у HSL\HSV. Процедурная генерация же требует быстроты, что сводит полезность LCH здесь на нет. Возможно, в будущем выйдет заоптимизировать.
#graphics_engine #dlang #dm #программирование
У HSL есть пара недостатков и я несколько раз спотыкался об контринтуитивный максимум яркости посередине (0.5 или 50%) диапазона светлоты, что заставило изучить альтернативы, например, LCH. На хабре есть неплохое сравнение с HSL: https://habr.com/ru/companies/ruvds/articles/496966
Потестировал несколько реализаций LCH в RGB и обратно, грубо замерив их скорость. Увы, она оказалась на порядки ниже в сравнении с таковой у HSL\HSV. Процедурная генерация же требует быстроты, что сводит полезность LCH здесь на нет. Возможно, в будущем выйдет заоптимизировать.
#graphics_engine #dlang #dm #программирование
This media is not supported in your browser
VIEW IN TELEGRAM
Переделывал индикаторы, попытки наклонить семисегментный не увенчались успехом. Поворот текстуры создавал хотя и малозаметные, но бесячие артефакты, а игра с настройками особо ничего не дала. Тогда я решил сменить концепцию: переложить сглаживание с рендерера на векторную библиотеку, в которой уже вращается сам холст. Теперь сегменты рисует Cairo.
Светодиоды остались композитными: несколько текстур друг на друге с разными прозрачностью и размытием, которое движок делает матрицей свёртки 10x10 с 1/9. Это т.н. фильтр box blur. Вероятно, отсюда и квадратная форма лампочек, в отличие от более сглаженного гаусса. Но мне она понравилась.
Также заинтересовал матричный светодиодный дисплей. У электронщиков видел пример парсинга гифок пайтоном с выхлопом в код ардуиновской библиотеки FastLED. Но сложно сказать, насколько это полезно для графического движка, ибо это, по-сути, просто ряды спрайтов... посмотрим, зарекомендует ли он себя в будущем.
#graphics_engine #dlang #dm #программирование
Светодиоды остались композитными: несколько текстур друг на друге с разными прозрачностью и размытием, которое движок делает матрицей свёртки 10x10 с 1/9. Это т.н. фильтр box blur. Вероятно, отсюда и квадратная форма лампочек, в отличие от более сглаженного гаусса. Но мне она понравилась.
Также заинтересовал матричный светодиодный дисплей. У электронщиков видел пример парсинга гифок пайтоном с выхлопом в код ардуиновской библиотеки FastLED. Но сложно сказать, насколько это полезно для графического движка, ибо это, по-сути, просто ряды спрайтов... посмотрим, зарекомендует ли он себя в будущем.
#graphics_engine #dlang #dm #программирование
This media is not supported in your browser
VIEW IN TELEGRAM
В открытый иллюминатор космической станции заскочила валентинка, сигнализируя о мощных романтических потоках энергии любви за бортом. Самое время спросить у графического движка: смогут ли два сердца согласовать свои непохожие ритмы и соединиться в едином биении? Ответ требует эксперимента.
На этот раз я обошёлся без сторонних картинок, рисовательная нагрузка легла на Cairo. Для сердца взял достаточно популярную формулу (есть даже видеотутор для JS https://thecodingtrain.com/challenges/134-heart-curve), наложив сверху радиальный градиент - белое пятно с малой альфой. Анимация биения вышла случайной, нужные интерполяции сходу не встретились.
На заднем фоне радиальный градиент. Случайная вариация цвета мелких сердечек ±20° по кругу тона от 7D0055, между 0.4 и 0.65 светлоты в HSL. Таймер за несколько секунд уменьшает время биения одного сердца и увеличивает другого, заставляя их синхронизироваться. Быть может, именно так и работает любовь. Всем любви. ❤️
#graphics_engine #dlang #dm #программирование
На этот раз я обошёлся без сторонних картинок, рисовательная нагрузка легла на Cairo. Для сердца взял достаточно популярную формулу (есть даже видеотутор для JS https://thecodingtrain.com/challenges/134-heart-curve), наложив сверху радиальный градиент - белое пятно с малой альфой. Анимация биения вышла случайной, нужные интерполяции сходу не встретились.
На заднем фоне радиальный градиент. Случайная вариация цвета мелких сердечек ±20° по кругу тона от 7D0055, между 0.4 и 0.65 светлоты в HSL. Таймер за несколько секунд уменьшает время биения одного сердца и увеличивает другого, заставляя их синхронизироваться. Быть может, именно так и работает любовь. Всем любви. ❤️
#graphics_engine #dlang #dm #программирование
Графический движок совершил дерзкий гипертехнологический прыжок в систему SDL3 - новую версию популярной медиабиблиотеки, используемой им в роли бэкенда для управления окнами, рисования и прочего. Этот манёвр стоил мне недели жизни на переезд, а ещё неделя была потрачена на шлифование новых SDL-обёрток.
В SDL3 сменились возвращаемые значения из функций, все вызовы пришлось рефакторить. На виджетах заметны графические артефакты, разная толщина линий, корявости шрифта, но я безмерно рад, что движок запустился.
Все ждали абстракций над графическими интерфейсами - SDL GPU, открывающие условно кроссплатформенный путь к самым красивым явлениям компьютерной графики - шейдерам. Но изучать их, как и доделывать оставшиеся текстовые виджеты, буду позже.
Новый курс - медиасистема. Затраты времени непредсказуемы и я боюсь не уложиться в срок. Она может затребовать смены архитектуры, многопоточности, как и перебора разных библиотек
Нарисовались уже, теперь пробуем звукать.
#graphics_engine #dlang #dm #программирование
В SDL3 сменились возвращаемые значения из функций, все вызовы пришлось рефакторить. На виджетах заметны графические артефакты, разная толщина линий, корявости шрифта, но я безмерно рад, что движок запустился.
Все ждали абстракций над графическими интерфейсами - SDL GPU, открывающие условно кроссплатформенный путь к самым красивым явлениям компьютерной графики - шейдерам. Но изучать их, как и доделывать оставшиеся текстовые виджеты, буду позже.
Новый курс - медиасистема. Затраты времени непредсказуемы и я боюсь не уложиться в срок. Она может затребовать смены архитектуры, многопоточности, как и перебора разных библиотек
Нарисовались уже, теперь пробуем звукать.
#graphics_engine #dlang #dm #программирование
Ласкаясь в тёплых лучах весеннего солнца, станция отмечает в бортовом журнале начало марта, яркие краски цветочных букетов которого заметны даже из космоса. Пользуясь таким случаем, станция поздравляет всех обитательниц этой планеты с их Праздником.
Начались эксперименты с аудиосистемой, для первого уровня которой я выбирал из множества библиотек: miniaudio, soloud, PortAudio, OpenAL и т.д, среди которых победил SDL mixer. Часть из них очень функциональные, но звук связан с цифровой обработкой сигналов (DSP), для вспоминания которой я хочу начать с нуля, обойдясь лишь аудиобуфером, а недостающее реализовать самостоятельно. Всё-таки сложное-готовое хотя и ускоряет разработку, но для понимания подкапотной работы вещей оно бесполезно. Скорее всего, всю весну я буду изучать DSP, ибо оно нужно в электронике, а визуализировать можно любые сигналы, не только звук.
У SDL есть коллбэк, который даёт доступ к буферу. Отсюда проблема - переброс аудиоданных между SDL-потоком и потоком движка с минимумом блокировок, размер данных требует степени двойки для FFT. Версия с одним буфером потерпела крах, я попробовал набросать примитивную двойную буферизацию, что хотя бы убрало мигание визуализаций.
Далее данные в окно Ханна и следом FFT (быстрое преобразование Фурье), которое у D есть из коробки, для выделения частотных компонент. Из комплексных чисел на выходе корнем из суммы квадратов действительных и мнимых частей можно получить магнитуду и перевести её в децибелы через десятичный логарифм, как и вычислить частоту. На этом уже можно сделать примитивный эквалайзер, объединив результат по каналам. Но, вероятно, из-за рассинхронизации записи-чтения между движком и SDL он пока не всегда попадает в такт и работает немного коряво.
Тем не менее, я быстро набросал простенькую демку, нагенерив роз, раз уж сегодня 8 Марта, хотя не все из них получились верной формы. Если вы вспомните таблицу первых коэффициентов роз https://ru.wikipedia.org/wiki/%D0%A0%D0%BE%D0%B7%D0%B0_(%D0%BF%D0%BB%D0%BE%D1%81%D0%BA%D0%B0%D1%8F_%D0%BA%D1%80%D0%B8%D0%B2%D0%B0%D1%8F), то в диагоналях там есть невалидные комбинации d и n, как и не везде цветы. Но пока розогенератора у меня нет, отчего наблюдаем геометрические ошибки природы. Ещё наблюдаются небольшие рандомные графические артефакты по экрану, вероятно, отголоски недавнего переезда на новую версию SDL.
Музыка "Of Far Different Nature - Cruiser": https://opengameart.org/content/huge-loop-box-2-heavy-bass-music-for-action-racing-fighting-rpg-adventure-and-cutscenes
В движке появляется звук и теперь в блоге начинает появляться уже видео. Пока я экспериментирую с разными форматами и размером файлов, ибо некоторые соцсети по-разному работают с видео: в одной хорошо, а в другой нужно скачивать для просмотра. От этого размер файла не может быть большим, но при уменьшении размеров страдает качество, что дилемма. Также видео может не сразу загружаться к посту, требуя времени, как и повторов при ошибках загрузки. Тестируем-наблюдаем.
Всех ещё раз с Праздником!
#graphics_engine #dlang #dm #программирование
Начались эксперименты с аудиосистемой, для первого уровня которой я выбирал из множества библиотек: miniaudio, soloud, PortAudio, OpenAL и т.д, среди которых победил SDL mixer. Часть из них очень функциональные, но звук связан с цифровой обработкой сигналов (DSP), для вспоминания которой я хочу начать с нуля, обойдясь лишь аудиобуфером, а недостающее реализовать самостоятельно. Всё-таки сложное-готовое хотя и ускоряет разработку, но для понимания подкапотной работы вещей оно бесполезно. Скорее всего, всю весну я буду изучать DSP, ибо оно нужно в электронике, а визуализировать можно любые сигналы, не только звук.
У SDL есть коллбэк, который даёт доступ к буферу. Отсюда проблема - переброс аудиоданных между SDL-потоком и потоком движка с минимумом блокировок, размер данных требует степени двойки для FFT. Версия с одним буфером потерпела крах, я попробовал набросать примитивную двойную буферизацию, что хотя бы убрало мигание визуализаций.
Далее данные в окно Ханна и следом FFT (быстрое преобразование Фурье), которое у D есть из коробки, для выделения частотных компонент. Из комплексных чисел на выходе корнем из суммы квадратов действительных и мнимых частей можно получить магнитуду и перевести её в децибелы через десятичный логарифм, как и вычислить частоту. На этом уже можно сделать примитивный эквалайзер, объединив результат по каналам. Но, вероятно, из-за рассинхронизации записи-чтения между движком и SDL он пока не всегда попадает в такт и работает немного коряво.
Тем не менее, я быстро набросал простенькую демку, нагенерив роз, раз уж сегодня 8 Марта, хотя не все из них получились верной формы. Если вы вспомните таблицу первых коэффициентов роз https://ru.wikipedia.org/wiki/%D0%A0%D0%BE%D0%B7%D0%B0_(%D0%BF%D0%BB%D0%BE%D1%81%D0%BA%D0%B0%D1%8F_%D0%BA%D1%80%D0%B8%D0%B2%D0%B0%D1%8F), то в диагоналях там есть невалидные комбинации d и n, как и не везде цветы. Но пока розогенератора у меня нет, отчего наблюдаем геометрические ошибки природы. Ещё наблюдаются небольшие рандомные графические артефакты по экрану, вероятно, отголоски недавнего переезда на новую версию SDL.
Музыка "Of Far Different Nature - Cruiser": https://opengameart.org/content/huge-loop-box-2-heavy-bass-music-for-action-racing-fighting-rpg-adventure-and-cutscenes
В движке появляется звук и теперь в блоге начинает появляться уже видео. Пока я экспериментирую с разными форматами и размером файлов, ибо некоторые соцсети по-разному работают с видео: в одной хорошо, а в другой нужно скачивать для просмотра. От этого размер файла не может быть большим, но при уменьшении размеров страдает качество, что дилемма. Также видео может не сразу загружаться к посту, требуя времени, как и повторов при ошибках загрузки. Тестируем-наблюдаем.
Всех ещё раз с Праздником!
#graphics_engine #dlang #dm #программирование
Космическая станция Аналитики 🌌
#graphics_engine #dlang #dm #программирование
Продолжаю эксперименты с DSP в графическом движке. Обмен между потоками теперь идёт через более эффективную структуру данных - кольцевой буфер. Однако из-за фиксированного размера в нём легко потерять сами данные из-за рассинхронизации скорости читателя и писателя, да и получить коварные баги перекрытия индексов. После множества улучшений и исправлений пришло время повысить сложность задачи.
Теперь спрайтами должны управлять не случайные сигналы, как на предыдущем видео, а магнитуда выбранного инструмента. Это задача разделения звука (source separation), имеющая проблемы из-за пересечения частот инструментов и погрешностей самой обработки сигнала. Например, могут быть искажения из-за эффекта утечки спектра, когда частота расплывается по соседним, на что влияет размер окна fft, оконная функция и т.д. и т.п. множество факторов.
После беглого поиска мне приглянулась композиция от cynicmusic - November Snow (https://opengameart.org/content/november-snow) из-за чётко звучащего фортепиано (назовём его условно так) в начале, хотя дальше там частоты начинают перекрываться. Я изучил график спектра в Audacity и обнаружил пики на частотах ≈800Гц.
Там располагается несколько нот официального фортепиано, пробовал сужать и расширять диапазон фильтрации, оценивая нужный мне уровень магнитуды, но, увы, было много ложных срабатываний. Тогда я решил поискать гармоники - кратные частоты основному тону. Если предположить, что основной тон мог быть в районе 800Гц, то следующая гармоника должна быть где-то в 2*800=1600Гц. И в диапазоне 1540-1630Гц там действительно есть более узкий и чёткий пик, оно кое-как, но заработало. Хотя, быть может и банальное совпадение.
Для придания эксперименту какой-то визуальной интересности я нагенерил ворох снежинок, раз уж композиция снежная. Часть снежинок - звёздчатые многоугольники, каждая вторая снежинка - фрактал Коха. Снежинок Коха много разных, но именно симметричная получается с углом поворота черепашьей графики в 60° (больше-меньше нарушает симметрию), аксиома F++F++F, правило F=F-F++F-F в системе Линденмайера.
В процессе построения снежинок обнаружился интересный хак: если сделать их размер не квадратным, а немного асимметричным, то при повороте с изменяемым углом рендерер создаёт более хаотичное и интересное движение, нежели простой поворот в случае квадратной геометрии. Забавно...
#graphics_engine #dlang #dm #программирование
Теперь спрайтами должны управлять не случайные сигналы, как на предыдущем видео, а магнитуда выбранного инструмента. Это задача разделения звука (source separation), имеющая проблемы из-за пересечения частот инструментов и погрешностей самой обработки сигнала. Например, могут быть искажения из-за эффекта утечки спектра, когда частота расплывается по соседним, на что влияет размер окна fft, оконная функция и т.д. и т.п. множество факторов.
После беглого поиска мне приглянулась композиция от cynicmusic - November Snow (https://opengameart.org/content/november-snow) из-за чётко звучащего фортепиано (назовём его условно так) в начале, хотя дальше там частоты начинают перекрываться. Я изучил график спектра в Audacity и обнаружил пики на частотах ≈800Гц.
Там располагается несколько нот официального фортепиано, пробовал сужать и расширять диапазон фильтрации, оценивая нужный мне уровень магнитуды, но, увы, было много ложных срабатываний. Тогда я решил поискать гармоники - кратные частоты основному тону. Если предположить, что основной тон мог быть в районе 800Гц, то следующая гармоника должна быть где-то в 2*800=1600Гц. И в диапазоне 1540-1630Гц там действительно есть более узкий и чёткий пик, оно кое-как, но заработало. Хотя, быть может и банальное совпадение.
Для придания эксперименту какой-то визуальной интересности я нагенерил ворох снежинок, раз уж композиция снежная. Часть снежинок - звёздчатые многоугольники, каждая вторая снежинка - фрактал Коха. Снежинок Коха много разных, но именно симметричная получается с углом поворота черепашьей графики в 60° (больше-меньше нарушает симметрию), аксиома F++F++F, правило F=F-F++F-F в системе Линденмайера.
В процессе построения снежинок обнаружился интересный хак: если сделать их размер не квадратным, а немного асимметричным, то при повороте с изменяемым углом рендерер создаёт более хаотичное и интересное движение, нежели простой поворот в случае квадратной геометрии. Забавно...
#graphics_engine #dlang #dm #программирование
Космическая станция Аналитики 🌌
#graphics_engine #dlang #dm #программирование
Продолжаю звукоэксперименты в графическом движке. Проблемы разделения частот инструментов заставили вспомнить инженерный приём, онумерованный в советском ТРИЗ как 13-ый - принцип "наоборот". Мы можем не разбирать звук на инструменты, а создавать его из них, где все частоты будут известны.
Здесь я призадумался, нужен ли мне синтез звука, одним своим аудиоконцом упирающийся в теорию музыки. Чистые сигналы звучат не особо эстетично, а их усложнение разбросает их по частотам, сводя изначальную идею на нет. Но это всё ещё DSP, что будет полезным в электронике, ибо встречается повсеместно. Да и в движке есть проблема: процедурные алгоритмы позволяют обойтись без сторонней графики, но движок остаётся привязанным к звуку, что досадно. Я решил поисследовать немного эту задачу.
После некоторой возни движок заверещал, рожая звук из синусоид с добавленными гармониками. Но для оценки этого писка нужно видеть сигнал. Виджеты в движке ещё слабы и я начал искать способы экспорта в WAV. SDL может из него загружать, а вот сохранения не видно. Но сам формат достаточно прост и экспорт был набросан руками. Audacity понял файл и показал сигналы.
Сразу выявилась причина противных щелчков, возникающих из-за резких колебаний амплитуды, отчего просто так напихать несколько подряд нот в аудиобуфер не выйдет. Сначала я пробовал фазовую синхронизацию: новый сигнал начинается там, где заканчивается старый, добавляя плавный подъём и затухание в начале и конце всего буфера. Это работало, но потом я узнал о ADSR-огибающей, более подходящей на эту роль т.к. фаза затухания предыдущего сигнала плавно переходит в фазу атаки\подъёма следующего.
Эксперименты с огибающими выявили большую проблему аудиоалгоритмов - стереобуферы с чередованием левого и правого каналов (L,R,L,R). Часть алгоритмов работает для монобуфера, часть для стерео и они легко перепутываются, нарушая временные метки сэмплов и прочие расчёты. Где-то используется нормализация сигнала, где-то время в относительных величинах, где-то в постоянных, уф.
В целях эксперимента была набросана простенькая пианинка, а следом к ней и примитивная drum-машина на FM-модуляции, которая выглядит очень перспективной. При переключении каналов SDL mixer тоже радует щелчками и в поисках решения я немного занизил амплитуду недоударных, чтобы погасить треск, отчего они не слишком выражены. Однако... в движке родился синтезатор, ура.
#graphics_engine #dlang #dm #программирование
Здесь я призадумался, нужен ли мне синтез звука, одним своим аудиоконцом упирающийся в теорию музыки. Чистые сигналы звучат не особо эстетично, а их усложнение разбросает их по частотам, сводя изначальную идею на нет. Но это всё ещё DSP, что будет полезным в электронике, ибо встречается повсеместно. Да и в движке есть проблема: процедурные алгоритмы позволяют обойтись без сторонней графики, но движок остаётся привязанным к звуку, что досадно. Я решил поисследовать немного эту задачу.
После некоторой возни движок заверещал, рожая звук из синусоид с добавленными гармониками. Но для оценки этого писка нужно видеть сигнал. Виджеты в движке ещё слабы и я начал искать способы экспорта в WAV. SDL может из него загружать, а вот сохранения не видно. Но сам формат достаточно прост и экспорт был набросан руками. Audacity понял файл и показал сигналы.
Сразу выявилась причина противных щелчков, возникающих из-за резких колебаний амплитуды, отчего просто так напихать несколько подряд нот в аудиобуфер не выйдет. Сначала я пробовал фазовую синхронизацию: новый сигнал начинается там, где заканчивается старый, добавляя плавный подъём и затухание в начале и конце всего буфера. Это работало, но потом я узнал о ADSR-огибающей, более подходящей на эту роль т.к. фаза затухания предыдущего сигнала плавно переходит в фазу атаки\подъёма следующего.
Эксперименты с огибающими выявили большую проблему аудиоалгоритмов - стереобуферы с чередованием левого и правого каналов (L,R,L,R). Часть алгоритмов работает для монобуфера, часть для стерео и они легко перепутываются, нарушая временные метки сэмплов и прочие расчёты. Где-то используется нормализация сигнала, где-то время в относительных величинах, где-то в постоянных, уф.
В целях эксперимента была набросана простенькая пианинка, а следом к ней и примитивная drum-машина на FM-модуляции, которая выглядит очень перспективной. При переключении каналов SDL mixer тоже радует щелчками и в поисках решения я немного занизил амплитуду недоударных, чтобы погасить треск, отчего они не слишком выражены. Однако... в движке родился синтезатор, ура.
#graphics_engine #dlang #dm #программирование
Космическая станция Аналитики 🌌
#graphics_engine #dlang #dm #программирование
Продолжаю звукоэксперименты в графическом движке, изучая FM-синтез. "Аналоговый динозавр", которого никто не смог вытеснить на задачах малого потребления ресурсов, простоты алгоритмов и управления ими. Это делает его очень популярным в электронике: детские игрушки, звуки будильников, сигнализаций, промоборудования и т.д. и т.п., отчего и мой интерес к нему.
В части движка меня также интересовала процедурная звукогенерация: например, изменение частоты звука двигателя космокорабля от степени его нагрева, как и получение мелодий из каких-нибудь столкновений объектов. Последнее немного сложнее, ибо уходит в теорию музыки с её консонансами и диссонансами, гаммами, ладами, гармониями и вот этим всем.
Теоретически, консонанс условно легко запрограммировать как известное соотношение частот несущей и модулятора, например, 2:1 - октава, 3:4 - квинта и т.д. Вообще я сразу заметил, что если модулирующую получать умножением рандомного числа на несущую, то звуки более интересные, нежели при ручном подборе значений.
Однако для мелодий этого мало и нужно погружаться в теорию музыки поглубже, как и затачивать модулятор под конкретный жанр, привлекая к этому и звукоэффекты, коих много всяких разных. Но треть года уже пролетела, а вот дел осталось ещё много, что заставляет оставить пока синтезатор на уровне симпатичного верещания. Тем более, что будущие демки могут очень сильно поменять его дизайн.
Хотя мои музыконавыки околонулевые, я набросал простенькую демку, где все звуки генерируются двухоператорным (у промсинтезаторов десятки операторов) FM-синтезом. Звучит оно явно получше чем "у-ру-ру" из предыдущего видео. Эффект наведения мышки не сработал на второй клавише из-за зажатой кнопки, пока оно немного коряво работает.
При смешивании каналов в SDL mixer сразу же столкнулся с лютыми шумами, намекающими на клиппинг - превышение суммарной амплитуды при сложении каналов, что решилось уменьшением их амплитуд. Технически, от SDL mixer можно вообще избавиться, ибо доступ к аудиобуферу есть в самом SDL, но тогда нужна библиотека для загрузки разных форматов, возня с буферами и т.п., оставлю пока эту либу.
Я безмерно рад, что для аудиосистемы вышло обойтись самой простой библиотекой без завязки движка на более сложные, хотя и функциональные, но с проблемами обновления и пересборки в случае каких-либо проблем в т.ч. отсутствия на целевом железе.
Но теперь появилась другая проблема - слышать, конечно, хорошо, но вот видеть - тоже нужно. А движок ничего не показывает. Начинаю ломать голову над видеосистемой.
#graphics_engine #dlang #dm #программирование
В части движка меня также интересовала процедурная звукогенерация: например, изменение частоты звука двигателя космокорабля от степени его нагрева, как и получение мелодий из каких-нибудь столкновений объектов. Последнее немного сложнее, ибо уходит в теорию музыки с её консонансами и диссонансами, гаммами, ладами, гармониями и вот этим всем.
Теоретически, консонанс условно легко запрограммировать как известное соотношение частот несущей и модулятора, например, 2:1 - октава, 3:4 - квинта и т.д. Вообще я сразу заметил, что если модулирующую получать умножением рандомного числа на несущую, то звуки более интересные, нежели при ручном подборе значений.
Однако для мелодий этого мало и нужно погружаться в теорию музыки поглубже, как и затачивать модулятор под конкретный жанр, привлекая к этому и звукоэффекты, коих много всяких разных. Но треть года уже пролетела, а вот дел осталось ещё много, что заставляет оставить пока синтезатор на уровне симпатичного верещания. Тем более, что будущие демки могут очень сильно поменять его дизайн.
Хотя мои музыконавыки околонулевые, я набросал простенькую демку, где все звуки генерируются двухоператорным (у промсинтезаторов десятки операторов) FM-синтезом. Звучит оно явно получше чем "у-ру-ру" из предыдущего видео. Эффект наведения мышки не сработал на второй клавише из-за зажатой кнопки, пока оно немного коряво работает.
При смешивании каналов в SDL mixer сразу же столкнулся с лютыми шумами, намекающими на клиппинг - превышение суммарной амплитуды при сложении каналов, что решилось уменьшением их амплитуд. Технически, от SDL mixer можно вообще избавиться, ибо доступ к аудиобуферу есть в самом SDL, но тогда нужна библиотека для загрузки разных форматов, возня с буферами и т.п., оставлю пока эту либу.
Я безмерно рад, что для аудиосистемы вышло обойтись самой простой библиотекой без завязки движка на более сложные, хотя и функциональные, но с проблемами обновления и пересборки в случае каких-либо проблем в т.ч. отсутствия на целевом железе.
Но теперь появилась другая проблема - слышать, конечно, хорошо, но вот видеть - тоже нужно. А движок ничего не показывает. Начинаю ломать голову над видеосистемой.
#graphics_engine #dlang #dm #программирование
Космическая станция Аналитики 🌌
#graphics_engine #dlang #dm #программирование
Первый тестовый запуск видеосистемы в графическом движке. Ранее для медиаприложений я использовал GStreamer, однако системный стек движка легко адаптируется к осям и железу, что может потребовать пересборки всех библиотек-зависимостей. GStreamer в этом далеко не подарок, а недавнее добавление плагинов на Rust делает его мультиязычным проектом, усложняя сборку. Если Rust продолжит распространяться по фреймворку, то сборка может стать ещё более проблемной, что риск.
Вторая проблема в высокоуровневости GStreamer, что скрывает много деталей по устройству тамошних пайпланов, а мне хотелось бы потрогать их более тонкие нюансы. Я решил повысить уровень сложности, пуститься во все тяжкие и собрать пайплайн самостоятельно с помощью более низкоуровневой либы - FFmpeg.
Библиотека тоже не подарок, в мажорных версиях часто ломается и многие туторы-примеры не работают, как и путают нейросети. Проект большой, под капотом за миллион кодострок, но они любезно распространяют скомпиленные готовые либы (не то, что некоторые). Ну разве что, например, в более мягкой LGPL-сборке есть не все фильтры.
Пайплайн выбрал трёхзвенный - по потоку на демультиплексор, видео и аудиодекодер с очередями на кольцевых буферах. Демультиплексор читает видео и аудиофреймы, разбрасывая их в очереди декодеров. При этом если они достаточно большие, то он может закончить работу раньше всех. В ином случае ему нужно подтормаживать, дожидаясь обработки очередей. В свою очередь, декодеры подтормаживают, если очереди пусты, а также если SDL не успевает за ними. Да, тут важную роль играет система обратных связей и она достаточно хрупка. При этом если очереди будут маленькие, то будут лаги, а если очень большими, то начнёт расти потребление памяти, что можно принять за утечку.
Видео рисуется в SDL-текстуру с форматом YUV, при этом фильтры FFMPEG могут его ломать. В SDL даже предусмотрели отдельное апи SDL_UpdateYUVTexture. C аудио немного сложнее т.к. теперь добавляется не только упакованный формат стереобуфера (LRLRLR), как это было в прошлых экспериментах, а и планарный (два буфера LLL,RRR). При переконвертировании в другой формат устройства SDL немного усложняется подсчёт время сэмплов, что нужно для синхронизации видео по аудио. Так, я его более-менее вытыкал лишь экспериментально...
Кроме того, ауидоустройство буферизует данные, а также запрашивает их в определённом размере, что ещё больше осложняет синхронизацию. При этом видео может быть впереди и позади, а аудио может вообще не быть и т.д. и т.п. классические медиапроблемы.
Для теста использовал опенсурсные мультики Blender Open Movie (https://commons.wikimedia.org/wiki/Category:Blender_movies), в частности - WING IT! (https://commons.wikimedia.org/wiki/File:WING_IT!_-_Blender_Open_Movie-full_movie.webm). Также потестил фильтр colorbalance c фильтром format, ибо YUV цветофильтр явно портит.
Наблюдается небольшой треск аудио и некоторая рассинхронизация с видео, но в целом я доволен прототипом - что-то да показывает. Оставлять его или же добавлять ещё к нему и GStreamer... в т.ч. банально чтобы не забыть работу с ним... тут теперь нужно подумать.
#graphics_engine #dlang #dm #программирование
Вторая проблема в высокоуровневости GStreamer, что скрывает много деталей по устройству тамошних пайпланов, а мне хотелось бы потрогать их более тонкие нюансы. Я решил повысить уровень сложности, пуститься во все тяжкие и собрать пайплайн самостоятельно с помощью более низкоуровневой либы - FFmpeg.
Библиотека тоже не подарок, в мажорных версиях часто ломается и многие туторы-примеры не работают, как и путают нейросети. Проект большой, под капотом за миллион кодострок, но они любезно распространяют скомпиленные готовые либы (не то, что некоторые). Ну разве что, например, в более мягкой LGPL-сборке есть не все фильтры.
Пайплайн выбрал трёхзвенный - по потоку на демультиплексор, видео и аудиодекодер с очередями на кольцевых буферах. Демультиплексор читает видео и аудиофреймы, разбрасывая их в очереди декодеров. При этом если они достаточно большие, то он может закончить работу раньше всех. В ином случае ему нужно подтормаживать, дожидаясь обработки очередей. В свою очередь, декодеры подтормаживают, если очереди пусты, а также если SDL не успевает за ними. Да, тут важную роль играет система обратных связей и она достаточно хрупка. При этом если очереди будут маленькие, то будут лаги, а если очень большими, то начнёт расти потребление памяти, что можно принять за утечку.
Видео рисуется в SDL-текстуру с форматом YUV, при этом фильтры FFMPEG могут его ломать. В SDL даже предусмотрели отдельное апи SDL_UpdateYUVTexture. C аудио немного сложнее т.к. теперь добавляется не только упакованный формат стереобуфера (LRLRLR), как это было в прошлых экспериментах, а и планарный (два буфера LLL,RRR). При переконвертировании в другой формат устройства SDL немного усложняется подсчёт время сэмплов, что нужно для синхронизации видео по аудио. Так, я его более-менее вытыкал лишь экспериментально...
Кроме того, ауидоустройство буферизует данные, а также запрашивает их в определённом размере, что ещё больше осложняет синхронизацию. При этом видео может быть впереди и позади, а аудио может вообще не быть и т.д. и т.п. классические медиапроблемы.
Для теста использовал опенсурсные мультики Blender Open Movie (https://commons.wikimedia.org/wiki/Category:Blender_movies), в частности - WING IT! (https://commons.wikimedia.org/wiki/File:WING_IT!_-_Blender_Open_Movie-full_movie.webm). Также потестил фильтр colorbalance c фильтром format, ибо YUV цветофильтр явно портит.
Наблюдается небольшой треск аудио и некоторая рассинхронизация с видео, но в целом я доволен прототипом - что-то да показывает. Оставлять его или же добавлять ещё к нему и GStreamer... в т.ч. банально чтобы не забыть работу с ним... тут теперь нужно подумать.
#graphics_engine #dlang #dm #программирование
commons.wikimedia.org
File:WING IT! - Blender Open Movie-full movie.webm - Wikimedia Commons
Космическая станция Аналитики 🌌
#graphics_engine #dlang #dm #программирование
Подходит к концу переменчивая капризность весны, а значит пора подвести итоги зимне-весеннего сезона. Значительное достижение - медиасистема в графическом движке, которую теперь можно неспешно совершенствовать, не опасаясь промахнуться со сроками. Этого я сильно опасался, ибо трудоёмкость высокая, а потери времени непредсказуемы.
Станция даже поиграла с нейросетевой музыкой, способной повысить контентонезависимость блога. Закрыть сезон также захотелось музыкокомпозицией, но уже с Riffusion. На этот раз я решил нароллить симфоник-метал.
Для эксперимента насочинял (сам) динамичненький текст, запустив песенку на движке через SDL Mixer (mp3 есть в аудио ВК и продублирован в TG). Хотелось заложить какую-то игру слов. Например, изначально было "Страх рвётся изнутри", но учитывая способности инопланетян встраиваться в других, заменилось на "Боль".
Фоновая картинка сгенерена через DeepAI, где-то с раза пятидесятого, но генерит их довольно быстро. Эквалайзер движка работает не очень стабильно, бедняга, не успевает за таким (хотя из-за техограничений он пока не успевает ни за каким).
В Riffusion менее жёсткие лимиты, а в нужный жанр он попал сразу, что плюс. Минус - тамошний MP3 c битрейтом 128kbps. У того же симфо-метала широкий динамический диапазон, такого качества недостаточно. На русскоязычном тексте модель спотыкается чаще, чем в Suno. Забавно, что если ввести исполнителя, а-ля давай как Тарья, то сервисы ругаются, Riffusion меняет её имя на 'Finnish symphonic metal pioneer', подставляя в пром(п)т.
Вообще, здесь усматривается поляризация: мало генераций, терпимое качество в Suno и большое количество, плохое качество в Riffusion. Хм... значит экономическая модель обоих уязвима к конкуренту с посерединным вариантом и монетизацией профессионалов, а не всех подряд. Такой конкурент может появиться позже, либо он уже есть. Поэтому я займу пока выжидательную стратегию. Кто выживет, с тем и будем работать, а выживать, как известно, склонны не все. Периодически, раз в несколько месяцев, можно баловаться музыкой, оценивая жизнедеятельность сервисов.
Летом станция займётся техническими долгами: улучшение текстовых контролов, иконки, оптимизации и т.п., параллельно изучая пути снижения трудоёмкости движка через создание инструментов в нём. Часть времени нужно вкинуть в развитие других пет-проектов, что пострадали весной. В общем, штатно продолжаем полёт.
#graphics_engine #dlang #dm #программирование
Станция даже поиграла с нейросетевой музыкой, способной повысить контентонезависимость блога. Закрыть сезон также захотелось музыкокомпозицией, но уже с Riffusion. На этот раз я решил нароллить симфоник-метал.
Для эксперимента насочинял (сам) динамичненький текст, запустив песенку на движке через SDL Mixer (mp3 есть в аудио ВК и продублирован в TG). Хотелось заложить какую-то игру слов. Например, изначально было "Страх рвётся изнутри", но учитывая способности инопланетян встраиваться в других, заменилось на "Боль".
Фоновая картинка сгенерена через DeepAI, где-то с раза пятидесятого, но генерит их довольно быстро. Эквалайзер движка работает не очень стабильно, бедняга, не успевает за таким (хотя из-за техограничений он пока не успевает ни за каким).
В Riffusion менее жёсткие лимиты, а в нужный жанр он попал сразу, что плюс. Минус - тамошний MP3 c битрейтом 128kbps. У того же симфо-метала широкий динамический диапазон, такого качества недостаточно. На русскоязычном тексте модель спотыкается чаще, чем в Suno. Забавно, что если ввести исполнителя, а-ля давай как Тарья, то сервисы ругаются, Riffusion меняет её имя на 'Finnish symphonic metal pioneer', подставляя в пром(п)т.
Вообще, здесь усматривается поляризация: мало генераций, терпимое качество в Suno и большое количество, плохое качество в Riffusion. Хм... значит экономическая модель обоих уязвима к конкуренту с посерединным вариантом и монетизацией профессионалов, а не всех подряд. Такой конкурент может появиться позже, либо он уже есть. Поэтому я займу пока выжидательную стратегию. Кто выживет, с тем и будем работать, а выживать, как известно, склонны не все. Периодически, раз в несколько месяцев, можно баловаться музыкой, оценивая жизнедеятельность сервисов.
Летом станция займётся техническими долгами: улучшение текстовых контролов, иконки, оптимизации и т.п., параллельно изучая пути снижения трудоёмкости движка через создание инструментов в нём. Часть времени нужно вкинуть в развитие других пет-проектов, что пострадали весной. В общем, штатно продолжаем полёт.
#graphics_engine #dlang #dm #программирование