EvilEngine/Sound Format

From Heavy Iron Modding
(Redirected from Sound Format)

This page contains information on how sounds and music are stored in EvilEngine games.

In Scooby-Doo! Night of 100 Frights and SpongeBob SquarePants: Battle for Bikini Bottom sounds are usually contained in SND and SNDS assets, with the SNDI asset containing information about them. Each HOP file (sometimes the HIP) contains multiple SND and SNDS assets and one single SNDI asset. There doesn't seem to be an internal difference between SND and SNDS other than being stored as different assets; sound effects are usually in SND and voice lines and music (stored in mnu5.HIP in BFBB) are usually in SNDS.

In The SpongeBob SquarePants Movie, The Incredibles and The Incredibles: Rise of the Underminer, SND and SNDS assets are empty, and instead, all of the sounds are contained entirely in the SNDI asset.

Xbox and the FMOD GameCube games are the only platform which support Stereo. PS2 and GameCube (Scooby/BFBB) only support Mono due to its sound format (VAG and DSP).

SND/SNDS Format

SND/SNDS
Sound/Streaming Sound
TypeBinary
Games usedNight of 100 Frights

Battle for Bikini Bottom
The SpongeBob SquarePants Movie
The Incredibles
Rise of the Underminer

Ratatouille Prototype

GameCube (Night of 100 Frights/Battle for Bikini Bottom)

The audio format on the GameCube version of Scooby-Doo and BFBB is a Nintendo DSP-ADPCM audio file stripped of its 0x60 bytes *.dsp header: all of a level's sound headers are kept separate in the single SNDI asset.

GameCube (The SpongeBob SquarePants Movie - Ratatouille Prototype)

Those games on GameCube are the only EvilEngine games which utilize the FMOD audio engine. This allows stereo support although it still uses the same Nintendo non-stereo codec like Scooby-Doo and BFBB by interleaving two mono tracks. SND/SNDS assets are empty; all sounds are contained entirely in SNDI assets within "FSB3" (FMOD Sample Bank) files.

Xbox

The audio format on the Xbox version of all 5 games is either Xbox ADPCM, or raw 16-bit Linear PCM stripped of its *.wav header: all of a level's sound headers are kept separate in the single SNDI asset.

PlayStation 2

The audio format on the PS2 version of all 5 games is a PS2 VAG sound file stripped of its 0x30 bytes header (except in Scooby-Doo): all of a level's sound headers are kept separate in the single SNDI asset. The first 0x10 bytes are usually null to initialize the SPU.

CSSS Format

CSSS
Cutscene Streaming Sound
TypeBinary
Games usedThe SpongeBob SquarePants Movie

The Incredibles

Rise of the Underminer

Same as SND/SNDS in Movie and The Incredibles: CSSS assets are empty and only used to "link" the sound header in SNDI with the sound data stored in cutscenes.



SNDI Format

SNDI
Sound Info
TypeBinary
Games usedNight of 100 Frights

Battle for Bikini Bottom
The SpongeBob SquarePants Movie
The Incredibles
Rise of the Underminer

Ratatouille Prototype

GameCube (Night of 100 Frights/Battle for Bikini Bottom)

The SNDI has a 0xC or 0x10 bytes big-endian header:

Offset Type Variable Description
0x00 u32 num_effects Amount of headers for SND assets
0x04 u32 - Padding "0xCDCDCDCD"
0x08 u32 num_streams Amount of headers for SNDS assets
0x0C u32 num_cutscenes Amount of headers used in cutscene assets. (BFBB only)

After that, there are three consecutive arrays of SNDI entries: one for the SND, one for the SNDS and one for cutscene headers. Each SNDI entry is 0x64 bytes long, big-endian and follows this structure:

Offset Type Variable Description
0x00 u32 num_samples Amount of raw samples
0x04 u32 num_adpcm_nibbles Amount of ADPCM nibbles (including frame headers)
0x08 u32 sample_rate Sample rate in Hz
0x0C u16 loop_flag 0 = Not Looped, 1 = Looped
0x0E u16 format Always 0
0x10 u32 sa Loop start offset, in nibbles
0x14 u32 ea Loop end offset, in nibbles
0x18 u32 ca Initial offset value, always 2
0x1C s16[16] coef Decoder coefficients
0x3C u16 gain Gain factor. Always 0
0x3E u16 pred_scale Predictor and scale. This will be initialized to the predictor and scale value of the sample’s first frame.
0x40 u16 yn1 History data; used to maintain decoder state during sample playback
0x42 u16 yn2
0x44 u16 loop_pred_scale Predictor/scale for the loop point frame. If the sample does not loop, this value is zero
0x46 u16 loop_yn1 History data for the loop point. If the sample does not loop, this value is zero.
0x48 u16 loop_yn2
0x4A u8[22] pad Unknown values
0x60 AssetID uAssetID Asset ID of corresponding SND/SNDS asset

GameCube (The SpongeBob SquarePants Movie - Ratatouille Prototype)

In those games, the SNDI contains not only the sound headers but also the entirety of the sound data themselves.

SNDI Header

The SNDI itself has a 0x20 byte big-endian header:

Offset Type Variable Description
0x00 AssetID uSoundInfoID Asset ID of this asset
0x04 u32 uSumFSBSize / nOffsetFinalFSBEnd Total size of all FSB3 files, also offset to the Footer section (relative to end of this header, add 0x20 to get the absolute offset).
0x08 s32 pFMusicMod null
0x0C s32 pFSBFileArray null
0x10 s32 pWavInfoArray null
0x14 s32 pCutsceneAudioHeaders null
0x18 u16 nWavFiles Total amount of sounds
0x1A u16 nSounds Amount of sounds in the first FSB3 of the SNDI
0x1C u16 nStreams Amount of sounds combining all FSB3's which are not the first of the SNDI
0x1E u8 nFSBFiles Amount of FSB3 files
0x1F u8 nCutsceneAudioHeaders Amount of cutscene headers

FSB3 Format

All sounds are contained inside FSB3 files. The first FSB3 is loaded into RAM, thus it has a ~8MB size limit, but can contain multiple sounds. Every subsequent FSB3 is streamed, thus it has no size limit but can only contain 1 sound. Read FMOD for more information about FMOD and the FSB3 format. Note: SNDI header and the Footer section are stored in big-endian while FSB's are little-endian.

Footer Section

This is a section which occurs at the end of the SNDI. The offset to this is set in the SNDI header. This is its structure:

FSB3 Offsets
Offset Size Description
0x00 4[nFSBFiles] Array of ints. The amount of ints is the same amount of FSB3 files, as set in the SNDI header. Each int is an offset to the start of each FSB3 file, relative to the end of the SNDI header. Add 0x20 to each value to get the absolute offset.

After this, we have nWavFiles times the following structure, which refers to each sound in the SNDI:

gcWavInfo
Offset Type Variable Description
0x00 AssetID uAssetID Asset ID of sound.
0x04 u8 uFlags Loop and format flag.
  • 0 = RAM sound (first FSB)
  • 1 = Looped
  • 2 = Streaming sound (subsequent FSB)
0x05 u8 uAudioSampleIndex Zero-based index of sound inside its FSB3 file
0x06 u8 uFSBIndex Zero-based index of the FSB3 file containing this sound (index to the FSB3 offsets array)
0x07 u8 uSoundInfoIndex
Cutscene Header

At the end of the SNDI are the cutscene header. They are a 0x60 bytes dsp header + asset id of corresponding CSSS asset (same format as header in Scooby/BFBB).

Xbox

Stored in little-endian. The SNDI has a 0xC byte header:

Offset Type Variable Description
0x00 u32 num_effects Amount of headers for SND assets
0x04 u32 num_streams Amount of headers for SNDS assets
0x08 u32 num_cutscenes Amount of headers used in cutscenes assets

After that, there are three consecutive arrays of entries: one for the SND, one for the SNDS and one for cutscene headers. Each entry is 0x2C bytes long and follows this structure:

Offset Type Variable Description
0x00 u16 wFormatTag 1 if PCM, 0x69 (105) if Xbox ADPCM
0x02 u16 nChannels Number of audio Channels. Always 1 (Mono), but support for 2 (Stereo)
0x04 u32 nSamplesPerSec Sampling rate in Hz
0x08 u32 nAvgBytesPerSec Used as an estimate for bytes per second. Can be ignored
0x0C u16 nBlockAlign Block size in bytes. 2 if PCM, 36 (0x24) if Xbox ADPCM
0x0E u16 wBitsPerSample Number of bits used per sample. 16 (0x10) if PCM, 4 if Xbox ADPCM
0x10 u16 cbSize Amount of extra bytes. Always 0 if PCM, 2 if Xbox ADPCM (NibblesPerBlock)
0x12 u16 NibblesPerBlock ADPCM nibbles per block. 64 (0x40) if Xbox ADPCM, 0 if PCM
0x14 u32 Datasize Size of corresponding sound data.
0x18 AssetID Sound Asset ID Asset ID of corresponding SND or SNDS asset
0x1C u32 flag/loop 0 = Not Looped, 1 = Looped, 2 = Unknown
0x20 u8[12] Padding null

More information about Xbox ADPCM.

PlayStation 2

The SNDI has a 0x8 or 0xC bytes little-endian header:

Offset Type Variable Description
0x00 AssetID assetID AssetID of SNDI (Only present in Incredibles and ROTU)
0x04/0x00 uint num_effects Amount of headers for SND assets
0x08/0x04 uint num_streams Amount of headers for SNDS assets

After that, there are two consecutive arrays of SNDI entries: one for the SND and one for the SNDS. Each SNDI entry is 0x30 bytes long and is a Sony VAG header.

Scooby-Doo: Night of 100 Frights

Stored in big-endian, except reserved and probably also reserved2 which are in little-endian.

Offset Type Variable Description
0x00 char[4] id "VAGp"
0x04 u32 version Always 3, 4 or 32
0x08 u32 reserved Asset ID of corresponding SND/SNDS
0x0C u32 data_size Size of corresponding SND/SNDS asset
0x10 u32 frequency Sampling rate in Hz
0x14 u32[3] reserved2
  • u32[1]: null
  • u32[2]: null or 0xE4AC0000
  • u32[3]: null
0x20 char[16] name Old filename, can be ignored

There are two 0x30 bytes "RIFF" header with a different format, one in I001.HIP and in S005.HIP. However, they don't seem to work ingame.

Battle for Bikini Bottom - Rise of the Underminer

Stored in little-endian.

Offset Type Variable Description
0x00 char[4] id "VAGp"
0x04 u32 version 4 or 32 in BFBB, always 32 in every other game
0x08 u32 assetID Asset ID of corresponding SND/SNDS
0x0C u32 data_size Size of corresponding SND/SNDS asset
0x10 u32 frequency Sampling rate in Hz
0x14 u32 streamInterleaveSize
0x18 u32 streamInterleaveCount
0x1C u32 reserved2
0x20 char[16] name Old filename, can be ignored