Космическая станция Аналитики 🌌
26 subscribers
19 photos
6 videos
35 links
Мчимся из темноты к ярким звёздам! 🛸
Авторский IT DIY-техноблог: https://initkfs.github.io/pages/about.html

Прогресс станции:
1. Делаем обучающую платформу для исследований - графический движок.
2. (Ещё не разблокирован).
3. (Ещё не разблокирован).
Download Telegram
Космическая станция Аналитики 🌌
#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 #программирование
Космическая станция Аналитики 🌌
#graphics_engine #dlang #dm #программирование
Продолжаю звукоэксперименты в графическом движке. Проблемы разделения частот инструментов заставили вспомнить инженерный приём, онумерованный в советском ТРИЗ как 13-ый - принцип "наоборот". Мы можем не разбирать звук на инструменты, а создавать его из них, где все частоты будут известны.

Здесь я призадумался, нужен ли мне синтез звука, одним своим аудиоконцом упирающийся в теорию музыки. Чистые сигналы звучат не особо эстетично, а их усложнение разбросает их по частотам, сводя изначальную идею на нет. Но это всё ещё 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 #программирование
Космическая станция Аналитики 🌌
#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 #программирование
Очередной виток сделан в межзвёздном пространстве, за поздравления с которым станция благодарит всех: большое космическое спасибо.

Пользуясь моментом, решил поиграться с AI-музыкой, самостоятельно сочинив спасибочный текст, затем пробуя озвучить и омелодить его нейросетью. Композитором вызвался TG-бот от Сбера GigaChat (есть веб и в вк). Вышел на него через коммент к обзору ботов habr.com/ru/articles/836856/

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

Заодно сгенерил картинку с котонавтом. Генерит картинки достаточно быстро, но получить кота с одним хвостом и в правильной комплектации лап вышло не сразу. Лапкодефекты можно объяснить тяжёлой космической работой - труд, при котором пальцы и не так способны вывернуться, да и не только они, уж поверьте.

Ещё раз всем спасибо!
Последний эксперимент зародил интерес: а возможно ли улучшить качество AI-музыки. Меня интересуют графические симуляторы, на которых можно решать разные полезные задачи. Полезность музыки найти тяжелее, но она может быть дополнением к графическим проектам, что интересно.

Музыку вызвался писать Suno AI Music (suno.com) на бесплатном тарифе.

Создавать по готовому тексту как-то уж слишком просто, поэтому я усложнил задачу (станция не занимается слишком простыми задачами), написав текст самостоятельно. Поэтических способностей у меня нет, но можно подойти методично: схема опорных рифм, а потом заполнить пространства между ними словами, решая эдакий кроссворд. Да и сервисы подбора рифм тоже могут помочь.

Под вечер было бы приятно услышать что-нибудь философское, расслабляюще-печальное, откуда и текст.

Неожиданно, нейросеть спотыкается на слове пещерный, видя в нём 'Ё'. Запишем-запомним. Режет по ушам "задачу", но другого как-то на ум не пришло.

Пока победили два варианта, вроде как звучит условно неплохо, хм...
Космическая станция Аналитики 🌌
#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 #программирование
Космическая станция Аналитики 🌌
Photo
Переделываю текстовые виджеты в движке, так что показывать нечего. Для моих задач хватило бы и устройства их на обычных массивах, но даже на условно средних объёмах текста можно заиметь сильную деградацию из-за постоянных сдвигов массы элементов вправо-влево. Хочется более продвинутых структур данных.

Простой текст решил оставить как есть, а вот для редактируемого заинтересовала Piece Table, в одном буфере которой хранится неизменяемый исходный текст, для вставляемого текста используется второй буфер, а сам текст собирается динамически из разных "кусочков". Есть опасения, что усложнение даст много тонких багов в поведении курсора, вьюпорта строк, выделения и т.д. и т.п., посмотрим. В текстовых редакторах популярен ещё Gap Buffer, как альтернативный вариант.

Параллельно экспериментирую со следующей AI-песенкой, пытаясь выбить из нейросетей Melodic Dubstep. К этому жанру меня привели запредельные айтишные нагрузки, что заставило искать мелодичное, успокаивающее, но не приевшееся. В начале я забрасываю черновик в AI-сервисы для оценки наложения вокала и музыки. Иногда в эти моменты генерится композиция, которую не могут превзойти последующие сотни генераций, что немного досадно...

Меня просили показывать промежуточные прототипы, вот один из них, сгенерил Riffusion. Suno что-то в MD очень так себе. В тексте есть промахи, но что есть, то есть. Сюжет навеян классическим инженерным принципом "наоборот": если на Земле внешняя космическая энергия обуславливает жизнь, то может быть наоборот - жизнь на планете может питаться внутренней. Возможно, это близко к концепту т.н. планет-сирот и похожих.

Картинку сгенерил DeepAI в режиме Alien Flora Generator