Эта заметка писалась когда еще Ion Maiden не была переименована в Ion Fury.
Это же надо было прикопаться к такому.
Маркетологи рок-группы по моему пробили днище из днищ.
В DMC файле может быть произвольное количество сэмплов, их расположение и длина неизвестны. В модуле с мелодией есть таблица сэмплов в 63 записи, по одной записи для каждой ноты, начиная с C-1. Эти записи указывают, где в DMC файле находятся данные нужных сэмплов, какова их длина и питч. В нотном тексте сэмплы с нужными параметрами вызываются просто проигрыванием соответствующей ноты. Сэмпл лая назначен на ноту C-4 в исходном модуле, из которого строится таблица параметров сэмплов. 36 — смещение в табличке, она начинается с C-1, и если добавить 36 (3*12), получается C-4.
Я реально не понимаю связи. Почему 36 какое то отношение имеет к ноте C-4 и какое отношение обе этих вещи вообще могут иметь к потоку однобитовых звуковых данных со звуком лающей собачки.
У музык и sfx всё было достаточно просто — 0..N и соответствующие API логичные и простые и их легко было увидеть в интерфейсе в поле «Song», а тут непонятно.
Но я всё-таки вообще не шарю как музыкант в трекерных этих делах потому что музыкантом даже близко не являюсь и в трекерах шарю как та лающая собачка в апельсинах. Поэтому не удивительно.
Ладно, я даже уже из-за необходимости 3 раза опрашивать контроллер выкинул DCPM из урока, проблем куча, а одно уже только объяснение почему я его выкинул заняло полэкрана. Со всеми этими фейковыми считываниями портов ввода и как там биты портятся.
Думаю это годится на «сложную» тему в будущем после мапперов и полноценного скроллинга реальной карты метатайлов. Посмотрим. Так или иначе спасибо за ответы.
FamiTracker отношения к вопросу не имеет, это связано с устройством приставки и возможностями FamiTone. Сэмплы в нотном тексте назначаются на ноты для удобства использования. В данных мелодии есть таблица соответствия нот и сэмплов, а также их параметров — смещения от начала блока, длительность, питч. Вызов FamiToneInit нужен, чтобы сохранить указатель на эту таблицу сэмплов (FT_DPCM_LIST), чтобы при вызове FamiToneSamplePlay знать, где она находится.
Внутри файла DMC нет ничего, кроме бинарного потока сэмплов, никаких заголовков. Его содержимое описывается только таблицей в мелодии.
В старых версиях FamiTone поддерживалось только 12 сэмплов, была короткая табличка, с расчётом на то, что сэмплы будут использоваться только для немногочисленных ударных инструментов. Позже я сделал поддержку 63 сэмплов, чтобы можно было делать сэмплированный бас а-ля Sunsoft. Номер сэмпла 36 — это нота C-4. Описание в readme.txt просто не было обновлёно, как обычно.
Появились еще вопросы связанные с Samples. Тут мне не хватает уже видимо знаний самого Famitracker, как устроены его мелодии.
1. Правильно ли я понимаю, что Samples изначально могут быть как бы инструментами в мелодии?
2. Правильно ли я понимаю, что Samples поэтому как бы пристёгнуты в первую очередь к мелодии и чтобы их инициализировать нужно вызвать FamiToneMusicInit?
3. Когда мы Samples грузим через .incbin по адресам в верхних 16Кб ПЗУ — там внутри .dmc файла тоже есть некий заголовок который хранит сколько самплов тут есть? Потому что совсем непонятно почему в demo.asm вызывается так:
lda #36 ;play sample 36
jsr FamiToneSamplePlay
но в readme.txt написано:
FamiToneSamplePlay
A is sample number 1..12 (i.e. note C..B with assigned sample).
«Таким образом в итоге в буфере остаются данные только самых громких частей… Это не самое оптимальное решение, но оно вполне рабочее»
На практике звучит отлично. Давно удивлялся как при всего четырёх-пяти физических осцилляторах-каналах на практике игр у Famicom/NES/Денди и музыка играет и выстрелы-попадания-прыжки звучат как влитые. И ощущение, что музыка выпадает существует прям на грани восприятия. Ведь всё это было и звучало нормально.
«можно делать что угодно без ограничений и без указания авторства.»
Я вообще считаю обязательным такой тип лицензии для уроков/обучения, т.е. все мои уроки в той же лицензии. Но конечно в самих уроках нельзя не упоминать откуда берёшь материал.
Общаюсь по письму в неделю по поводу IDE Nesicide с Кристофером (который её автор) упомянул как то тебя и он мне написал следующее:
«Indeed. He is very talented. I created a nesicide project of his Alter Ego game to show debugging in C in nesicide.»
:)
Вывод данных регистров идёт не напрямую в APU, а в промежуточный буфер. Сначала выводятся данные регистров для музыки. Далее для каждого из виртуальных каналов эффектов для Pulse и Noise каналов проверяется текущая моментальная громкость канала эффекта, если она выше той, что записана в буфер, значения соответствующего канала APU перезаписываются данными для эффекта; для Triangle перезапись идёт всегда, если он активен (т.к. громкость у него бинарная, вкл-выкл). Таким образом в итоге в буфере остаются данные только самых громких частей, если эффект громче музыки — он глушит соответствующие каналы музыки, если эффекты одинаковой громкости, приоритет у старшего канала эффектов. Это не самое оптимальное решение, но оно вполне рабочее, и в принципе нет однозначно лучшего решения, у каждого есть свои плюсы и минусы.
Новых мелодий у меня нет. FamiTone и всё ему сопутствующее опубликовано под лицензией CC0/PD, можно делать что угодно без ограничений и без указания авторства.
У меня появилось два вопроса:
Первое — для теории мне надо понять как в Famitone2 Sfx совмещаются с музыкой и как они совмещаются друг с другом. Подозреваю что Sfx-каналы с меньшими номерами пишут в порты в Update позже больших и таким образом просто перетирают их осцилляторы при коллизиях. А вот как с музыкой оно сосуществует?
Второе — для урока нужны примеры и музыки и звуков. Можно ли взять (естественно с указанием авторства) их из самой Famitone2 с одной стороны, а с другой стороны нет ли желания какую нибудь новую мелодию выставить? В license.txt я для всех сторонних материалов по умолчанию пишу «автор дал разрешение использовать в рамках данного урока, любые другие применения надо обсуждать с ним».
P.S.
Сегодня понял как вкравшаяся ошибка осталась незамеченной — если одновременно и FT_PAL_SUPPORT = 1 и FT_NTSC_SUPPORT = 1, то всё скомпилируется потому что выполнение пойдёт по ветке когда все символы определены и проблем не возникает. А вот попытка хоть что-то из этого отключить вызовет ошибку отсутствия определения символа FT_PITCH_FIX.
Оставлю это здесь, для подшивки к основополагающим принципам.
Релизы идеально называть именами не больше 8 букв для сохранения совместимости с разными файловыми системами.
Старая кассетная школа говорит нам, что имя может быть 10 символов — ОК.
Однако если вы пошли дальше, и пишите длинное название релиза, учитывайте, что в браузере DivIDE FatWare видно всего лишь 19 символов (имя точка расширение). Если у вас несколько версий файлов и СУТЬ указана в конце (например финальный релиз Tiratok) то после копирования их на DivIDE просто невозможно понять, какой из файлов нужен.
Подозреваю еще, что в культуре где как минимум три разных ассемблера на вкус и цвет многие просто правят не задумываясь «адаптируя исходник под другой ассемблер на свой» и не считая нужным сообщать что есть какие то проблемы, т.к. такое часто бывает.
Я без понятия, видимо так. Надо понимать, что это старый проект, в который на протяжении многих лет предлагали изменения какие-то люди, ожидая, что я всё время только о нём и думаю — но мне, чтобы ответить на любой вопрос, теперь нужно разбираться столько же времени, сколько и любому другому человеку. Это вообще типичная история поддержки homebrew-проектов — первые несколько лет после выхода они не нужны и не интересны никому. А когда успел разочароваться в результатах, сделать десяток других, заняться вообще принципиально другими делами в жизни, люди вдруг начинают писать — а почему эта запятая не на том месте? А почему в конвертере в версии XYZ пятилетней давности было $30, а в версии XYZZ четырёхлетней давности стало $c0, но код плеера не поменялся? А почему окно конвертера открывается и сразу закрывается?
Версия CA65 автоматически генерируется из мастер-исходника для NESASM, вероятно отсюда растут ноги у проблемы. Вероятно, когда и если я с этим сталкивался сколько-то лет назад, я один раз пофиксил по месту и забыл. Но скорее просто за всё это время данные дефайны ни разу никому никаким образом не понадобились, включая меня — в рабочем коде пары текущих проектов они у меня точно в таком же виде, как в цитате выше.
Насколько я понял в последней версии Famitone2 (1.15) ( вроде бы одно и то же лежит и тут famitracker.com/downloads.php и тут shiru.untergrund.net/code.shtml ) закралась ошибка в версии исходника для CA65.
Комментарии и код предполагают как бы такое использование:
; FT_PAL_SUPPORT ;undefine to exclude PAL support
; FT_NTSC_SUPPORT ;undefine to exclude NTSC support
.if(FT_PAL_SUPPORT)
.if(FT_NTSC_SUPPORT)
FT_PITCH_FIX = (FT_PAL_SUPPORT|FT_NTSC_SUPPORT)
.endif
.endif
т.е. идентификаторы воспринимаются как макросы которые могут быть defined/undefined.
Но справка по ключевому слову .IF в CA65 www.cc65.org/doc/ca65-11.html#ss11.47 говорит, что .IF воспринимает константу времени компиляции которая обязана быть defined и трактует её как число ровно как c-style if.
Соответственно попытка компиляции выдаёт кучу ошибок и здесь и ниже везде на .if и чтобы этого не было нужно присвоить идентификаторам 0 или 1 и вообще убрать .if в данном случае (но не ниже по коду), т.е.:
FT_PAL_SUPPORT = 0 ; set 0 or 1
FT_NTSC_SUPPORT = 1
FT_PITCH_FIX = (FT_PAL_SUPPORT|FT_NTSC_SUPPORT)
Тогда вроде компилируется, хотя до запуска я еще не скоро дойду чтобы точно сказать что работает.
.if-ы в этих строках вообще получается что не нужны, т.к. могут сделать символ undefined и это вызовет ошибку ниже где он тестируется в .if опять же.
Это же надо было прикопаться к такому.
Маркетологи рок-группы по моему пробили днище из днищ.
И кто комментирует её первым?
>8-D
Я реально не понимаю связи. Почему 36 какое то отношение имеет к ноте C-4 и какое отношение обе этих вещи вообще могут иметь к потоку однобитовых звуковых данных со звуком лающей собачки.
У музык и sfx всё было достаточно просто — 0..N и соответствующие API логичные и простые и их легко было увидеть в интерфейсе в поле «Song», а тут непонятно.
Но я всё-таки вообще не шарю как музыкант в трекерных этих делах потому что музыкантом даже близко не являюсь и в трекерах шарю как та лающая собачка в апельсинах. Поэтому не удивительно.
Ладно, я даже уже из-за необходимости 3 раза опрашивать контроллер выкинул DCPM из урока, проблем куча, а одно уже только объяснение почему я его выкинул заняло полэкрана. Со всеми этими фейковыми считываниями портов ввода и как там биты портятся.
Думаю это годится на «сложную» тему в будущем после мапперов и полноценного скроллинга реальной карты метатайлов. Посмотрим. Так или иначе спасибо за ответы.
Внутри файла DMC нет ничего, кроме бинарного потока сэмплов, никаких заголовков. Его содержимое описывается только таблицей в мелодии.
В старых версиях FamiTone поддерживалось только 12 сэмплов, была короткая табличка, с расчётом на то, что сэмплы будут использоваться только для немногочисленных ударных инструментов. Позже я сделал поддержку 63 сэмплов, чтобы можно было делать сэмплированный бас а-ля Sunsoft. Номер сэмпла 36 — это нота C-4. Описание в readme.txt просто не было обновлёно, как обычно.
1. Правильно ли я понимаю, что Samples изначально могут быть как бы инструментами в мелодии?
2. Правильно ли я понимаю, что Samples поэтому как бы пристёгнуты в первую очередь к мелодии и чтобы их инициализировать нужно вызвать FamiToneMusicInit?
3. Когда мы Samples грузим через .incbin по адресам в верхних 16Кб ПЗУ — там внутри .dmc файла тоже есть некий заголовок который хранит сколько самплов тут есть? Потому что совсем непонятно почему в demo.asm вызывается так:
но в readme.txt написано:
Откуда эти числа берутся на самом деле?
На практике звучит отлично. Давно удивлялся как при всего четырёх-пяти физических осцилляторах-каналах на практике игр у Famicom/NES/Денди и музыка играет и выстрелы-попадания-прыжки звучат как влитые. И ощущение, что музыка выпадает существует прям на грани восприятия. Ведь всё это было и звучало нормально.
«можно делать что угодно без ограничений и без указания авторства.»
Я вообще считаю обязательным такой тип лицензии для уроков/обучения, т.е. все мои уроки в той же лицензии. Но конечно в самих уроках нельзя не упоминать откуда берёшь материал.
Общаюсь по письму в неделю по поводу IDE Nesicide с Кристофером (который её автор) упомянул как то тебя и он мне написал следующее:
«Indeed. He is very talented. I created a nesicide project of his Alter Ego game to show debugging in C in nesicide.»
:)
Новых мелодий у меня нет. FamiTone и всё ему сопутствующее опубликовано под лицензией CC0/PD, можно делать что угодно без ограничений и без указания авторства.
Первое — для теории мне надо понять как в Famitone2 Sfx совмещаются с музыкой и как они совмещаются друг с другом. Подозреваю что Sfx-каналы с меньшими номерами пишут в порты в Update позже больших и таким образом просто перетирают их осцилляторы при коллизиях. А вот как с музыкой оно сосуществует?
Второе — для урока нужны примеры и музыки и звуков. Можно ли взять (естественно с указанием авторства) их из самой Famitone2 с одной стороны, а с другой стороны нет ли желания какую нибудь новую мелодию выставить? В license.txt я для всех сторонних материалов по умолчанию пишу «автор дал разрешение использовать в рамках данного урока, любые другие применения надо обсуждать с ним».
Сегодня понял как вкравшаяся ошибка осталась незамеченной — если одновременно и FT_PAL_SUPPORT = 1 и FT_NTSC_SUPPORT = 1, то всё скомпилируется потому что выполнение пойдёт по ветке когда все символы определены и проблем не возникает. А вот попытка хоть что-то из этого отключить вызовет ошибку отсутствия определения символа FT_PITCH_FIX.
Могу подтвердить, что на сером +2 Dizzy 3 сбрасывается в самом начале игры, в буквальном смысле — с первым снегом.
Релизы идеально называть именами не больше 8 букв для сохранения совместимости с разными файловыми системами.
Старая кассетная школа говорит нам, что имя может быть 10 символов — ОК.
Однако если вы пошли дальше, и пишите длинное название релиза, учитывайте, что в браузере DivIDE FatWare видно всего лишь 19 символов (имя точка расширение). Если у вас несколько версий файлов и СУТЬ указана в конце (например финальный релиз Tiratok) то после копирования их на DivIDE просто невозможно понять, какой из файлов нужен.
Версия CA65 автоматически генерируется из мастер-исходника для NESASM, вероятно отсюда растут ноги у проблемы. Вероятно, когда и если я с этим сталкивался сколько-то лет назад, я один раз пофиксил по месту и забыл. Но скорее просто за всё это время данные дефайны ни разу никому никаким образом не понадобились, включая меня — в рабочем коде пары текущих проектов они у меня точно в таком же виде, как в цитате выше.
Комментарии и код предполагают как бы такое использование:
т.е. идентификаторы воспринимаются как макросы которые могут быть defined/undefined.
Но справка по ключевому слову .IF в CA65 www.cc65.org/doc/ca65-11.html#ss11.47 говорит, что .IF воспринимает константу времени компиляции которая обязана быть defined и трактует её как число ровно как c-style if.
Соответственно попытка компиляции выдаёт кучу ошибок и здесь и ниже везде на .if и чтобы этого не было нужно присвоить идентификаторам 0 или 1 и вообще убрать .if в данном случае (но не ниже по коду), т.е.:
Тогда вроде компилируется, хотя до запуска я еще не скоро дойду чтобы точно сказать что работает.
.if-ы в этих строках вообще получается что не нужны, т.к. могут сделать символ undefined и это вызовет ошибку ниже где он тестируется в .if опять же.