CHAR | 8-битовое целое со знаком, 1-байтовый символ |
BYTE | 8-битовое целое без знака |
INT | 16-битовое целое со знаком |
UINT | 16-битовое целое без знака |
LONG | 32-битовое целое со знаком |
ULONG | 32-битовое целое без знака |
PSTRING | Строка фиксированной длины (Pascal-строка) |
FDAHeader | Заголовок файла |
FBIF | Порция File Burn Info |
FDA_ | Порция-контейнер FDA |
INFO |
Порция INFO |
DATA |
Порция DATA |
typedef struct TFDAHeader {
CHAR Signature[12]; // Идентификатор файла (всегда "Relic Chunky")
CHAR SignServ[4]; // (всегда 0x0d0a1a00)
ULONG MajorVer; // Возможно, старший номер версии (всегда 0x01)
ULONG MinorVer; // Возможно, младший номер версии (всегда 0x01)
} FDAHeader;
Поле SignServ останавливает вывод файла на экран в командной строке (команда "type”).
typedef struct TChunkHeader {
CHAR ChunkType[4]; // Тип порции
CHAR ChunkID[4]; // Идентификатор порции
ULONG ChunkVer; // Версия порции
ULONG ChunkSize; // Размер данных в порции, в байтах
ULONG lenChunkName; // Длина строки ChunkName
CHAR ChunkName[lenChunkName]; // Имя порции
} ChunkHeader;
Поле ChunkType определяет тип порции: "DATA" - порция содержит данные
(структуру и/или поток); "FOLD" - порция-контейнер, содержит субпорции.
В этом случае в поле ChunkSize записывается сумма размеров всех субпорций.
typedef struct TFBIFChunk {
ULONG lenPluginName; // Длина строки PluginName (всегда 0x0a)
CHAR PluginName[lenPluginName]; // Имя плагина (всегда "RAW to FDA")
ULONG PluginVer; // Версия плагина (всегда 0x01)
ULONG lenUserName; // Длина строки UserName
CHAR UserName[lenUserName]; // Имя пользователя в ОС
ULONG lenBurnTime; // Длина строки BurnTime
CHAR BurnTime[lenBurnTime]; // Дата и время создания файла
} FBIFChunk;
Поле PluginName определяет имя плагина, который использовался при создании
файла (или умеет работать с данными, записанными в файле).
ChunkType = "DATA"
ChunkID = "FBIF"
ChunkVer = 0x01
lenChunkName = 0x0d
ChunkName = "FileBurnInfo"\0
typedef struct TFDA_Chunk {
} FDA_Chunk;
Поля заголовка порции всегда равны следующим значениям:
ChunkType = "FOLD"
ChunkID = "FDA "
ChunkVer = 0x01
lenChunkName = 0x00
ChunkName = ""
typedef struct TINFOChunk {
ULONG Channels; // Количество каналов (1 - моно, 2 - стерео и т.д.)
ULONG SampleSize; // Размер семпла в битах
ULONG BlockBitrate; // Размер фрейма в битах
ULONG SampleRate; // Частота дискретизации в герцах
ULONG BeginLoop; // Начало цикла (всегда 0x00)
ULONG EndLoop; // Конец цикла (всегда 0xffffffff)
ULONG StartOffset; // Начальное смещение цикла (всегда 0x00)
} INFOChunk;
Поле BlockBitrate определяет размер фрейма в битах. Стандартные значения 256,
512, 1024 и 2048 эти значения соответствуют следующим битрейтам (для одного
канала): 22.05kbps, 44.1kbps – низкое качество, 88.2kbps – среднее качество
и 176.4kbps – высокое качество.
ChunkType = "DATA"
ChunkID = "INFO"
ChunkVer = 0x01
ChunkSize = 0x1c
lenChunkName = 0x00
ChunkName = ""
typedef struct TDATAChunk {
ULONG DataSize; // Размер сжатых звуковых данных
BYTE SoundData[DataSize]; // Звуковые данные
} DATAChunk;
Поля заголовка порции всегда равны следующим значениям:
ChunkType = "DATA"
ChunkID = "DATA"
ChunkVer = 0x01
lenChunkName = 0x00
ChunkName = ""
FORM | Порция-контейнер FORM |
FVER |
Порция Format Version |
COMM |
Порция Common |
SSND |
Порция Sound Data |
MARK |
Порция Marker |
typedef struct TSSNDChunk {
ULONG Offset; // Смещение данных (всегда 0x00)
ULONG BlockSize; // Размер блока данных (всегда 0x00)
UINT BlockBitrate; // Размер фрейма в битах
} SSNDChunk;
Поле BlockBitrate существует только в файлах, созданных программами Relic.
Значение этого поля аналогично полю BlockBitrate порции INFO в FDA файле.
typedef struct TAIFCMarker {
UINT MarkerID; // Уникальный ID маркера (должен быть >0)
ULONG Position; // Позиция в данных, на которую указывает маркер
PSTRING MarkerName; // Имя маркера
} AIFCMarker;
Программы Relic записывают в файл три маркера:
MarkerID = 0x01
Position = 0x00
MarkerName = "beg loop"\0
End Loop Marker:
MarkerID = 0x02
Position = 0xffffffff
MarkerName = "end loop"\0
Start Offset Marker:
MarkerID = 0x03
Position = 0x00
MarkerName = "start offset"\0
При указанных значениях поля Position цикл не работает. Некоторые программы
Relic при таких значениях вообще не записывают в файл порцию MARK, другие все
же записывают.