STP – это родной формат компилированного модуля ZX Spectrum Sound Tracker Pro (см. описание STF).
Компилятор встроен прямо в редактор и в разных версиях Sound Tracker Pro имеет те или иные ошибки.
В некоторых компиляторах это ошибка оптимизации, при которой, удаляя вроде бы лишний (повторяющийся) орнамент, забывают про включённую до этого команду скольжения, и она начинает дублироваться на последующие ноты. Яркий пример: модуль "IMP49:FOOLISH GIRL", или Sumea_FN.stp Visual'а (по последнему нигде нет исходного STF, чтобы перекомпилировать без ошибок).
В других этой ошибки нет, но остаётся много лишнего мусора и исчезают команды установки громкости 1 (хотя это уже незаметно на слух – слишком мала громкость).
К сожалению, нумерации версий редактора нет, поэтому выбирать для себя, какой из имеющихся у вас на руках лучше, придётся методом проб и ошибок.
Если ваша цель – просто откомпилировать STF, то это можно сделать с помощью встроенного в Ay_Emul компилятора: я исправил все обнаруженные ошибки родных компиляторов и проработал оптимизацию по размеру.
Формат STP хорошо описал VfNG в электронной газете Echo № 3 (приведён в конце). Поэтому если в дальнейшем тексте будут некоторые неясные моменты, можете сперва прочитать его.
Когда я выбирал расширение STP для использования данного формата в Ay_Emul, не озвучил один важный момент (в прочем, эту ошибку допустил и с другими форматами). Многие форматы компилированных модулей имеют два состояния: инициализированные и не инициализированные. В родном проигрывателе перед началом проигрывания вызывается специальная подпрограмма инициализации. В большинстве форматов она просто готовит внутренние переменные к началу проигрывания и не вносит никаких изменений в сам модуль. Но есть плееры у некоторых форматов, в которых данные модуля во время инициализации привязываются к адресу загрузки, и есть даже такие, которые используют область заголовка для своих нужд (и, следовательно, портят её).
Во время инициализации компилированного модуля Sound Tracker Pro осуществляется привязка части смещений к адресу загрузки. Причём внутри файла есть байт-идентификатор, по которому и можно судить, что модуль уже инициализирован.
Расширение STP даётся только тем модулям, которые либо не инициализированы (то есть находятся в том состоянии, в котором их сохранили из редактора), либо с которыми произведена обратная операция отвязки от адреса загрузки.
Ay_Emul во время сохранения найденных модулей (это касается не только STP) проделывает всё необходимое, чтобы вернуть их в состояние "до инициализации".
К сожалению, в последние годы в сети начали появляться модули, которые сохранены без соблюдения этого правила, и даже с некорректно вставленными авторскими строчками (см. далее).
Поэтому в Ay_Emul для некоторых форматов (в том числе и STP) пришлось добавить дополнительные проверки после загрузки для учёта этой особенности текущего момента.
Первые трекерные форматы на ZX Spectrum мучила одна и та же болезнь. Авторы редакторов либо вообще не предусмотрели в формате место под авторскую строчку (Sound Tracker), либо предусмотрели, но не в формате, а в его плеере. При этом, если в таком редакторе как ASC Sound Master есть намёк, что проигрыватель и данные (модуль) – одно неделимое целое, то в STP прямо в документации упоминается о том, что одним проигрывателем можно играть разные модули (а ведь в таком сценарии использования становится непонятно, к какому именно модулю относится авторская строка).
Мы обсуждали эту проблему с Ильёй Кудрявцевым (Himik's ZXZ), и он предложил немного модифицировать ASC-модули. Я в свою очередь предложил проделать тоже самое с STP. Таким образом, мы договорились о двух новых форматах, главное достоинство которых – полная совместимость с оригиналами. Новые STP и ASC без проблем проигрываются оригинальными плеерами, поскольку те даже не догадываются о наличии дополнительной информации в теле блока данных.
Для вставки авторской строки (длина 53 байта, начинается с "KSA SOFTWARE COMPILATION OF ") из плеера в тело модуля, необходимо:
Далее приведена немного отредактированная выдержка из статьи VfNG в газете Echo № 3.
---------------------------cut here-------------------
В описании могут встречаться отдельные неточности, так что будьте внимательны. Это описание пишется не с целью устранения всех вопросов, а только должно помочь вам разобраться в некоторых вещах при работе с player'ом.
+0 | Скорость проигрывания; |
+1 | Смещение до TABL1; |
+3,4 | Смещение до TABL2; |
+5,6 | Смещение до TABL3; |
+7,8 | Смещение до TABL4; |
+9 | В этом байте содержится число элементов, к которым надо прибавить реальный адрес +0 в памяти. Это делает секция инициализации. Если этот байт=0, значит инициализация уже проведена. Первый элемент, требующий настройки, находится с адреса TABL2. Каждый элемент – 2 байта (младший, старший байты смещения от +0); |
+10 | Первый паттерн; |
TABL1+0 | длина музыки в позициях; |
TABL1+1 | номер позиции для зацикливания; |
TABL1+2 | по 2 байта/позиция: +0 6*номер PATTERN; +1 HEIGHT (отклонения в нотах от обычного звучания PATTERN); |
TABL2 | описатели PATTERN'ов: по 2 байта смещения для каждого канала, значит по 6 байт/PATTERN; |
TABL3 | смещения до орнаментов. 0-й орнамент служит для отключения орнаментов в канале; |
ТABL4 | смещения до сэмплов; |
Формат орнамента:
+0 | точка зацикливания; |
+1 | полная длина; |
+2, 1*(+1) | отклонения от значения ноты; |
Формат сэмпла:
+0 | точка зацикливания; |
+1 | полная длина; |
+2 | по 4 байта/QUARK: +0 биты 0-3 амплитуда; бит 4 маска тона; бит 7 маска шума; +1 бит 0 маска огибающей; биты 1-5 частота шума; +2,3 байты частотного вибратто; |
Каждый описатель PATTERN содержит указатели на описатели каналов. Каналы анализируются следующим образом:
LD HL,CHAN_POS LD A,(HL) OR A JR Z,конец PATTERN LD C,#10 LOOP LD A,(HL) INC HL CP #C0 JR C,L9 SUB C JR NC,L1 SUB C JR NC,L2 SUB C JR NC,L3 SUB C JR L4 L9 SUB #80 JR NC,L5 SUB C JR NC,L6 SBC A,C JR NC,L7 L8 ADD A,#60
в A – номер ноты. Её установка, выход;
L7
в A – номер сэмпла. LOOP;
L6
в A – номер орнамента. LOOP;
L5
в A – сколько INT'ов не надо анализировать канал. LOOP;
L4
в A – тип огибающей. В следующем байте-период. Установка регистра амплитуды в #1F, LOOP;
L3
выключение канала, выход;
L2
установка величины, полученной в L5, выход;
L1 JR Z,L0 DEC A
в A – число, которое надо отнять от #0F для получения громкости. LOOP;
L0
в следующем байте – glissade. LOOP;
---------------------------cut here-------------------