Это компилированные модули Pro Sound Creator, автор Виктор Кузьмин (KVA). Идеология сходна с ASC Sound Master, большая часть возможностей унаследована из ASM практически без изменений. И вместе с новыми получился неплохой инструмент для музыкантов, которые либо уже имели опыт работы в ASM, либо хотели, но не смогли к нему подступиться (см. список проблем ASM в описании формата ASC).
Pro Sound Creator похож на ASM в том числе и по особенностям формата компилированного модуля: в чём-то изначально, а в чём-то по мере развития. Так, начиная с версии 1.04, смещения на данные сэмплов и орнаментов стали делаться не относительно начала модуля, а как в ASM – относительно начала этих структур, но тут автор PSC явно не понял идею, для чего это было сделано в ASC, так как в PSC это не даёт таких же плюсов.
Поэтому в первую очередь необходимо ознакомиться с форматом ASC, потому что без этого некоторые моменты, описанные ниже без излишней детализации, могут показаться непонятными.
Смещение | Размер | Обозначение | Описание |
---|---|---|---|
+0 | 25 | ID | Идентификатор "PSC V1.00 COMPILATION OF " (может отличаться версиями, последняя 1.07). |
+25 | 20 | Title | Название (неиспользуемые символы забиты пробелами). |
+45 | 4 | BY | Строка " BY " (визуальный разделитель полей). |
+49 | 20 | Author | Автор (неиспользуемые символы забиты пробелами). |
+69 | 2 | Samples | Указатель на область сэмплов (в плеере не используется). |
+71 | 2 | PatsPtr | Указатель на область порядка проигрывания паттернов. |
+73 | 1 | Delay | Скорость проигрывания. |
+74 | 2 | OrnsPtr | Указатель до смещений на орнаменты. |
+76 | ? | SamPtrs | Смещения (с версии 1.04 – относительно +76) до тела каждого из сэмплов (всего может быть до 32 сэмплов). |
+OrnsPtr | ? | OrnPtrs | Смещения (с версии 1.04 – относительно +OrnsPtr) до тела каждого из орнаментов (всего может быть до 32 орнаментов). |
+Samples | ? | SamsArea | Область сэмплов: сэмплы друг за другом (структура каждого описана ниже). |
+Ornaments | ? | OrnsArea | Область орнаментов: орнаменты друг за другом (структура каждого описана ниже). Смещение +Ornaments явно в формате не хранится, но его можно вычислить из смещения нулевого орнамента, уменьшив его на 1, либо пройдясь по всем сэмплам по порядку (видимо по второму варианту и работает декомпилятор в редакторе). |
+Patterns | ? | PatsArea | Область паттернов: паттерны друг за другом (структура каждого описана ниже). Смещение +Patterns явно в формате не хранится, но его можно вычислить, пройдясь по всем орнаментам по порядку. |
+PatsPtr | ? | PlayOrder | Область порядка проигрывания паттернов (структура описана ниже). |
Как видно, формат спроектирован так, чтобы декомпилятор при загрузке модуля в редактор не метался по разным областям структуры, а шёл по порядку, раскручивая область за областью. В результате внутри модуля хранится много избыточной (не нужной для проигрывания) информации.
Я обычно смотрю на формат глазами плеера, чтобы брать из формата только то, что реально необходимо, и игнорировать всё, что не влияет на звук. Но в случае PSC такой подход оставляет слишком много вопросов. Поэтому сделаем исключение для PSC и раскрутим формат с точки зрения декомпилятора.
Первый же указатель в формате не используется в плеере. Значит это и есть точка входа декомпилятора: указатель на область сэмплов.
Область сэмплов – это парный список вида "Номер:Данные". Конец списка определяется байтом 0xFF.
Номер – это оригинальный номер сэмпла до компиляции (находится в диапазоне 0..31), не используется проигрывателем, т.к. в компилированном паттерне хранятся относительные номера сохранённых сэмплов. Если в модуле сохранено всего два сэмпла, к примеру 4-й и 8-й, то их нумерация в компилированном паттерне будет 0 и 1 соответственно.
Данные сэмпла состоят из тиков по 6 байт следующей структуры:
Смещение | Описание |
---|---|
+0 | Двухбайтовое накопление (число со знаком) смещения периода тона. |
+2 | Накопление (число со знаком) смещения шума или огибающих (последнее только если огибающие одновременно разрешены и в треке, и в сэмпле). |
+3 | Биты 7–4: неизвестно. Биты 3–0: амплитуда. |
+4 | Бит 7: 0 – данный тик является точкой зацикливания. Бит 6: 0 – данный тик является последним тиком в теле цикла. Бит 5: 0 – данный тик является последним тиком в сэмпле. Бит 4: 0 – огибающие разрешены. Бит 3 – маска шума. Бит 2: 1 – уменьшение громкости канала на 1. Бит 1: 1 – увеличение громкости канала на 1. Бит 0 – маска тона. |
+5 | Неизвестно. |
Анализируя сэмплы тик за тиком, декомпилятор достигает байта 0xFF вместо номера сэмпла. А это значит, что сэмплов больше нет, и далее начинается область орнаментов.
Область орнаментов – это также парный список вида "Номер:Данные". И также конец списка определяется байтом 0xFF.
Номер – это оригинальный номер орнамента до компиляции (находится в диапазоне 0..31), не используется проигрывателем (см. описание области сэмплов, причина та же).
Данные орнамента состоят из тиков по 2 байта следующей структуры:
Смещение | Описание |
---|---|
+0 | Бит 7: 0 – данный тик является точкой зацикливания. Бит 6: 0 – данный тик является последним тиком в теле цикла. Бит 5: 0 – данный тик является последним тиком орнамента. Биты 4–0 – накопление отклонения периода шума (старший бит – знаковый). |
+1 | Накопление к смещению ноты в полутонах (число со знаком). |
Область паттернов хоть и достаточно сложная структура, но это также список, который позволяет декомпилятору раскручивать модуль далее паттерн за паттерном. Но этот список состоит уже из пяти элементов: "Размер:Номер:Данные канала:Данные канала:Данные канала". Конец списка определяется аналогично – байтом 0xFF.
Размер – это количество строк в паттерне в диапазоне 1..64 (в проигрывателе не используется). Номер – это номер паттерна (также не используется в проигрывателе). Далее идут три одинаковые структуры, описывающие каждый канал паттерна в порядке A, B, C.
Данные канала паттерна – это последовательность байт, заканчивающихся маркёром 0xFE. Структура следующая:
Байты | Описание |
---|---|
0x00..0x56 | Установить ноту. |
0x57 | Установить громкость канала 15. Включить огибающую. |
0x58..0x66 | Установить громкость канала 1..15. Выключить огибающую. |
0x67..0x6a, Unkn | Резерв для спец. команд с параметром. |
0x6b, Tones | Запустить слайд тона вверх. Tones – величина изменений в единицах тонового регистра на каждое прерывание. |
0x6c, Tones | Запустить слайд тона вниз. Tones – величина изменений в единицах тонового регистра на каждое прерывание. |
0x6d, Tones | Запустить портаменто от текущей частоты тона к частоте устанавливаемой ноты. Tones – величина изменений в единицах тонового регистра на каждое прерывание. |
0x6e, Delay | Установить новое значение скорости проигрывания (Delay в прерываниях). |
0x6f, Unkn | Отключить орнамент. В байте Unkn – случайное значение. |
0x70, Period | Запустить периодическое повышение или понижение громкости на 1. Period – 7-битное число (6-й бит – знаковый), т.е. теоретически диапазон -64..63. Отрицательный Period для понижения громкости, положительный – для повышения, абсолютная величина – период изменений громкости в прерываниях. |
0x71, Unkn | Прервать цикл орнамента. В байте Unkn – случайное значение. |
0x72..0x79, Unkn | Резерв для спец. команд с параметром. |
0x7a, EnvT, [EnvPL, EnvPH] | Установить тип огибающей (если это канал B) В других каналах EnvT игнорируется. В канале B извлекаются ещё два байта – EnvPL и EnvPH (младший и старший байт периода огибающей). Примечание: потенциально возможен сбой, но на самом деле в канал A или C эти данные попасть не должны, т.к. в формат PSC не заложена оптимизация сохранения одинаковых каналов. |
0x7b, Noise | Установить базу для периода шума (если это канал B). |
0x7c | Выключить звук. |
0x7d | Прервать цикл сэмпла. |
0x7e..0x7f | Резерв для команд без параметра. |
0x80..0x9f | Установить сэмпл 0..31. |
0xa0..0xbf | Установить орнамент 0..31. |
0xc0..0xff | С этого момента пропускать указанное количество строк (0..63). По умолчанию 0. |
Порядок проигрывания определяется списком позиций, каждая позиция занимает 8 байт. Завершает список двухбайтовый маркёр: первый байт номер позиции для зацикливания, второй байт – 0xFF. После маркёра находится двухбайтовый указатель на позицию цикла, номер которой был указан в первом байте маркёра.
Структура одной позиции следующая:
Смещение | Описание |
---|---|
+0 | Номер позиции начиная с 0. |
+1 | Количество строк в этом паттерне. |
+2 | Двухбайтовый указатель на данные канала A этого паттерна. |
+4 | Двухбайтовый указатель на данные канала B этого паттерна. |
+6 | Двухбайтовый указатель на данные канала C этого паттерна. |
В документации к Vortex Tracker II высказано предположение о не оптимальности формата, приводящей к большим размерам модулей. Позднее было добавлено уточнение, что, возможно, большой размер у тех модулей, которые просто сохранены, а не выгружены через меню компиляции.
Теперь, после детального изучения "лишней" информации в модуле, можно констатировать и то, и другое.
Тем не менее, если не зацикливаться на размере модуля, можно подвести некоторые итоги.