SABS & SABL Files: Difference between revisions
Aerosoul94 (talk | contribs) Created page with "SAB(Stream) and SAB(Load). The B is most likely "bank" as the game code refers to a "sound bank" when loading SABL/SABS files. * SABS = Snd Alias Bank Stream * SABL = Snd Al..." |
Red-EyeX32 (talk | contribs) |
||
| (18 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
[[Category:PAK Files]] | |||
[[Category:BO2]] | |||
SAB(Stream) and SAB(Load). The B is most likely "bank" as the game code refers to a "sound bank" when loading SABL/SABS files. | SAB(Stream) and SAB(Load). The B is most likely "bank" as the game code refers to a "sound bank" when loading SABL/SABS files. | ||
* SABS = Snd | * SABS = Snd Asset Bank Stream | ||
* SABL = Snd | * SABL = Snd Asset Bank Load | ||
== Structure == | == Structure == | ||
<source lang="cpp"> | <source lang="cpp"> | ||
enum snd_asset_channel_mode | |||
{ | { | ||
SND_ASSET_CHANNEL_MODE_MONO = 0x1, | |||
}; | SND_ASSET_CHANNEL_MODE_DUAL = 0x2, | ||
// Could be more modes ex: ("Joint Stereo" and "Stereo") | |||
}; | |||
enum snd_asset_format | |||
{ | |||
SND_ASSET_FORMAT_PCMS16 = 0x0, | |||
SND_ASSET_FORMAT_PCMS24 = 0x1, | |||
SND_ASSET_FORMAT_PCMS32 = 0x2, | |||
SND_ASSET_FORMAT_IEEE = 0x3, | |||
SND_ASSET_FORMAT_XMA4 = 0x4, | |||
SND_ASSET_FORMAT_MP3 = 0x5, | |||
SND_ASSET_FORMAT_MSADPCM = 0x6, | |||
SND_ASSET_FORMAT_WMA = 0x7, | |||
SND_ASSET_FORMAT_FLAC = 0x8, | |||
SND_ASSET_FORMAT_WIIUADPCM = 0x9, | |||
SND_ASSET_FORMAT_MPC = 0xA, | |||
SND_ASSET_FORMAT_COUNT = 0xB, | |||
}; | |||
struct | struct SndAssetBankEntry | ||
{ | { | ||
unsigned int id; // this is a hash of the name. Name Found in SndBank asset in ff | |||
unsigned int size; | |||
unsigned int offset; | |||
unsigned int frameCount; | |||
char frameRateIndex; // see frame_rate_table | |||
snd_asset_channel_mode channelCount; // enum 0x1 = mono 0x2 = dual | |||
char looping; | |||
snd_asset_format format; | |||
}; // 0x14 | }; // 0x14 | ||
struct | struct SndAssetBankEntryHash | ||
{ | { | ||
char hash[16]; // md5 of the audio file | |||
}; // 0x10 | |||
}; // | |||
struct | struct SndAssetBankHeader | ||
{ | { | ||
unsigned int magic; // "2UX#" | |||
unsigned int version; // 0x0E | |||
unsigned int entrySize; // 0x14 | |||
unsigned int checksumSize; // 0x10 | |||
unsigned int dependencySize; // 0x40 | |||
unsigned int entryCount; // Amount of sound entries NOT NAME ENTRIES | |||
unsigned int dependencyCount; // Always 0x8 for some reason, might be the size of the next 3 fields | |||
unsigned int pad32; | |||
__int64 fileSize; // Size of the whole file | |||
__int64 entryOffset; // &SndAssetBankEntry[0] | |||
__int64 checksumOffset; // &SndAssetBankEntryHash[0] | |||
char checksumChecksum[16]; // 16 bytes which are associated between sabs + 0x38 and soundasset + 0x830 (can be > 0x830) | |||
char dependencies[512]; | |||
char padding[1464]; | |||
}; // 0x800 | }; // 0x800 | ||
</source> | |||
To calculate the duration of an audio entry: | |||
<source lang="cpp"> | |||
unsigned int SND_AssetBankGetFrameRate(SndAssetBankEntry *entry) { | |||
int frameRate; | |||
if (!entry) | |||
break; | |||
switch (entry->frameRateIndex) { | |||
case 0: frameRate = 8000; break; | |||
case 1: frameRate = 12000; break; | |||
case 2: frameRate = 16000; break; | |||
case 3: frameRate = 24000; break; | |||
case 4: frameRate = 32000; break; | |||
case 5: frameRate = 44100; break; | |||
case 6: frameRate = 48000; break; | |||
case 7: frameRate = 96000; break; | |||
case 8: frameRate = 192000; break; | |||
default: | |||
frameRate = 0; | |||
break; | |||
} | |||
return frameRate; | |||
} | |||
unsigned int SND_AssetBankGetLengthMs(SndAssetBankEntry *entry) { | |||
if (!entry) | |||
break; | |||
return 1000 * entry->frameCount / SND_AssetBankGetFrameRate(entry); | |||
} | |||
</source> | </source> | ||
Latest revision as of 18:56, 5 July 2015
SAB(Stream) and SAB(Load). The B is most likely "bank" as the game code refers to a "sound bank" when loading SABL/SABS files.
- SABS = Snd Asset Bank Stream
- SABL = Snd Asset Bank Load
Structure
enum snd_asset_channel_mode
{
SND_ASSET_CHANNEL_MODE_MONO = 0x1,
SND_ASSET_CHANNEL_MODE_DUAL = 0x2,
// Could be more modes ex: ("Joint Stereo" and "Stereo")
};
enum snd_asset_format
{
SND_ASSET_FORMAT_PCMS16 = 0x0,
SND_ASSET_FORMAT_PCMS24 = 0x1,
SND_ASSET_FORMAT_PCMS32 = 0x2,
SND_ASSET_FORMAT_IEEE = 0x3,
SND_ASSET_FORMAT_XMA4 = 0x4,
SND_ASSET_FORMAT_MP3 = 0x5,
SND_ASSET_FORMAT_MSADPCM = 0x6,
SND_ASSET_FORMAT_WMA = 0x7,
SND_ASSET_FORMAT_FLAC = 0x8,
SND_ASSET_FORMAT_WIIUADPCM = 0x9,
SND_ASSET_FORMAT_MPC = 0xA,
SND_ASSET_FORMAT_COUNT = 0xB,
};
struct SndAssetBankEntry
{
unsigned int id; // this is a hash of the name. Name Found in SndBank asset in ff
unsigned int size;
unsigned int offset;
unsigned int frameCount;
char frameRateIndex; // see frame_rate_table
snd_asset_channel_mode channelCount; // enum 0x1 = mono 0x2 = dual
char looping;
snd_asset_format format;
}; // 0x14
struct SndAssetBankEntryHash
{
char hash[16]; // md5 of the audio file
}; // 0x10
struct SndAssetBankHeader
{
unsigned int magic; // "2UX#"
unsigned int version; // 0x0E
unsigned int entrySize; // 0x14
unsigned int checksumSize; // 0x10
unsigned int dependencySize; // 0x40
unsigned int entryCount; // Amount of sound entries NOT NAME ENTRIES
unsigned int dependencyCount; // Always 0x8 for some reason, might be the size of the next 3 fields
unsigned int pad32;
__int64 fileSize; // Size of the whole file
__int64 entryOffset; // &SndAssetBankEntry[0]
__int64 checksumOffset; // &SndAssetBankEntryHash[0]
char checksumChecksum[16]; // 16 bytes which are associated between sabs + 0x38 and soundasset + 0x830 (can be > 0x830)
char dependencies[512];
char padding[1464];
}; // 0x800To calculate the duration of an audio entry:
unsigned int SND_AssetBankGetFrameRate(SndAssetBankEntry *entry) {
int frameRate;
if (!entry)
break;
switch (entry->frameRateIndex) {
case 0: frameRate = 8000; break;
case 1: frameRate = 12000; break;
case 2: frameRate = 16000; break;
case 3: frameRate = 24000; break;
case 4: frameRate = 32000; break;
case 5: frameRate = 44100; break;
case 6: frameRate = 48000; break;
case 7: frameRate = 96000; break;
case 8: frameRate = 192000; break;
default:
frameRate = 0;
break;
}
return frameRate;
}
unsigned int SND_AssetBankGetLengthMs(SndAssetBankEntry *entry) {
if (!entry)
break;
return 1000 * entry->frameCount / SND_AssetBankGetFrameRate(entry);
}