FMOD
FMOD is an audio engine used in all Good and some Evil engine GameCube games. It uses *.fsb (FMOD Sample Bank) files to store audio data and *.fev (FMOD Event) files to control the playback of a sound (GoodEngine only). EvilEngine stores all sample banks in SNDI assets in HIP/HOP level archives, while GoodEngine stores them externally in a "media" folder. All sample banks are not encrypted and in little-endian.
Below is a table of all games and platforms which use fmod and their version.
Game (EvilEngine) | GameCube | FSB | |||
---|---|---|---|---|---|
The SpongeBob SquarePants Movie | 3.73 | 3.1 | |||
The Incredibles | |||||
The Incredibles: Rise of the Underminer | 3.74 | ||||
Ratatouille Prototype | |||||
Game (GoodEngine) | Wii | Xbox 360 | PS3 | PC | FSB |
Ratatouille | - | Unknown | Unknown | - | 3.1 |
Wall-E | 4.12.07 | Unknown | Unknown | - | 3.1/4 |
Up | 4.20.03 | Unknown | Unknown | - | |
SpongeBob's Truth or Square | 4.24.16 | Unknown | - | - | 4 |
UFC Personal Trainer | 4.32.00 | Unknown | Unknown | - | |
Hollywood Workout | 4.35.02 | Unknown | - | - | |
FGUY: Back to the Multiverse | - | Unknown | Unknown | 4.35.02 |
Format (FMOD Sample Bank)
FSB Header
0x18 (FSB3) or 0x30 (FSB4) bytes header
Offset | Type | Variable | Description (FSB3) | Description (FSB4) |
---|---|---|---|---|
0x00 | char[4] | id | "FSB3" in ASCII | "FSB4" in ASCII |
0x04 | s32 | numsamples | Amount of samples (sounds) in FSB | |
0x08 | u32 | shdrsize | Size in bytes of all sample headers | |
0x0C | u32 | datasize | Size in bytes of all compressed sound data combining all sound entries | |
0x10 | u32 | version |
| |
0x14 | u32 | mode |
Flags that apply to all samples. See Header Flags
| |
FSB4 only | ||||
0x18 | u64 | hash | - | |
0x20 | guid | guid | - | Globally unique identifier: AAAAAAAA-BBBB-BBBB-CCCC-CCCCDDDDDDDD |
Sample Header
0x50 bytes sample header for first sound only in EvilEngine, and for every sound in GoodEngine.
Offset | Type | Variable | Description (EvilEngine) | Description (GoodEngine) |
---|---|---|---|---|
0x00 | u16 | size | Sample length (0x50) + extended headers (if any) | |
0x02 | char[30] | name | Sample name in ASCII | |
0x20 | u32 | lengthsamples | Amount of samples in sound data | |
0x24 | u32 | lengthcompressedbytes | Length in bytes of compressed sound data | |
0x28 | u32 | loopstart | Start of loop in sample | |
0x2C | u32 | loopend | End of loop in sample | |
0x30 | u32 | mode | Sample Flags | |
0x34 | s32 | deffreq | Frequency - Sample rate in Hz | |
0x38 | u16 | defvol | Volume | |
0x3A | s16 | defpan | Pan | |
0x3C | u16 | defpri | Priority | |
0x3E | u16 | numchannels | Amount of channels. 1 (Mono), 2 (Stereo), >2 (Multi-channel) | |
0x40 | f32 | mindistance | Always 1.0 | |
0x44 | f32 | maxdistance | Always 1000000.0 | Always 10000.0 |
0x48 | s32 (u32) | varfreq (size_32bits) | Variable Frequency - null |
|
0x4C | u16 | varvol | Variable Volume - null | |
0x4E | s16 | varpan | Variable Pan - null |
Sample Header Basic
Only present if the FMOD_FSB_SOURCE_BASICHEADERS flag is set. Basic sample header for every consecutive sample after the first one. This is always the case in EvilEngine which means every basic sample inherits all values of the first 0x50 bytes sample header (numchannels, frequency, ...) i.e. you cannot store mono and stereo or different frequency tracks in one FSB.
Offset | Type | Variable | Description |
---|---|---|---|
0x00 | u32 | lengthsamples | Amount of samples in sound data |
0x04 | u32 | lengthcompressedbytes | Length in bytes of compressed sound data |
Extended Header
Extended header are only present if a specific flag is set and are appended to the end of a (basic) sample header.
FMOD_GCADPCMINFO
Only present if the FSOUND_GCADPCM flag ist set. GCADPCM header for every channel (stereo has 2).
Offset | Type | Variable | Description |
---|---|---|---|
0x00 | s16[16] | coef | Decoder coefficients |
0x20 | u16 | gain | Gain factor. Always 0 |
0x22 | u16 | pred_scale | Predictor and scale. This will be initialized to the predictor and scale value of the sample’s first frame. |
0x24 | s16 | yn1 | History data; used to maintain decoder state during sample playback |
0x26 | s16 | yn2 | |
0x28 | u16 | loop_pred_scale | Predictor/scale for the loop point frame. If the sample does not loop, this value is zero |
0x2A | s16 | loop_yn1 | History data for the loop point. If the sample does not loop, this value is zero. |
0x2C | s16 | loop_yn2 |
Syncpoints
Only present if the FSOUND_SYNCPOINTS flag is set.
Offset | Size | Description |
---|---|---|
0x00 | 4 | "SYNC" in ASCII |
0x04 | 4 | Amount of entries |
Entries[] | ||
0x08 | 4 | Offset in samples, relative to start of sound data |
0x0C | 256 | Name (Not present if the FSOUND_SYNCPOINTS_NONAMES flag is set) |
XMA
Only present if the FSOUND_XMA flag is set. Ratatouille and Wall-E Xbox360 use XMA1, every game after that XMA2 (with a few exceptions).
Offset | Size | Description |
---|---|---|
XMA1 | ||
0x00 | 4 | Unknown - usually 0x20 |
0x04 | 3 | Unknown |
0x07 | 1 | Unknown - Always 0, 1 or 2 |
0x08 | 4 | Unknown - Always 3, 19, 35, 36 or 51 |
XMA2 | ||
0x00 | 12 | Unknown - Always 0 |
Seek Table | ||
0x0C | 4 | Length in bytes of seek table, relative to end of this |
0x10 | 4 | Unknown - Always 1 |
0x14 | 4 | Amount of offsets in seek table. Always +1 if XMA2 |
0x18 | 4[] | Array of offsets |
Flags
Note: Only flags that occur are listed.
FSB Header Flags
0x02 = FMOD_FSB_SOURCE_BASICHEADERS [Samples have basic headers] 0x10 = FMOD_FSB_SOURCE_NOTINTERLEAVED [Sample data is not interleaved] 0x20 = FMOD_FSB_SOURCE_MPEG_PADDED [MPEG frames are aligned to the nearest 2 bytes, 16 bytes for multichannel] 0x40 = FMOD_FSB_SOURCE_MPEG_PADDED4 [MPEG frames are aligned to the nearest 4 bytes, 16 bytes for multichannel]
Sample Header Flags
0x00000001 = FSOUND_LOOP_OFF [For non looping samples] 0x00000010 = FSOUND_16BITS [For 16-bit samples] 0x00000020 = FSOUND_MONO [For mono samples] 0x00000040 = FSOUND_STEREO [For stereo samples] 0x00000100 = FSOUND_SIGNED [For user created source data containing signed data] 0x00000200 = FSOUND_MPEG [For MPEG layer 2/3 data] 0x00001000 = FSOUND_HW3D [Attempts to make samples use 3d hardware acceleration] 0x00002000 = FSOUND_2D [Tells software (not hardware) based sample not to be included in 3d processing] 0x00004000 = FSOUND_SYNCPOINTS_NONAMES [Specifies that syncpoints are present with no names] 0x00008000 = FSOUND_DUPLICATE [This subsound is a duplicate of the previous one i.e. it uses the same sample data but w/different mode bits] 0x00080000 = FSOUND_HW2D [2D hardware sounds. Allows hardware specific effects] 0x00400000 = FSOUND_IMAADPCM [Contents are stored compressed as IMA ADPCM] 0x00100000 = FSOUND_3D [3D software sounds] 0x01000000 = FSOUND_XMA [For Xbox360 only - Contents are compressed as XMA format] 0x02000000 = FSOUND_GCADPCM [For Gamecube/Wii only - Contents are compressed as Gamecube/Wii DSP-ADPCM format] 0x04000000 = FSOUND_MULTICHANNEL [Contents are interleaved into a multi-channel (more than stereo) format] 0x10000000 = FSOUND_MPEG_LAYER3 [Data is in MP3 format] 0x20000000 = FSOUND_IMAADPCMSTEREO [Signify IMA ADPCM is actually stereo not two interleaved mono] 0x80000000 = FSOUND_SYNCPOINTS [Specifies that syncpoints are present]