Files
aklive2d/python/fsb5/FSB5.bt

202 lines
5.5 KiB
Plaintext

//--------------------------------------
//--- 010 Editor Binary Template
//
// File: FSB5.bt
// Author: Simon Pinfold
// Purpose: Parses the FSB5 (v0 and v1) audio container.
//--------------------------------------
BitfieldDisablePadding();
string OffsetCalcComment(int offset){
string s;
SPrintf(s, "Offset = %d from sampleData start", offset * 16);
return s;
}
string FrequencyLookupComment(int value){
switch (value){
case 1: return "8000Hz";
case 2: return "11000Hz";
case 3: return "11025Hz";
case 4: return "16000Hz";
case 5: return "22050Hz";
case 6: return "24000Hz";
case 7: return "32000Hz";
case 8: return "44100Hz";
case 9: return "48000Hz";
default: { Warning("Invalid value for frequency"); return "Unknown"; }
}
}
typedef enum<uint32> {
NONE = 0,
PCM8 = 1,
PCM16 = 2,
PCM24 = 3,
PCM32 = 4,
PCMFLOAT = 5,
GCADPCM = 6,
IMAADPCM = 7,
VAG = 8,
HEVAG = 9,
XMA = 10,
MPEG = 11,
CELT = 12,
AT9 = 13,
XWMA = 14,
VORBIS = 15
} MODE;
typedef enum<uint32> {
CHANNELS=1,
FREQUENCY=2,
LOOP=3,
XMASEEK=6,
DSPCOEFF=7,
XWMADATA=10,
VORBISDATA=11
} CHUNK_TYPE;
typedef struct {
char id[4];
if (id != "FSB5"){
Warning( "File is not FSB5. Template stopped." );
return -1;
}
int32 version;
int32 numSamples;
int32 sampleHeaderSize;
int32 nameTableSize;
int32 dataSize;
MODE mode;
byte zero[8];
byte hash[16];
byte dummy[8];
if (version == 0) {
uint32 unknown <format=hex, bgcolor=0x0000ff>;
}
} FSOUND_FSB_HEADER_FSB5;
typedef struct {
uint32 extraParams :1;
uint32 frequency :4 <comment=FrequencyLookupComment>;
uint32 twoChannels :1;
uint32 dataOffset :28 <comment=OffsetCalcComment>;
uint32 samples :30;
if (extraParams){ // has extra params
local int _next = 1;
while (_next){
struct {
uint32 next :1;
uint32 size :24;
CHUNK_TYPE type :7;
if (type == CHANNELS){
Assert(size == 1, "Channels chunk should be 1 byte");
byte channels;
} else if (type == FREQUENCY){
Assert(size == 4, "Frequency chunk should be 4 bytes");
uint32 frequency;
} else if (type == LOOP){
Assert(size == 8, "Frequency chunk should be 8 bytes");
struct {
uint32 loopstart;
uint32 loopend;
} loop;
} else if (type == XMASEEK){
byte xmaSeek[size];
} else if (type == DSPCOEFF){
byte dspCoefficient[size];
} else if (type == XWMADATA){
byte xwmaData[size];
} else if (type == VORBISDATA){
struct {
uint32 crc32;
local int _remain = size - 4;
while (_remain > 0){
struct {
uint32 offset;
if ( _remain > 4) uint32 granulePosition;
} packetData;
_remain -= 8;
}
//byte unknownData[size-4] <format=hex>;
} vorbis;
} else {
byte unknownData[size];
}
} chunk;
_next = chunk.next;
}
}
} FSOUND_FSB_SAMPLE_HEADER;
FSOUND_FSB_HEADER_FSB5 header <bgcolor=0xffbf00>;
struct {
local int i;
for (i = 0; i < header.numSamples; i++) {
FSOUND_FSB_SAMPLE_HEADER sampleHeader;
}
} sampleHeaders <bgcolor=0x00ffff>;
if (header.nameTableSize) {
local int nameTableStart = FTell();
struct {
local int i;
for (i = 0; i < header.numSamples; i++) {
uint32 nameStart;
}
for (i = 0; i < header.numSamples; i++) {
struct {
Assert(nameTableStart + nameTable.nameStart[i] == FTell(), "nameStart did not point to expected start of string");
string name;
} name;
}
} nameTable <bgcolor=0x33ff00>;
} else {
Printf("No name table\n");
}
byte pad[(sizeof(header) + header.sampleHeaderSize + header.nameTableSize) - FTell()];
struct {
local int dataStart = FTell();
local int dataEnd = dataStart + header.dataSize;
local int i, start, end;
for (i = 0; i < header.numSamples; i++) {
end = dataEnd;
if (i+1 < header.numSamples) end = dataStart + sampleHeaders.sampleHeader[i+1].dataOffset * 16;
start = dataStart + sampleHeaders.sampleHeader[i ].dataOffset * 16;
Assert(start == FTell(), "Wrong length calculated for sample data");
struct {
if (header.mode == VORBIS){
while (!FEof()){
struct {
ushort size;
if (!size)
return 0;
ubyte audio :1;
ubyte r :7;
ubyte data[size-1];
} packet;
}
} else
byte bytes[end - start] <bgcolor=cLtGray>;
} sample;
}
} sampleData;