Sounds (Burnout Paradise)

From Burnout Wiki

Sounds in Burnout Paradise are a multifaceted topic ranging from as high a level as the directory layout and in-game purposes of sounds to as low a level as the structure of the different formats and headers in the files. This page attempts to document the interactions between sound resources in order to provide an explanation of how sounds are accessed and played in-game. To do this appropriately, the creation and/or replacement of sounds is also covered.

SndPlayer Plug-In Assets

The primary sound asset, Generic RWAC Wave Content, is a container for EA SndPlayer Plug-In Assets. The parsing of these assets has been difficult in the past but has become much easier due to multiple leaks of EA tools, the most pertinent being a 2008 version of sx (EA Sound Exchange) which can be downloaded here.

Sound Exchange is a command-line tool. Opening a command prompt window and dragging and dropping the executable should list the full path to it. This path will be referred to simply as sx from now on. Pressing enter should output basic information, and adding -h after a space should output a full help menu.

Handling assets

Encoding

Sound exchange can encode streams to a number of codecs. Those relevant to Burnout Paradise are EA-XMA, XAS V1, EALayer3 V1, and EALayer3 V2 Spike. To encode a SndPlayer-compatible file, use the following syntax:

sx -sndplayer -<format> <input> -=<output>

Where the available formats are eaxma (codec 3), xas_int (codec 4), ealayer3_int (codec 5), and ealayer3spike_int (codec 7). (Note: int stands for Interleaved.)

An example command would look like this:

sx -sndplayer -ealayer3_int "F:\Music\The Primitives - Crash (falefee trap remix).mp3" -="F:\Music\The Primitives - Crash (falefee trap remix)"

The .snr extension will be added to the output automatically.

A variable bitrate can also be specified by setting the option -vbr<quality> before the input file path, where quality is a value between 0 and 100. A quality of 100 appears to be around 256kbps, while 50 is around 160kbps. Although there is a constant bitrate option as well, it has no effect.

Decoding

Decoding is trivial with Sound Exchange. Use -wave as the format with no additional options such that the command looks like this:

sx -wave "F:\Music\The Primitives - Crash (falefee trap remix).snr" -="F:\Music\The Primitives - Crash (falefee trap remix).wav"

This will output an uncompressed file, meaning there is no quality loss.

Be aware that EA-XMA cannot be decoded using Sound Exchange.

Streams

Setting the correct play location

SndPlayer Plug-In Assets are, by default, a single file that is loaded into RAM. This is the SNR (RAM-targeted) file. Burnout, however, only uses this within other assets, such as engines or splicers. The majority of sounds use a different play location: stream or gigasample. Streams have a header which goes in RAM and is used to stream the rest of the file from alternative storage, such as discs or a hard drive. Gigasample is similar, but the first portion of the sound data resides in RAM along with the header so the rest of the stream can be loaded from storage while the sound plays.

Generally, it is streams that are encountered—in fact, only nine gigasamples are present in Burnout Paradise Remastered, those being the intro videos, race starts, showtime transitions, Party fireworks, and online entry sounds. In other words, if you need a gigasample, you will know.

Encoding streams

Generating stream-targeted assets is a simple matter of adding the -playlocstream option to the command:

sx -sndplayer -ealayer3_int -playlocstream "F:\Music\The Primitives - Crash (falefee trap remix).mp3" -="F:\Music\The Primitives - Crash (falefee trap remix)"

Once this is done, via a hex editor such as HxD, the SNR should be given a Binary File header that looks like this:

10 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00

With the edit complete, the file should be added to SOUND/STREAMS/STREAMHEADERS.BUNDLE, replacing the existing header if there was one. The SNS should go in SOUND/STREAMS, replacing the existing stream if there was one.

To find an existing header, search the Bundle debug data in Burnout Paradise Remastered for the file name. If it exists, the given resource ID is that of the resource that needs to be replaced. Depending on the toolset, it may be byteswapped (e.g., 01020304 becomes 04030201).

Encoding gigasamples

Similar to streams, gigasample-targeted assets are created by using -playlocgigasample. The amount in RAM should be specified using -gigaram<period> where period is the time in seconds from 0.0 to 10000.0:

sx -sndplayer -ealayer3_int -playlocgigasample -gigaram1.0 "F:\Music\The Primitives - Crash (falefee trap remix).mp3" -="F:\Music\The Primitives - Crash (falefee trap remix)"

Increasing the portion in RAM may have consequences on RAM-limited platforms such as the PS3 and should be done sparingly. If left unspecified, Sound Exchange will set a default period of 1.0 seconds.

Decoding streams

Wave resources have a Binary File header that must be removed in order to decode. This is always the first 8 bytes of the file, which is padded to 16 bytes in the retail game. To remove it, open the SNR from SOUND/STREAMS/STREAMHEADERS.BUNDLE in a hex editor and delete the first 16 bytes of the file. If done correctly, the file should begin with the codec ID noted in Encoding.

Once the SNR is edited, streams can be decoded by placing the SNR and SNS in the same directory and using the same file name on both. Then the stream can be decoded using the same command as with RAM-targeted assets:

sx -wave "F:\Music\The Primitives - Crash (falefee trap remix).snr" -="F:\Music\The Primitives - Crash (falefee trap remix).wav"

Crucially, the SNR extension must be lowercase in the command. Sound Exchange does not recognize the format if the extension is uppercase. (Note: This only applies to the command. File names may have uppercase extensions.)

Decoding gigasamples

Decoding a gigasample is exactly the same as decoding a stream. Unfortunately, due to what appears to be either errors or version incompatibilities, Burnout's gigasamples cannot be decoded by Sound Exchange. It is unknown whether there is a way to correctly decode them.

Global sound data

The game uses an AttribSys Vault resource stored in SOUND/BURNOUTGLOBALDATA.BIN to find and read global audio such as streams. BurnoutGlobalData contains several settings, such as what assets to use for different languages and what volume/pitch/etc to use for specific splicer sounds. It also contains strings, including those used to display the artist, track, and album names shown in-game.

BurnoutGlobalData works hand in hand with Registry and any additions to it must be reflected in the relevant Registry resource for use in-game.

Changing song details

Although it is difficult to add songs, it is possible to change the ArtistName, TrackName, and AlbumName fields for existing songs. While it is sometimes possible to simply replace the strings directly, it is not possible to extend the string beyond its original length. Strings are also sometimes used for multiple fields; for example, the Saosin string is used for not only the artist and album names, but the stream name as well, meaning any changes will cause it to look for a different file and crash the game.

To avoid these issues, custom strings are needed. Add strings to the file (the safest place is at the end), ensuring they each have a null terminator, and adjust the bin size (found at offset 0xC) to reflect the new data size, being the end offset minus the bin offset (at offset 8). Following this, find the pointers to the original strings. In a hex editor, this can be done by searching for the string and subtracting its start offset by the bin offset. Searching for this value will reveal it in the pointer node; if there is only one occurrence, it can be changed to the pointer to the desired custom string (again, the start offset of the string subtracted by the bin offset) and there is nothing more to do.

If the same pointer is used multiple times, the string is used for multiple fields. To have separate values, which pointer is used by which field must be determined. Currently, this is a trial and error process—change the pointers, one by one, to that of the custom string(s) and test them in-game, where they will display in the relevant EA Trax popup. If the game crashes, that means the pointer is to the stream name and should be kept as the original pointer. Once all pointers are correct, the process is complete.

Registry entries

Registry resources are scattered throughout the game assets. Each apply to a different sound category. These include streams, RWAC features, playback, the sound entity, CSIS, and each engine.

Unfortunately, not enough is known about the Registry to correctly add entries. This section will be updated with that information in the future.

Replacing a registry entry

Generally, replacing a registry entry is unnecessary. If changing the name is required, however, it can be done. When viewing the resource using a hex editor, by finding the associated gamedb:// path (which includes the name of the file), an entry can be updated to use a new name. 16 bytes before the start of the string is the hash of that string. Using Bo98's online hasher, the new string can have a sound hash generated and the old hash and string can be replaced, effectively replacing the entry.

Hashes for streams are different—they are hashes of the file name in the gamedb:// string, such as Adam_Ant or RaceStartRolling. It is important to get this right as this is how the game will find the file to read from.

Resource Types

Sound resource types are among the most common resources in the game and make up a significant of the total size. While the main types are understood, many of the miscellaneous types, some of which are very important, are not. A synopsis of the types is given here.

Generic RWAC Wave Content

Generic RWAC Wave Content, sometimes simply called Wave, is the primary sound asset type used by the game. Internally, it is an EA format that supports several different audio codecs and settings. The type is so ubiquitous that every sound heard in the game uses it in some form.

Ginsu Wave Content

Ginsu Wave Content, usually just called Ginsu, is a sound asset type used specifically for engine acceleration and deceleration. Ginsu is an EA format that is widely understood, but has much more limited codec and setting support than RWAC Waves. A related type, Gunsu, is found the in the Black 2 development builds.

Registry

Registry resources are, as one might expect, a registry of sound assets. They are how the game finds and accesses sounds. It is among the most important sound resources—arguably more important than the assets themselves—but are unfortunately not entirely understood.

Splicer

Splicers are containers for multiple sounds which dynamically play according to the player's actions. They are also used in engines for "sweeteners" (additional sounds such as gear shifts).

AEMS Bank

Similar to splicers, AEMS banks contain multiple sounds which usually play when the player triggers them. While some research has gone into it, it isn't yet clear why this type exists separately from Splicer.

CSIS

CSIS is a resource with links to AEMS. It has not been researched and its purpose is unknown, but it is likely relevant to adding AEMS banks.

Loop Model

Used in engines, loop models are graphs that track RPM on the X axis and volume on the Y axis. They stitch individual waves together to make a cohesive acceleration/deceleration sound.

Other types

Nicotine assets are present in the final game but have not been researched, so their purpose is unknown. The same is true of Snapshot Data. Generic RWAC Reverb IR Content is present in Burnout 5 (2007-02-22 build) under SOUND/IR.BUNDLE. Voice Hierarchy and its collection variant are both unused in Burnout, though the former is present in Black 2 (2007-02-13 build). Snr and Interpreter Data are sound-related but entirely unused.

Related resource types

Certain resources are known to be related to specific sounds. World sounds are emitted by triggers, while there is another world-related type called Static Sound Map that very little is known about. Engines also employ AttribSys Vault resources to control their behaviour. World Painter 2D resources are also related in that ambiences are in this format.