Если это перевод оригинального материала — дай ссылку на оригинал, проставь тег ПЕРЕВОД и укажи это явно в начале текста.
Очень хороший рисерч. Одобрено дедом!
  • avatar aa-dav
  • 0
  • avatar aa-dav
  • 0
Эта заметка писалась когда еще Ion Maiden не была переименована в Ion Fury.
Это же надо было прикопаться к такому.
Маркетологи рок-группы по моему пробили днище из днищ.
  • avatar aa-dav
  • 0
Вот же совпадение. Именно сегодня на хабре появляется статья habr.com/ru/post/482916/
И кто комментирует её первым?

>8-D
  • avatar Shiru
  • 1
В DMC файле может быть произвольное количество сэмплов, их расположение и длина неизвестны. В модуле с мелодией есть таблица сэмплов в 63 записи, по одной записи для каждой ноты, начиная с C-1. Эти записи указывают, где в DMC файле находятся данные нужных сэмплов, какова их длина и питч. В нотном тексте сэмплы с нужными параметрами вызываются просто проигрыванием соответствующей ноты. Сэмпл лая назначен на ноту C-4 в исходном модуле, из которого строится таблица параметров сэмплов. 36 — смещение в табличке, она начинается с C-1, и если добавить 36 (3*12), получается C-4.
  • avatar aa-dav
  • 0
«Номер сэмпла 36 — это нота C-4.»

Я реально не понимаю связи. Почему 36 какое то отношение имеет к ноте C-4 и какое отношение обе этих вещи вообще могут иметь к потоку однобитовых звуковых данных со звуком лающей собачки.
У музык и sfx всё было достаточно просто — 0..N и соответствующие API логичные и простые и их легко было увидеть в интерфейсе в поле «Song», а тут непонятно.
Но я всё-таки вообще не шарю как музыкант в трекерных этих делах потому что музыкантом даже близко не являюсь и в трекерах шарю как та лающая собачка в апельсинах. Поэтому не удивительно.
Ладно, я даже уже из-за необходимости 3 раза опрашивать контроллер выкинул DCPM из урока, проблем куча, а одно уже только объяснение почему я его выкинул заняло полэкрана. Со всеми этими фейковыми считываниями портов ввода и как там биты портятся.

Думаю это годится на «сложную» тему в будущем после мапперов и полноценного скроллинга реальной карты метатайлов. Посмотрим. Так или иначе спасибо за ответы.
  • avatar Shiru
  • 1
FamiTracker отношения к вопросу не имеет, это связано с устройством приставки и возможностями FamiTone. Сэмплы в нотном тексте назначаются на ноты для удобства использования. В данных мелодии есть таблица соответствия нот и сэмплов, а также их параметров — смещения от начала блока, длительность, питч. Вызов FamiToneInit нужен, чтобы сохранить указатель на эту таблицу сэмплов (FT_DPCM_LIST), чтобы при вызове FamiToneSamplePlay знать, где она находится.

Внутри файла DMC нет ничего, кроме бинарного потока сэмплов, никаких заголовков. Его содержимое описывается только таблицей в мелодии.

В старых версиях FamiTone поддерживалось только 12 сэмплов, была короткая табличка, с расчётом на то, что сэмплы будут использоваться только для немногочисленных ударных инструментов. Позже я сделал поддержку 63 сэмплов, чтобы можно было делать сэмплированный бас а-ля Sunsoft. Номер сэмпла 36 — это нота C-4. Описание в readme.txt просто не было обновлёно, как обычно.
  • avatar aa-dav
  • 0
Появились еще вопросы связанные с 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).

Откуда эти числа берутся на самом деле?
  • avatar aa-dav
  • 0
«Таким образом в итоге в буфере остаются данные только самых громких частей… Это не самое оптимальное решение, но оно вполне рабочее»

На практике звучит отлично. Давно удивлялся как при всего четырёх-пяти физических осцилляторах-каналах на практике игр у 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.»
:)
  • avatar Shiru
  • 1
Вывод данных регистров идёт не напрямую в APU, а в промежуточный буфер. Сначала выводятся данные регистров для музыки. Далее для каждого из виртуальных каналов эффектов для Pulse и Noise каналов проверяется текущая моментальная громкость канала эффекта, если она выше той, что записана в буфер, значения соответствующего канала APU перезаписываются данными для эффекта; для Triangle перезапись идёт всегда, если он активен (т.к. громкость у него бинарная, вкл-выкл). Таким образом в итоге в буфере остаются данные только самых громких частей, если эффект громче музыки — он глушит соответствующие каналы музыки, если эффекты одинаковой громкости, приоритет у старшего канала эффектов. Это не самое оптимальное решение, но оно вполне рабочее, и в принципе нет однозначно лучшего решения, у каждого есть свои плюсы и минусы.

Новых мелодий у меня нет. FamiTone и всё ему сопутствующее опубликовано под лицензией CC0/PD, можно делать что угодно без ограничений и без указания авторства.
  • avatar aa-dav
  • 0
У меня появилось два вопроса:
Первое — для теории мне надо понять как в Famitone2 Sfx совмещаются с музыкой и как они совмещаются друг с другом. Подозреваю что Sfx-каналы с меньшими номерами пишут в порты в Update позже больших и таким образом просто перетирают их осцилляторы при коллизиях. А вот как с музыкой оно сосуществует?
Второе — для урока нужны примеры и музыки и звуков. Можно ли взять (естественно с указанием авторства) их из самой Famitone2 с одной стороны, а с другой стороны нет ли желания какую нибудь новую мелодию выставить? В license.txt я для всех сторонних материалов по умолчанию пишу «автор дал разрешение использовать в рамках данного урока, любые другие применения надо обсуждать с ним».
  • avatar aa-dav
  • 0
P.S.
Сегодня понял как вкравшаяся ошибка осталась незамеченной — если одновременно и FT_PAL_SUPPORT = 1 и FT_NTSC_SUPPORT = 1, то всё скомпилируется потому что выполнение пойдёт по ветке когда все символы определены и проблем не возникает. А вот попытка хоть что-то из этого отключить вызовет ошибку отсутствия определения символа FT_PITCH_FIX.
  • avatar sq
  • 1
Некоторые пишут, что снег на 128K/+2 машинах может привести к сбросу компьютера; я не имел возможности это проверить.


Могу подтвердить, что на сером +2 Dizzy 3 сбрасывается в самом начале игры, в буквальном смысле — с первым снегом.
Оставлю это здесь, для подшивки к основополагающим принципам.

Релизы идеально называть именами не больше 8 букв для сохранения совместимости с разными файловыми системами.
Старая кассетная школа говорит нам, что имя может быть 10 символов — ОК.

Однако если вы пошли дальше, и пишите длинное название релиза, учитывайте, что в браузере DivIDE FatWare видно всего лишь 19 символов (имя точка расширение). Если у вас несколько версий файлов и СУТЬ указана в конце (например финальный релиз Tiratok) то после копирования их на DivIDE просто невозможно понять, какой из файлов нужен.
  • avatar mmcm
  • 0
нормаха :)
  • avatar aa-dav
  • 0
Подозреваю еще, что в культуре где как минимум три разных ассемблера на вкус и цвет многие просто правят не задумываясь «адаптируя исходник под другой ассемблер на свой» и не считая нужным сообщать что есть какие то проблемы, т.к. такое часто бывает.
  • avatar Shiru
  • 2
Я без понятия, видимо так. Надо понимать, что это старый проект, в который на протяжении многих лет предлагали изменения какие-то люди, ожидая, что я всё время только о нём и думаю — но мне, чтобы ответить на любой вопрос, теперь нужно разбираться столько же времени, сколько и любому другому человеку. Это вообще типичная история поддержки homebrew-проектов — первые несколько лет после выхода они не нужны и не интересны никому. А когда успел разочароваться в результатах, сделать десяток других, заняться вообще принципиально другими делами в жизни, люди вдруг начинают писать — а почему эта запятая не на том месте? А почему в конвертере в версии XYZ пятилетней давности было $30, а в версии XYZZ четырёхлетней давности стало $c0, но код плеера не поменялся? А почему окно конвертера открывается и сразу закрывается?

Версия CA65 автоматически генерируется из мастер-исходника для NESASM, вероятно отсюда растут ноги у проблемы. Вероятно, когда и если я с этим сталкивался сколько-то лет назад, я один раз пофиксил по месту и забыл. Но скорее просто за всё это время данные дефайны ни разу никому никаким образом не понадобились, включая меня — в рабочем коде пары текущих проектов они у меня точно в таком же виде, как в цитате выше.
  • avatar aa-dav
  • 0
Насколько я понял в последней версии 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 опять же.
  • avatar aa-dav
  • 0
Логично, так и буду делать, спасибо.