Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Новости
- by Alone Coder
- На работе у нас пертурбации, дома веселье, ещё я утонул в
- ремонте, поэтому я не попал ни на одно пати, а этот номер газеты
- задержался. Думаю, следующий задержится тоже, потому что дела
- ещё далеко не закончились. Зато в этом году, спустя уже не знаю
- сколько, удалось несколько раз выбраться на карьер, даже с
- Louis'ойи детишками - поочерёдно. Пешком. С коляской.
- ВиделАлексея Бугрова(который мне помогал с компьютером на
- презентацииFont Editor'ав1996году). Сейчас у него своя фирма
- по разработке железяк, по этому поводу и встречались. Выглядит
- очень усталым. Показывал ему демы, его заинтересовали
- мультиколоры и бордерныйKOT:).
- ЗвонилT(c)S'у.Он живёт всё там же, где мы тусовались в
- 2000-2002годах, и работает в своей фирме по ремонту сотовых
- телефонов. Очень занят. Хотел переманить его к нам на завод в
- качестве программиста микроконтроллеров, но не смог убедить. В
- Рязани очень трудно найти таких специалистов.
- CyberDaemonпериодически пишет, присылает новости из игрового
- мира (например, чтоSTEPделают новую игру во вселенной
- Звёздного Наследия,но не дляSpeccy...).
- Arwaldвсё ещё ведёт занятия по 2D анимации на киностудии, но я
- ни разу не смог его застать.
- Wandererнаписал (спустя22года!) новую игру -CELL 3326:
- https://zxwanderer.github.io/cell3326/Это квест на новом движке
- типаLaser Squad.Хоть я и не игрок, но я его прошёл полностью и
- подкорректировал пару переводов.Wanderer'ая тоже пытался
- переманить, но из меня плохой head hunter :)
- Hippimanвыпустил игруDizzy and the Mystical Letterна
- универсальномDizzyAGE-подобном движке, который он написал на
- языкеNedoLang.На настоящий момент игра существует на русском,
- английском и португальском языках. Неужели спектрумовские игры
- проDizzyне выходили так давно? Какие мы старые... Сейчас
- Hippimanвносит последние штрихи в движок и собирается релизить
- его отдельно. Уровни редактируются прямо в редактореDizzyAGE.
- Теперь каждый сможет сделать свою сериюDizzy:)
- Karboопять исчез, поэтому его трек не попал в игру. Насколько
- мне известно, он сейчас в деревне, а дел там летом много.
- John Silverзанимается написанием партитур для оркестра и
- пропадает в командировках. Последний раз уехал на целый месяц.
- Зато один композитор изШотландиинаписал, что решил освоитьPro
- Tracker 3,обещал поделиться результатами, когда получится :)
- DimkaMнаписал инструкцию, как работать с расширенной памятью в
- компилятореIAR(нажмите кнопку"2"). Пока таких возможностей
- нет вNedoLang(Hippimanв своём движкеDizzyразмещал
- процедуры и данные по памяти вручную). Может, со временем
- получится придумать круче? :)
- В эмулятореUnreal Speccy Portableпоявилась поддержка
- расширенных экрановATM2(Fyrexхотел с удобством читатьACNews
- и добился этого :)). Но память пока работает только в верхнем
- окне, причём, кажется, порты#7ffdи#fff7устанавливают один и
- тот же регистр.
- Utz/irrlicht projectорганизует конкурс графики под64цвета на
- точку (как вEye Ache 2) наInternational Symposium on Bits and
- Beverages.
- Картинки надо рисовать в тулзеStellarPaint:
- http://irrlichtproject.de/stellarpaint/
- Или просто сделатьPNGкартинку64x48с этой палитрой:
- http://
- irrlichtproject.de/stellarpaint/stellarmode_gimp_tools.zip
- И прислать по адресу1bitforum@posteo.netдо18 сентября 2018
- года. Не больше двух работ от автора, никаких конверсий или
- ограничений на свободное распространение!
- ЕщёUtzнаписал по поводу своего языка программирования для
- музыки (разговор завязался благодаря проекту языкаListh,
- опубликованному в прошлом номере):
- Utz>
- Сейчас я переделываюMDAL(https://utz82.github.io/MDAL/).
- На сайте сейчас не совсем понятно, но в общем там 3 вещи:
- -MDMOD- абстрактный универсальный язык разметки;
- -MDCONF- стандарт передачи данных, основанный на XML, который
- описывает, как из универсальногоMDMODна входе получить
- специфический для данного звукового устройства ассемблерный
- результат;
- -libmdal- библиотека, реализующаяMDMODиMDCONFдля
- использования (в будущем) в качестве бэк-энда для PC-шных
- трекеров.
- Ещё имеетсяbintracker(https://utz82.github.io/bintracker/) -
- собственно, тестовая реализация.
- В последнее время я написал проект спецификации новой версии
- MDCONF(поскольку первая версия оказалась слишком ограниченной
- по возможностям).
- Теперь я переписываю реализациюlibmdalв соответствии с этой
- новой спецификацией (с нуля, так что я могу написать код
- получше, благодаря всему, чему я научился за последний год).
- Alone>
- У меня была идея по поводу рекурсивного музыкального языка (и
- трекерного интерфейса), с которым можно реализовать ранее
- недостижимые музыкальные фишки.
- Допустим, у нас AY музон, состоящий из паттернов, а те состоят
- из треков на каждый канал. Каждый трек может содержать множество
- инструментов (звуковых эффектов), которые играют одновременно, а
- слышно только самый громкий на текущий момент. Нота в треке с
- номером инструментаNможет означать одно из двух:
- -перезапускзвукового эффектаNв этом канале(стаккато);
- -изменение частоты тонав звуковом эффектеNв этом канале
- (легато).
- По умолчанию используетсястаккато,алегатонадо чем-то
- помечать в нотном тексте. Или наоборот.
- Или, как вариант,легатобудет использоваться, если не указан
- номер инструмента - будет использоваться предыдущий указанный
- номер.
- В AY музыке инструменты состоят из "сэмпла" (список точных
- смещений тона, смещений громкости и масок тона-шума-огибающей на
- каждый фрейм времени) и "орнамента" (список смещений тона в
- полутонах на каждый фрейм времени).
- Если в "орнамент" добавить громкости, он будет выглядеть как
- трек в паттерне, с легато на всех нотах. Это первое
- использование рекурсии.
- Следующее использование - можно писать короткие музыкальные
- фразы (риффы) и использовать их как ноты.
- (Музыкальный модуль вызывает треки, треки вызывают риффы, риффы
- вызывают орнаменты - всё единым механизмом.
- Высота ноты уровнем выше задаёт транспозицию для используемого
- риффа.)
- Рифф содержит колонку"времени"для каждой ноты - сколько
- фреймов её играть. Можно указатьвремя=0,чтобы запустить две
- ноты одновременно: так можно, например, использовать рифф
- перкуссии одновременно с риффом фонового арпеджио.
- К сожалению, "сэмплы" уже играются другим механизмом, как
- звуковой эффект.
- Звуковые эффекты создаются нотами с флагом"стаккато"и
- удаляются, когда закончатся, или по ноте"R".
- Utz>
- Я тоже думал над таким рекурсивным подходом. Звуковой движок
- PhaseSqueek
- https://github.com/utz82/ZX-Spectrum-1-Bit-Routines/tree/master/
- phasesqueek
- частично использует эту идею. Формат данных"fx table"там почти
- такой же, как формат данных"pattern".Правда, там не совсем
- рекурсия, потому что вfx tableесть команда"position jump",
- которой нет в паттернах, но вfx tableтот же элемент данных,
- что и там. Если они будут обрабатываться одинаковой логикой, то
- получится настоящая рекурсия. Ордер тоже можно сделать так же.
- Вот примерMDMOD(старой версии) для движкаPhaseSqueek:
- https://github.com/utz82/MDAL/blob/master/examples/
- phasesqueek-demo.mdal
- Это текстовый формат, как и вVTили1tracker,но он хранит
- только текущие изменения, перед которыми пишетсяCOMMAND=(кроме
- ордера, где команда по умолчанию). Там есть одна фича, которой в
- новом стандарте не будет, потому что мне её сложно поддерживать:
- вMDALv1тип блока определяется автоматически, например, из
- такого текста вMDMOD:
- :SEQUENCE
- intro
- ...
- :intro
- FX=arp
- ...
- :arp
- CMD=...
- компиляторmdalможет определить, чтоintro- это паттерн, аarp
- - этоfx table.
- В новой версии форматаMDMODпользователь сам будет указывать
- тип блока и его уникальный номер. В новом формате ещё будут
- использоваться квадратные скобки для обрамления блоков.
- :BLOCKTYPE:$01[:name] {
- COMMAND=value, CMD2=othervalue...
- }
- Ордер в новом стандарте тоже будет более многословный, но ради
- гибкости и типобезопасности можно потерпеть.
- Делать форматMDMODпростым - не главная задача. Главное, чтобы
- его можно было редактировать вручную (но не в том смысле, чтобы
- печатать директивыdb) и при этом нормально обрабатывать
- трекером или другим GUI.
- Что могу сразу сказать, новый стандартMDCONFуже будет
- полностью поддерживать вышеописанную рекурсивность.
- Имеется 4 базовых типа данных:command, ifield, iblockиigroup,
- гдеcommandопределяет один входной параметр (такой как "note",
- "volume", "name"...). Типifieldрасширяет типcommand,тип
- iblockсодержит плавающее число полейifield,а типigroup
- содержит элементы типаifield, iblockили опять-такиigroup.
- Им соответствуют выходные типы данных, которые могут
- соответствовать или не соответствовать входной рекурсивной
- структуре.
- На самом деле входная структура в новом стандартеMDAL
- совершенно виртуальная, то есть не имеет отношения к выходной
- структуре. Это позволяет мудрить с входным форматом вплоть до
- поддержки совершенно разных видов ордера:
- - "таблица", как вBeep Tracker;
- - "список", как вBeepolaили в текущей версииbintracker;
- - "автоматический", то есть без ордера, как в1tracker.
- Причём независимо от звукового движка. С таким подходом
- низкоуровневую реализацию будет легко оптимизировать.
- Что я пока не продумал - как избежать выделения ордера в
- отдельный тип данных, а вывести его из обычных типов(i/o)block.
- Теоретически это должно работать, ведь мы можем определить
- структуру ордера по тем же правилам, как и паттерны или любые
- списки. Проблема в том, что это не будет работать, если выходной
- формат использует список элементов (например, список сэмплов,
- используемых в модуле, чтобы адресовать их по табличке или ещё
- как). Для этого есть отдельный тип выходных данных(otype)под
- названиемolist.Мне кажется, если я включу osequence внутрь
- oblock,то смогу избавиться отolist.Также есть специальный
- двоичный тип выходных данных -obitfield.Может быть, и
- получится вывести все выходные типы данных изobitfield,но это
- пока в голове не вырисовывается.
- Alone>
- А как ты отлаживаешь музыку в текстовом формате? Когда я писал
- трек для игры"Sewerage"на ассемблере, мне приходилось слушать
- его сначала после каждого изменения...
- Utz>
- Так же получается и с текущейlibmdal(разве что можно поставить
- блочные комментарии, чтобы пропускать куски ордера и т.п.).
- Новая версияlibmdal,скорее всего, будет работать в реальном
- времени, так что любое изменение вMDMODможет автоматически
- обновлять выходную структуру (а она может выдавать бинарник и
- ассемблер для всевозможных случаев - играть паттерн/текущую
- позицию/сонг сначала и т.д.). Кроме того, новаяlibmdalдолжна
- включать своеобразный скриптовый язык, для взаимодействия и
- реконфигурации на лету. Пока это не прорабатывал, но поглядываю
- на языкScheme.
- Alone>
- Я ещё раз подумал и придумал, как сделать рекурсивный формат без
- сэмплов :) Ну, кроме нескольких стандартных звуков в поле номера
- риффа (пример далее для AY).
- Это всё возможно потому, что конкретный орнамент обычно
- используется с одним конкретным инструментом.
- Иерархия такая:ордер->треки(можно несколько в одном канале,
- с независимыми громкостями) ->риффы->инструменты(орнаменты)
- ->сэмплы->стандартные звуки.Всё это будем называть риффами.
- - нота с риффом"T"включает тон и устанавливает частоту тона
- (относительно частоты текущего риффа) - в текущем подканале
- - нота с риффом"t"включает тон и устанавливает частоту тона
- (абсолютную) - в текущем подканале
- - нота с риффом"N"включает шум и устанавливает частоту шума -
- в текущем подканале
- - нота с риффом"n"устанавливает глобальное смещение шума
- - нота с риффом"E","C","1"перезапускает огибающую указанного
- типа - в текущем подканале
- - нота с пользовательским риффом (мне понравилась твоя идея с
- именованными треками) создаёт и запускает подканал с заданным
- риффом (удаляется, когда заканчивается).
- - нота с громкостью выключает огибающую и устанавливает
- громкость (относительно громкости текущего риффа) в текущем
- подканале.
- По умолчанию в текущем фрейме текущего подканала (связанного с
- текущим риффом) звук выключен, только громкость/огибающая
- остаётся с прошлого фрейма (в первом фрейме риффа - нулевая).
- Так мы можем накладыватьT+N+Eв любой комбинации, используя
- нулевую скорость.
- Подканалы рендерятся плейером в один канал в соответствии с их
- громкостями (слышно самый громкий на данный момент).
- Utz>
- С точки зрения формата данных самый важный выбор - использовать
- абстрактный базовый формат (соответствующий формату данных
- плейера, как в PC-шных трекерах) или же подход "прямо в памяти",
- как в большинстве нативных трекеров. Думаю, абстрактный для
- этого подойдёт больше, потому что он может решить тут многие
- проблемы. Так что надо исследовать этот вариант, если мы хотим
- нативный трекер. С другой стороны, с подходом "прямо в памяти"
- можно организовать очень интересные экспериментальные
- интерфейсы. Я к тому, что концепции трекера уже 30 лет, но за
- это время в трекерах появилось не так уж много новых идей. Было
- бы интересно порвать с традиционными концепциями и построить всё
- с новой точки зрения, без стереотипов. Как я понимаю,
- defMONнаC64до какой-то степени пошёл по этому пути, но пока
- точно оценить не могу. Стоит посмотреть.
- Например, можно поспорить с идеей, чтоTNEдолжны бать привязаны
- к ноте. Почему бы их не разделить? Конечно, это несколько дико в
- контексте AY, потому что делители разные. Но все делители шума и
- огибающей приемлемы (а иногда и юзабельны) в качестве делителей
- тона, так что можно и дать пользователю шанс прострелить себе
- ногу. Полагаю,nqможет с этим развлечься :D
- Или можно поставить три колонки делителей - тон, огибающая, шум,
- а плейер будет брать те, которые ему надо. С абстрактным базовым
- форматом этот выбор можно сделать во время компиляции, плейер
- будет не очень перегружен. То же можно сказать про
- многоканальные риффы и зацикленные сэмплы. Абстрактный базовый
- формат с агрессивной оптимизацией в компиляторе может решить
- многие такие проблемы. Вопрос только, юзабельный ли будет
- результат - в смысле объёма скомпилированных данных. Здравый
- смысл подсказывает, что объём получится большой даже с сильными
- оптимизациями, но это надо исследовать и попробовать, прежде чем
- отбросить :)
- Alone>
- Как описывать многоканальные риффы/сэмплы? Мы не можем иметь
- много стандартных звуков!
- Utz>
- По идее лучше вообще без стандартных звуков. Их можно
- реализовать в виде "патчей" или "макросов", загружаемых с диска.
- Многоканальные риффы в абстрактном базовом формате можно
- реализовать как "виртуальные" ордеры, которые разгребает
- компилятор.
- Alone>
- А как зацикливать сэмплы (особенно без шанса на бесконечное
- размножение их, если забудем их заглушить)?
- Utz>
- В общем-то, зацикленные сэмплы должны обрабатываться как циклы в
- ордере. ВMDAL v2было сделано две команды: команда типа
- "label",для указания именованных локаций внутри элемента
- (ордер/паттерн/сэмпл/что-то ещё) и команда типа"reference",
- которая ссылается наlabel(или другой элемент). Ордеры
- реализованы как обычные блоки, состоящие из таких команд ;)
- Alone>
- А как отображать и редактировать такую древовидную структуру?
- Utz>
- Главное, чтоMDAL(и в соответствии с нимbintracker) будет
- поддерживать такую структуру. Если он не сможет, то мне придётся
- повозиться, но сделать это. Чего мне пока не хватает - эмуляции
- AY вbintracker.Эмуляторы вbintrackerимеют специфические
- требования, а именно:1)они должны быть действительно
- свободными (то есть никакихGPL) и2)они должны поддерживать
- набор коллбэков в определённых точках, так что эмуляторы типа
- Game Music Emuне подходят. Пока я не прорабатывал программный
- интерфейс, так что это потом.
- В любом случае,MDALстарается поддерживать подход "не напрягать
- пользователя деталями реализации". Пользовательский интерфейс
- может использовать обычную символику, не показывая внутреннюю
- рекурсивность.
- В конце концов, ответ на этот вопрос опять сильно зависит от
- вида редактора. Если он кроссплатформенный, то я бы спрятал все
- детали, абстрагировал интерфейс от реализации, но сделал бы
- агрессивную оптимизацию в бэк-энде. Если же разговор про
- нативный редактор для ZX, то лучше наоборот показать так, как
- есть, чтобы пользователи могли оптимизировать модуль по размеру
- и т.п. и экспериментировать с рекурсивной структурой.
- С практической точки зрения на PC нет проблем, потому что экран
- достаточно большой, чтобы показать дерево прямо в виде вложенных
- элементов. Для нативного трекера можно использовать трюк,
- который уже есть вbintracker'е:нажатиеEnterна поле, которое
- указывает на какой-то элемент, переходит к этому элементу. Можно
- ещё отдельно вывести список текущих экземпляров этого элемента,
- но это не обязательно - в частности, обращение к несуществующему
- экземпляру может создать новый, пустой, а неиспользуемые
- экземпляры могут быть выброшены оптимизатором.
- Можно ещё подумать насчёт гибридного приложения, т.е. нативного
- трекера, использующего мощную периферию. Но здесь практическая
- проблема: на Западе такие устройства обычно базируются на
- ESXDOS,а на Востоке, как я понимаю, - наTR-DOS.ВESXDOSесть
- какая-то эмуляцияTR-DOS,но неполная. Например, я могу
- запуститьBeep Tracker,но не могуALASM.
- Я выпустил предварительные спецификацииMDAL v2:
- https://github.com/utz82/MDAL/wiki/
- MDCONF-Standard-Version-2-Specification-Draft
- https://github.com/utz82/MDAL/wiki/
- MDMOD-Standard-Version-2-Specification-Draft
- Полагаю, спецификацияMDMODуже достаточно проработана, аMDCONF
- будет ещё корректироваться.
- ...
- Свежие новости поlibmdal:дело идёт медленнее, чем
- планировалось. Явно недооценил сложность.
- Но библиотека уже умеет парсить текстMDMODво внутреннее
- представление модуля (в соответствии со спецификациейMDCONF) и
- выдавать правильный результат в форматеMDMODобратно. Далее
- надо будет сгенерировать ассемблерный текст. Пока не полностью
- вижу решение, но по идее нужен некий внутренний промежуточный
- формат, из которого можно быстро сгенерировать этот ассемблер и
- бинарник. Посмотрим, как получится.
- * * *
- По результатам этой беседы я решил довести языкListhдо
- запускаемого состояния (нажмите кнопку"4"). Может быть, со
- временем что-то из него и вырастет :)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement