Просмотр полной версии : Быстрый проигрыватель AY-музыки (980-1300t)
Как-то давно, еще делая демку на tum2009 я искали быстрый проигрыватель AY-музыки, но на все мои вопросы что хочу в районе 1500 тактов говорили что это нереально.
Тогда помню мне пришлось ручками переводить музыку из PT3 в PSC, ибо плейер первого никак не влезал под некоторые эффекты...
Теперь для меня это в прошлом!
Представляю вам универсальный проигрыватель и компилятор, который не зависит от типа используемого трекера, а компилирует дамп AY регистров, при этом размер компилированного модуля примерно в полтора раза больши, а порой даже меньше чем оригинала :)
кушает 964..1251t, в зависимости от музыки, при компиляции указывается точный диапазон тактов под конкретный музон (или фиксированное кол-во тактов)
Метод сжатия основан на том, что в паттернах каналов бывают повторяющиеся фрагменты.
Каналы паттерна рассматриваются отдельно друг от друга, также отдельно рассматриваются огибающая с формой, регистр управления и шума, в результате получаем список повторяющихся фрагментов для каждого канала и табличку (трек) для их проигрвания.
Сами данные регистров ay группируются в группы (например reg0, reg1, reg8) и составляется табличка вариантов принимаемых значений, из которой по индексу вытаскиваем значения.
Приведу тут наглядно примерный алгоритм (остальное - проигрыватель, компилер и пример в приложенном файле):
Рассмотрим какие регистры AY присутствуют в дампе
и какие биты в них задействованы:
;-----------------------------------------------------------
; Регистр / Номер / Обознач./ диапазон / битовая раскладка
;-----------------------------------------------------------
; RegA_lo 0 L 0-255 LLLLLLLL
; RegA_hi 1 H 0-15 0000HHHH
; RegA_Vol 8 V 0-15 000EVVVV
; RegB_lo 2 L 0-255 LLLLLLLL
; RegB_hi 3 H 0-15 0000HHHH
; RegB_Vol 9 V 0-15 000EVVVV
; RegC_lo 4 L 0-255 LLLLLLLL
; RegC_hi 5 H 0-15 0000HHHH
; RegC_Vol 10 V 0-15 000EVVVV
; Noise 6 N 0-31 000NNNNN
; Control 7 C 0-63 00cccCCC
; Period_lo 11 p 0-255 pppppppp
; Period_hi 12 P 0-255 PPPPPPPP
; Form 13 F 0-15 0000FFFF
Разделив на "каналы", данные можно представить следующим образом
; Channel_A
; LLLLLLLL 0000HHHH 000EVVVV (3 байта, reg 0,1,8)
; Channel_B
; LLLLLLLL 0000HHHH 000EVVVV (3 байта, reg 2,3,9)
; Channel_C
; LLLLLLLL 0000HHHH 000EVVVV (3 байта, reg 4,5,10)
; Channel_Env
; pppppppp PPPPPPPP 0000FFFF (3 байта, reg 11,12,13)
; Channel_Reg
; 000NNNNN 00cccCCC (2 байта reg 6,7)
Далее для каждого из "каналов" вычисляем кол-во принимаемых значений, и составляем таблицу возможных значений (256 знач макс)
если значений больше 256, то разделяем на более мелкие каналы
(например Channel_A оставляем только значения частоты, и например если кол-во вариантов Channel_Reg больше 256, то рассматриваем отдельно Channel_Noise, Channel_Control)
Далее разделяем каналы на паттерны, вычисляем совпадающие паттерны, и составяем треклист содержащий адреса паттернов в памяти
Если сразу не понятно - смотрим листинг кода проигрывателя.
Есть ограничения:
- длинна паттернов может быть хоть с постоянной, хоть с плавающей скоростью, но должно соблюдаться правило: длина паттерна в прерываниях должна быть одинаковой, либо половиной/четвертью и т.д.
Версия 1.3
Основное - добавил анализатор трека при загрузке (очистка неиспользуемых регистров, удаление громкости если установлена огибающая в регистрах громкости и т.п.) ну и по мелочи.
Ах да, зыбыл добавить... дамп музыки неполный, но почти полный...
в компилированном виде музыка занимала 10262, у нас при размере паттерна 8 получается 9972, так что думаю право на жизнь плэйер имеет)
unbeliever
15.11.2010, 23:05
Готовишься?
Эмм... к чему? ))
Это я для демки конечно делал) но вдруг кому еще пригодится)
Пока это бета версия, как доработаю полностью с сорцами выложу.
research
16.11.2010, 01:32
в моей молодости был урезанный плеер под саунд трекер, 700-800- тактов. огибающая была выпиленная, но умелый писатель вполне обходился 8) Перекомпилировать ничего ненадо было.
У кого увидели унесли и подправили, непомню, может у IMP, а может у MCHG
в моей молодости был урезанный плеер под саунд трекер, 700-800- тактов. огибающая была
Тогда и музыку писали на 5-8 скоростях, а треки занимали по 2 килобайта.
А где бит включения огибающей для нканала?
В регистре громкости для каждого канала.
D3-D0 амплитуда
D4 - 1-использование генератора
пакета.
D4 - 0-использование значения амплитуды
забылся немного :)
В регистре громкости для каждого канала.
Если заюзать под это дело биты 4-6 регистра R13, а бит 7 этого регистра заюзать под флаг перезагрузки огибающей, то пакеты каналов можно сжать в 2 байта, вместо 3.
Если заюзать под это дело биты 4-6 регистра R13, а бит 7 этого регистра заюзать под флаг перезагрузки огибающей, то пакеты каналов можно сжать в 2 байта, вместо 3.
Что сэкономит 256 байт текущей таблицы и увеличит кол-во тактов требуемых проигрывателю)
А тут цели ставились:
1) максимальная скорость проигрывания
2) приемлемый размер откомпилированного трека (в данном случае даже меньше оригинала)
пакеты канала тут занимают 1 байт (индекс по которому вытаскиваем из таблички tone_low, tone_hi, volume)
В данном случае (запускаем компилятор и смотрим варианты значений для каналов A,B,C) можно вместо отдельных таблиц для каждого канала объединить в одну таблицу - сэкономим 1280байт, но пока для меня это нетривиальная задача...
и увеличит кол-во тактов требуемых проигрывателю)
Насколько увеличит?
ну посмотри код исходника в приложении, сам прикинь... :)
ну посмотри код исходника в приложении, сам прикинь...
Нихрена не понял- ты хоть бы разделял навигацию по паттернам и воспроизведение оных...
Тут не как в стандартном трекере - есть паттерн, для него жестко заданы все каналы...
Тут идут паттерны на каждый канал отдельно
В листинге проигрывателя:
От позиции PLAY 82 строка до 273 строки - проигрывание паттернов для каждого из канналов: "A tone+Vol", "B tone+Vol", "C tone+Vo"', "Envelope+Form", "Noise+Control".
На примере канала А:
строки 86-89: берем адрес паттерна для канала А в HL, достаем индекс в регистр E, увеличиваем адрес паттерна (идем по паттерну), задаем в D адрес таблицы для регистров AY данного канала
строки 91-122: Задаем регистры AY, записываем в них данные из таблицы
(берем индекс, по индексу из таблицы вытаскиваем значения регистров AY)
строки 274-277 - проверяем достигли ли мы конца паттерна
строки 280-288 - при достижении конца паттерна, задаем новые адреса для каналов
Доступна новая версия:
- исправил глюки
- подцепил ayfly.dll (теперь можно открывать прямо сам модуль *.pt3 и другие, поддерживаемые ayfly.dll)
- сделал выбор адресов при компиляции
- добавил в архив исходники компилера (по просьбе newart)
Пока проект остается в стадии beta так как еще не до конца протестирован, а вот у тех кто пробовал/попробует юзать хотелось бы услышать багрепорты, и как какая мелодия получилась по размеру :)
Саш, сделай пожалуйста how-to для чайников "как пользоваться плеером-рекомпайлером".
Хочется попробовать компилированые мелодии, но в Аласм-е в эмуле. Как это осуществить?
Хочется попробовать компилированые мелодии, но в Аласм-е в эмуле. Как это осуществить?
1) Убрать все дерективы sjasm
DUP N ... EDUP - компилировать код внутри N раз
IF A ... ENDIF - условное компилирование (компилировать код внутри если выполнено условие А)
убрать sjasm`овское сохранение в *.trd
2) Как конвертить текст в ALASM: http://zx.pk.ru/showthread.php?t=12955
---------- Post added at 18:38 ---------- Previous post was at 17:10 ----------
Обновил архив.
Добавил примеров, описание для чайников тоже в архиве (правда английский вариант меньше и может там проблемы с грамматикой - фигово у меня с английским)
также там указаны ссылки на ветки обсуждений zx.pk.ru и wos
1) Убрать все дерективы sjasm
DUP N ... EDUP - компилировать код внутри N раз
IF A ... ENDIF - условное компилирование (компилировать код внутри если выполнено условие А)
убрать sjasm`овское сохранение в *.trd
2) Как конвертить текст в ALASM: http://zx.pk.ru/showthread.php?t=12955
Всё это сделано. Переводил Best View-ером в txt и грузил по IMPORT в Аласм. Аласм (4.44) отказывается компилить участки текста IF A.....ENDIF
Убери один из них.
Посмотри какое значение принимает
CHA_TYPE, CHB_TYPE, CHC_TYPE - и оставь те участки которые должны компилироватьася при указанных значениях...
т.е. если CHA_TYPE=1, то в коде
IF CHA_TYPE=0
INC D ;4 out_reg_8
LD A,8 ;7
OUT (C),A ;12
LD A,(DE) ;7
EXX ;4
OUT (C),A ;12
EXX ;4 //50
ENDIF
//---
IF CHA_TYPE=1
LD A,8 ;7 out_reg_8
OUT (C),A ;12
LD A,(HL) ;7
INC HL ;6
EXX ;4
OUT (C),A ;12
EXX ;4 //52
ENDIF
убираем все между IF CHA_TYPE=0 ... ENDIF и убираем сами скобки IF ENDIF
а старых аласмах можно заменить на IFDEF ENDIF
а в новом (от alone coder) есть просто IF
Откомпилил зацикленную мелодию (4 патерна + 1 пустой). С момента зацикливания проигрывается билиберда.
Мож я чего неправильно накомпилил?
В первом посту ay_zip_play такая же песня
В текущем плеере нет зацикливания.
Надо изменить код примерно так:
//--- переход на новый паттерн
LD A,PATTSIZE ;7
LD (HL),A ;7
LD HL,(ADR_PATT) ;16
LD DE,ADR_A ;10
DUP 10
LDI ;16*10=160
EDUP ;
LD (ADR_PATT),HL ;16
;RET ;10 //226 t=1200..1287
//--- LOOPER
LD HL,(ADR_PATT)
LD BC,END_TRACK
AND A
SBC HL,BC
RET NZ
LD HL,BEGIN_TRACK+10*XX
LD (ADR_PATT),HL
RET
Где 10*XX - в этой записи XX смещение в нотах * скорость
Спасибо помогло.
//--- LOOPER
LD HL,(ADR_PATT) - можно убрать.
Немного разобравшись, с помощью автора и GM BIT, добился чёткой работы плеера.
Заметил недостаток в том, что при выключении музыки огибающая не выключается и остаются неприятные звуки AY-ка. Немного изменил по метке INIT. Ещё хотелось бы таких нововведений в компилятор: автоопределение адреса, чтоб при ассемблировании не выдавалось ошибки компиляции в ПЗУ. Добавить автоопределение зацикливания мелодии с одновременной вставкой текста в сорцы плеера.
Ну и напоследок - изменил плеер так, что теперь он играет по тактам "ровно" т.е., при проигрывании мелодии занимает одно и то же число тактов. Правда теперь он занимает максимальное число тактов.
Зачем? А попробуйте сделать чё-нить на бордюре, вертикальную полоску например, с обычным плеером. Да так, чтоб она не дёргалась по сторонам.
http://psndcj.blogspot.com/2011/08/tbk-psg-squezer.html - Результаты очень даже приличные, psndcj - как всегда красавчик!!! Ждем пакер
Давно в массы пора, еще год назад с ним обсуждали...
Непотребный код и т.п. пофиг... главное алгоритм компиляции и поригрывателя объяснить - кому надо разберется)
Так, автора сюда :) почему кода не вижу? :) Сами код причешем, разберёмся.
psndcj : "В связи с идеологическим несоответствием меня и окружающих" - он покинул форум
На форуме он не появляется, очень жаль, толковый парень. Его опыт и ум мог бы много дать тем кто не сведует! Ну, что поделать будем хотя-бы его блог смотреть и учиться уму разуму!
Дайте кто нибудь его контакты (icq контакт etc)?
Обновил версию компилера и плеера (ver1.1).
Теперь в компилере можно выбирать фиксированный или нет по тактам плеер, а также нужно зацикливание или нет, также при компиляции и сохранении выводится кол-во тактов занимаемое плеером для компилируемой мелодии.
Плеер немного модифицирован для фиксированной/нет длительности по тактам и для зацикливания а также стал занимать немного меньше тактов(964..1251)
без смены паттерна = 964..997t, со сменой = 1172..1201t
со сменой и зацикливанием 1196..1251t
пока обе версии тут оставлю.
Спасибо GriV`у за участие в проекте :)
338 байт, музыко-зависимый (т.е. для каждого музона свой)
Можно к музыке добавить переменные в зависимости от которых компилиться плеер и переписать плеер сделав его универсальным, но добавив тактов, тока есть ли смысл?
Тут упор на скорость идет а не на размер, а по размеру в зависимости от мелодии этот плеер может очень сильно проиграть другим...
UPDATE:
Перезалил 1.1 build 2, т.к. нашел пару глюков в компилере и плеере.
Doctor Max
14.06.2012, 05:55
кхм... а не пожатый ли дамп регистров плеер играет?
Doctor Max, принцип же на первой странице описан :)
кхм... а не пожатый ли дамп регистров плеер играет?
дамп, пожатый и разделенный 'поканально' на 'паттерны' (см. первый пост)
А почему не поддержан drag'n'drop?
Попробовал паковать старые примивные музоны, пакует очень слабо, в среднем получается размер в два раза меньше PSG.
---------- Post added at 11:29 ---------- Previous post was at 11:27 ----------
Хм, ввел вместо 192 - 256 и получил вот что:
https://dl.dropbox.com/u/6439155/krasota.png
дык, упор на скорость плеера а не длины музона...
вместо 256 надо 128 вводить, все равно в районе 8-64 получается оптимальный размер.
Doctor Max
14.06.2012, 12:39
jerri, а я только последние страницы читаю :-) и понятно что поканально и попаттерно.
вместо 256 надо 128 вводить
Об этом юзер должен догадываться сам? :)
Об этом юзер должен догадываться сам? :)
help_rus.txt - все написано, может немного сумбурно, но про это там как раз есть :)
А почему не поддержан drag'n'drop?
а фиг знает, я окнами не пользуюсь...
Попробовал паковать старые примивные музоны, пакует очень слабо, в среднем получается размер в два раза меньше PSG.
залей чтоли 3-4 музона посмотреть почему так пакуются :)
А между тем обновил версию 1.2, с возможностью слияния таблиц
(+видео приложил как это примерно делается...)
скорость плеера упала на 12тактов :)
TmK, было бы хорошо иметь возможность внедрять свои call в плеер, в заданный промежуток тактов. Реально такое?
(надо для совмещения с digital)
---------- Post added at 19:20 ---------- Previous post was at 19:19 ----------
а фиг знает, я окнами не пользуюсь...
Какими окнами?
NovaStorm
20.06.2012, 15:24
>обновил версию 1.2
В новом архиве нет хелпов.
>>Copmile type
внезапно появилась Версия 1.3
Основное - добавил анализатор трека при загрузке (очистка неиспользуемых регистров, удаление громкости если установлена огибающая в регистрах громкости и т.п.) ну и по мелочи.
Есть ограничения:
- длинна паттернов может быть хоть с постоянной, хоть с плавающей скоростью, но должно соблюдаться правило: длина паттерна в прерываниях должна быть одинаковой, либо половиной/четвертью и т.д.
Не очень понял. Расшифруй пожалуйста.
Длина паттерна в прерываниях = длина паттерна * скорость паттерна (например 64*3). Или если плавающая скорость у паттерна то сумме скоростей каждой позиции.
так вот если у одного паттерна длина 192, у второго 185 у третьего 200 у четвертого 192, то не факт что нормально откомпилируется, т.к. не сможет повторы найти.
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot