Sound_Engine_Guide

Sound Engine Guide

Game Sound Streams and Effects

There are two types of sounds in the game, sound streams and sound effects.

Sound streams are read dynamically from disk during the game.

Sound effects are stored in a sound bank that is loaded into memory at game and/or mission runtime.

Sound effects are 3D, meaning they are positional within the world relative to the listener.

VO and Music are 2D, meaning the listener's position is the shell of interface.

2D sounds can be played in game for just the player or everyone in the world depending on the soundhook.

Soundhooks are calls in the various text files that are triggered in code by game events.

Soundhooks call sound properties, which then play sound samples according to the properties defined and designed for a particluar event.

Engine Intro

Sound effects and sound streams are stored in lvls as laid out out by the req files and subsequently loaded or opened by the mission script. Mission scripts, aka mission luas or just "the lua" load lvls and define mission properties such as global sound properties for a mission or for the shell. The sound in the game is split between shell and in game sound as defined by how the code loads the lvl contents and when.

Building Sound Lvls

When req files are munged their contents are wrapped up (munged) into lvl files. Req files are text files that contain sections with headers that define segments their type. Some segement headers such as the str segment are also followed by other lines which define additional segment properties such as "align=2048" which is used to align the byte size of stream segments to 2048.

Sound Req Segment Headers and The Contents:

lvl = req file names

bnk = sfx and asfx files

config = snd, mus and tsr files

str = stm and st4 files

Have a look at the various reqs for existing worlds to see the syntax for the entire file. Each file can contain numerous segments, including segments referencing other reqs. Reqs referencing reqs means one lvl will contain one or more sub-lvl. Each world typically has three sound req files, one that everything is wrapped up into for a particular planet, and then one for each era that plays on that planet, which is typically two.

Naming Convention

The naming convention in a fully fleshed out world is very intuitive. Typically the way it works a world has a three-letter designation that serves as it's name, which is the prefix for all of the files. If a planet has more than one playable map, then the number of the world comes next, followed by the era and then the extension. For example, bes1gcw would represent Bespin 1 Galactic Civil War, which was the Bespin Platforms maps as played by the galatic civil war era.

The various files types and their content are listed below.

LVL = Binary files containing munged and packed game data

LUA = Lua script files define mission properties as well as generate the shell

FX = Particle effect files animate textures using emitters

ODF = Object Definition Files define all of the properties for an object

SND = Sound config file define sound properties referenced by luas, ODFs and particle effects

FFX = Foley effects config file used for connecting events in code to sound properties

SFX = Sound effects files list the paths to sound samples which are munged into a given sound bank

ASFX = Additional sound effects files, same as sfx but added for mods to supplement existing banks on PC*

MUS = Music config files define additional properties for triggering music sound streams

TSR = Sound trigger region config files define properties for triggering sounds in sound regions

STM = Stream files list the paths to stream files

ST4 = Stream files list paths to pairs of quadraphphonic stream files

WAV = Binary wav files are differing formats for VO streams, Music streams, and sound effects

*This feature was added to allow modders on the PC to supplement existing sounds.

Binary File Formats

While the raw sound data used for sound samples is always a binary wav file, the file compression, bitrate, and frequency may differ depending on the sound's use.

VO Wav Format - typically 22Khz 16 bit mono.

Music Wav Format - as high quality as possible, 48khz 16 bit stereo

Sound Effects Wav Format - as high quality as possible, 44 Khz 16 bit mono.

Stereo samples are needed for stereo surround sounds such as ambience (which are actually split into multiple channels/samples for front and back) and music which is 2D, otherwise samples are typically 3D and in the world so they need to be mono (positional).

Sound Data Flow

Here's a simplified walkthrough of the data flow. Knowing this is important for troubleshooting.

World Sound LVL (bes.req)

-> Sound Streams (bes,stm, bes.st4)

-> Stream Sample Paths

-> Sound Stream Samples

-> Sub-LVLS (bes1.req, bes2.req)

-> Sound Banks (bes.sfx)

-> Sound Effect Sample Paths

-> Sound Effect Samples

-> Sound Config Files (bes.snd)

-> Sound Properties

-> Sound Samples Sound Bank

Sound Data Structure

Mission Luas load the sound lvl for a particular planet. With that lvl are streams accesible to both eras as well as two sub-lvls, each specific to a particular era. This is what is defined by the world sound req, for example bes.req. It's contents are listed below:

Bes.req

ucft

{

REQN

{

"str"

"align=2048"

"bes1gcw_music"

"bes2gcw_music"

"bes1cw_music"

"bes2cw_music"

"bes1"

"bes2"

}

REQN

{

"lvl"

"bes1gcw"

"bes1cw"

"bes2gcw"

"bes2cw"

}

}

The sections of interest all begin with REQN. This defines a segment within the lvl that will be generated by this req. The str section defines binary sound files to be compiled into the lvl. The names listed correspond to the stm or st4 files. In this example the first four are the music streams for each era on the two playable maps on the planet Bespin. (Bespin the planet has two maps, bes1 and bes2, the Platforms map and Cloud City respectively). The last two lines are for ambient environment sound streams that are global to each level. If each level used the same set of global sounds, only one stream would be needed and it could be called bes.stm rather than having one called bes1 and one called bes2. It's important to note that duplicating assets inside the lvl means the assets is stored on the disk twice when it may not need to be.

The second section entitled lvl defines the sub-lvls to include in the final lvl. These sub-lvls are generated by req files, the names of which appear in the list. In this example there are sub-lvls for each playable level for each era.

The Sound Folder Directory Structure:

All three platforms have their own requirements as it relates to sound. The consoles have more disk space since it ships on DVD, but this also means data not loaded into memory can only be read as fast as the disk can read the number of data streams being read from disk at one time. Each platform also has it's own sound memory and sound format requirements. For example the XBOX and PC support quadraphonic streams while the PS2 does not, and the PS2 makes use of Pro Logic (PL2) encoded sounds. The PS2 has the least amount of sound memory available (1.5 MB), the XBOX second (6.0 MB) and the PC the most (32MB) for sound effects.

These constraints are primarily what drove the overall design of the folder and file structure in the beginning, driven by the need to consolidate sounds as much as possible on the consoles as well as the need to share sound assets across multiple worlds. There were many other factors driving the file and folder structure design through production, and in post production with all of the decisions made and assets and functionality in place it could probably be optimized better. Given that assets and design decisions roll in on a level by level basis leading up to ship date you can only be expected to organize things as best as possible by anticipating what the final game and asset sizes will be like.

The PC ultimately ended up having a completely different compile process for sound than the consoles. The PC munge creates a common sound bank which eliminates the need to duplicate files on disk within lvls. All three platforms also have platform-specific switches in the sfx files that allow the sound samples to be resampled differently for each platform during the munge process, further enhancing the ability to cram more sound data into memory without mastering a completely different set of files for each platform. Having said that, the majority of the sound effects on the PS2 still made use of a separate set of sound samples that were shorter in length than those used on the XBOX and PC, and the sound file formats and compression (PL2, front and back channels) also target specific platforms.

This is just as important for conserving disk space rather than memory on the PC, in which case sounds are resampled during the munge to eliminate bits if data in sound samples of frequencies not needed for a particlaur sound. The best example of this is low frequency explosions. The raw sound samples are as high quality as possible, typically 16 bit 48 khz. A low frequency sound sample such as an exmplosion rumple may only contain sound data in 0-3000 khz range or less, in which case the sample can be resampled during the munge without a percievable loss in quality while reducing the amount of data stored in the lvl dramtically. Coupled with the normal encoding compression for each platform files can be reduced from hundreds of kilobytes to tens of kilobytes during the munge.

Mission Scripts

Mission lua scripts, located in data/common/scripts/ define all of the properties for a particular mission that appears on a mission list. Each option on the game's mission list calls a specific mission lua script that defines all of the properties for the mission, from reinforcement count and unit loadouts to memory pool allocation and camera shots you see when you die. Scattered throughout each mission script are sound property definitions. The location of the properties can be consolidated as much as desired rather than scattered, what is important is the order of the assets in the lvls that are loaded for a mission. If an asset is loaded before it's sounds then the sounds will not be found. For this reason the one sound lvl that is created for each mission is typically at the top of the file before any other lvl is loadeded.

Memory management and performance is important, which is one reason why all of the sounds for a world are wrapped up into a single lvl file.

While only one lvl is built for a world, there are other global lvls accessible by default which contain streams and are also opened to play streaming sounds in addition sound effects which are

The sound lvl files built end up in one directory after munging, but their text and binary files can reside anywhere as long as they are referenced appropriately in the mission lua for each level.

Sound properties are applied to sound samples, which are wavs files of varying formats that are played in game.

One sound sample can be affected by multiple sound properties, allowing for one sound sample to be used in different ways for more than purpose.

Each sound property has a set of paramaters that can be edited to define the properties of the same when it is played. See the soundhooks.txt for details on sound paramters.