Difference between revisions of "SABS & SABL Files"

From COD Engine Research
Jump to: navigation, search
(Thanks master131. Feel free to add/fix anything you'd like.)
(Structure)
Line 13: Line 13:
 
}; // 0x10
 
}; // 0x10
  
SampleRateTable = { 8000, 12000, 16000, 24000, 32000, 44100, 48000, 96000, 192000 };
+
enum snd_asset_format
 
+
struct audio_entry_t
+
 
{
 
{
u32 name; // this is a hash of the name. Name Found in snd_alias_t asset in ff
+
  SND_ASSET_FORMAT_PCMS16 = 0x0,
        u32 size;
+
  SND_ASSET_FORMAT_PCMS24 = 0x1,
u32 offset;
+
  SND_ASSET_FORMAT_PCMS32 = 0x2,
u32 sampleCount;
+
  SND_ASSET_FORMAT_IEEE = 0x3,
u8 sampleRateIndex; // see SampleRateTable
+
  SND_ASSET_FORMAT_XMA4 = 0x4,
u8 channelCount; // enum 0x1 = mono 0x2 = dual
+
  SND_ASSET_FORMAT_MP3 = 0x5,
u8 looped;
+
  SND_ASSET_FORMAT_MSADPCM = 0x6,
u8 format; // enum 0x0 = pcm, 0x4 = xma, 0x5 = mp3, 0x8 = flac
+
  SND_ASSET_FORMAT_WMA = 0x7,
}; // 0x14
+
  SND_ASSET_FORMAT_FLAC = 0x8,
 +
  SND_ASSET_FORMAT_WIIUADPCM = 0x9,
 +
  SND_ASSET_FORMAT_MPC = 0xA,
 +
  SND_ASSET_FORMAT_COUNT = 0xB,
 +
};
  
struct header_t
+
frameRateTable = { 8000, 12000, 16000, 24000, 32000, 44100, 48000, 96000, 192000 };
 +
 
 +
struct SndAssetBankEntry
 
{
 
{
u32 magic;         // "2UX#"
+
unsigned int id; // this is a hash of the name. Name Found in SndAlias asset in ff
u32 version;         // 0x0E
+
        unsigned int size;
u32 sizeOfAudioEntry;           // 0x14
+
unsigned int offset;
u32 sizeOfHashEntry;           // 0x10
+
unsigned int frameCount;  
u32 sizeOfStringEntry;          // 0x40
+
char frameRateIndex; // see frameRateTable
u32 entryCount; // number of sound entries NOT NAME ENTRIES
+
char channelCount; // enum 0x1 = mono 0x2 = dual
u64 unk1; // always 0x8 for some reason, might be the size of the next 3 fields
+
char looping;
u64 fileLength; // Size of the whole file
+
snd_asset_format format;
u64 entries; // &audio_entry_t[0]
+
}; // 0x14
u64 hashes; // &hash_entry_t[0]
+
}; // 0x38
+
  
struct sabs_file
+
struct SndAssetBankHeader
 
{
 
{
header_t header;
+
unsigned int magic;         // "2UX#"
u8 asset_link_id[0x10];        // 16 bytes which are associated between sabs + 0x38 and soundasset + 0x830 (can be > 0x830)
+
unsigned int version;         // 0x0E
u8 nameEntries[30][64];
+
unsigned int entrySize;          // 0x14
u8 padding[0x38];
+
unsigned int checksumSize;            // 0x10
 +
unsigned int dependencySize;          // 0x40
 +
unsigned int entryCount; // number 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; // &hash_entry_t[0]
 +
char checksumChecksum[16];        // 16 bytes which are associated between sabs + 0x38 and soundasset + 0x830 (can be > 0x830)
 +
char dependencies[30][64];
 +
char padding[0x38];
 
}; // 0x800
 
}; // 0x800
 
</source>
 
</source>
  
 
To calculate the duration of an audio entry:
 
To calculate the duration of an audio entry:
  durationInMilliseconds = 1000 * sampleCount / sampleRate;
+
  durationInMilliseconds = 1000 * frameCount / frameRate;
Note that "sampleRate" is the actual sample rate value from the table and not the index/flag value from the structure.
+
Note that "frameRate" is the actual frame rate value from the table and not the index/flag value from the structure.

Revision as of 09:04, 25 December 2014

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 Alias Bank Load

Structure

Thanks to Jakes625, Red-EyeX32, master131, and kokole.

struct hash_entry_t
{
	u8 md5[0x10];                   // md5 of the audio file
}; // 0x10
 
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,
};
 
frameRateTable = { 8000, 12000, 16000, 24000, 32000, 44100, 48000, 96000, 192000 };
 
struct SndAssetBankEntry
{
	unsigned int id; 			// this is a hash of the name. Name Found in SndAlias asset in ff
        unsigned int size;
	unsigned int offset;
	unsigned int frameCount; 
	char frameRateIndex; 			// see frameRateTable
	char channelCount; 		// enum 0x1 = mono 0x2 = dual
	char looping;
	snd_asset_format format;
}; // 0x14
 
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; 		// number 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; 			// &hash_entry_t[0]
	char checksumChecksum[16];         // 16 bytes which are associated between sabs + 0x38 and soundasset + 0x830 (can be > 0x830)
	char dependencies[30][64];
	char padding[0x38];
}; // 0x800

To calculate the duration of an audio entry:

durationInMilliseconds = 1000 * frameCount / frameRate;

Note that "frameRate" is the actual frame rate value from the table and not the index/flag value from the structure.