Soundbanks For Dummies
By: Simon Viklund
Published :02 March 2007


Ok, if you've read Modding/Creating Custom Ambiance Sounds and still don't get it, I'll write a little here to try to clear things up for you happy modders.

1) A wavebank is essentially a list of wavefiles either lying in the same folder or compressed in a .bank file lying in the same folder. The list also specifies the name the wavefiles are given by which they are recognized by the soundbank.

2) A soundbank is a list of "sounds" (an abstract object, not an actual wavefile) that can be called on by the script. Essential information such as the "rolloff" and "gain" of a sound are specified within the sound tag.

3) The sound in a soundbank calls for a sound in its corresponding wavebank; for example, the script for the Beretta pistol calls for its sounds in the beretta_sound.xml soundbank, and that soundbank in turn calls for the wavefiles found in the beretta_wave.xml wavebank. A sound can be set to randomly choose from a set of waves every time the cue is played, or randomly pitch the sound to make it sound less repetitive. Look in my xml documents to see the names for these attributes - they're self explaining.

3) The beretta_wave.xml wavebank in turn calls for the actual wave data in beretta_wave.bank. This is a single file containing all the sounds associated with the beretta. You cannot compress your own .bank files - we haven't released the tools for that. You can, however, create uncompressed wavebanks, or wavebanks containing wavefiles with lower sample rate (22050 or 11025 Hz) to save RAM. The wave files will have to lie "as is" in the same folder as the wavebank.

4) Any wavebank you put under local/english/sound/.. that has a corresponding wavebank under data/sound/.. will be used instead of the one in the data/sound/.. folder. This way you can exchange wavebanks without editing the original ones.

Hope that helps.
______________________________________________________

Advanced Soundbanks: Sequences and looped sounds

Soundbanks can be pretty advanced, with looped cues, queues and sequences of sounds, and sounds calling for other sounds. For example, look at sound/environment/birds/birds_sound.xml. The sound "birds" found in this soundbank is the sound you place in trees throughout a level to have bird singing coming from that location. The sound "birds" randomly calls for either one of the sounds "bird_a_looper" through "bird_f_looper". Each of those sounds contain a sequence - a call for another sound ("bird_a_looper" calls for "bird_a", etc) and a "wait". The sound this sequence calls for in turn contains a set of very short bird sounds as well as a call for the sound "pause". The sound "pause" in turn only contains a forced "wait" of random length (2-12 seconds). This is how things happen once you've placed the sound "birds" in a tree somewhere on the map, and start playing that map:

1. The script calls for the sound "birds" once the level starts.

2. The sound randomly selects one of the sounds it contains. Once any of these "daughter sounds" are done, the "mother sound" ("birds") would have to be retriggered - but an environmental sound placed in the level editor such as "birds" will only be triggered by the script once - when the level starts - so we've made sure that any sound it randomly plays is looped in eternety. This way the bird starts singing once the level starts, and it will never stop, and the script will never have to care about that environemental sound again.

3. Let's say that the "birds" sound randomly selects "bird_e_looper". This calls for the sound "bird_e_looper" further up in the xml code (a sound called on by another sound (a "daughter sound") always has to be above the "mother sound" in the xml code - so that it is read into the memory before it.

4. The sound "bird_e_looper" is a sequence containing a call for "bird_e" and then a "wait" (a wait is not a sound or a wavefile, but a sequence event that tells the sound sequence to wait until the previous instance in the sequence (in this case the sound "bird_e") is done before continuing to the next instance in the sequence. A "wait" can also contain a random or fixed delay of the following instance. Anyway, "bird_e_looper" only contains a call for "bird_e" and then a wait - this in combination with the fact that the sound ("bird_e_looper") is set to loop will cause it to play the sound "bird_e", and once that is done, wait for "0" seconds and then start the sequence all over again, forever.

5. Every time the sound "bird_e" is called on by "bird_e_looper", it randomly selects either of these waves from the birds_wave.xml file: bird_e_01, bird_e_02, bird_e_03, bird_e_04, bird_e_05 and bird_e_06, or it plays the sound "pause". Any of these waves (which are six different short short pieces of a bird call) or sounds (which as you know is a random wait of 2-12 seconds) are a events which the sound knows when its done with - and once it is done it will, as you know, return this information ("i'm done") to the mother sound ("bird_e_looper") whose looping sequence will go to the next instance ("wait") and then loop, meaning it will call back to "bird_e" in an instant.

When this looping procedure is set in motion, it will cause this kind of sound:

bird_e_looper calls for bird_e, who randomly selects "bird_e_02"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "bird_e_01"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "bird_e_05"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "bird_e_02"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "bird_e_04"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "pause"
pause plays its sequence causing it to randomly pick an amount of seconds (2-12) to wait
pause randomly picks 8 seconds, and waits for that period of time
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "bird_e_01"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over
bird_e_looper calls for bird_e, who randomly selects "bird_e_03"
bird_e returns "i'm done" to bird_e_looper, which waits for "0" seconds and starts over...

...and it goes on and on and on and on... to a player walking around near the tree in which the sound source for the "birds" sound is placed, it will sound like a totally random "chirp chip-chip, chirrrp, chirp-chirp... (pause for X amount of seconds) ...chrip-chrip-chirrrrp, chip-chip... (pause for X amount of seconds) ...chirp, chip-chirp...."

It is essentially a neverending, never repeating bird call - superior in all ways to a looping wave file of a bird:
A) A looping file would quickly become repetitive, and the player would not only see through the illusion but maybe even become annoyed with it
B) To make it less obvious that a looping wave is looping, you would have to make it very long - and if you wanted the bird to occasionally go silent and wait for a second, that would be a second of silence in the wave file which would be a complete waste of memory AND a voice (channel) on the sound card. In my solution, all silences are only abstract "wait" instances in a sound sequence which neither take up RAM nor take up a voice on the sound card while "playing".

Also, the randomization in the "birds" sound means that if you put "birds" sound sources all over the map, each of them will randomly pick their own bird sound of the six "virtual birds" ("bird_a" through "bird_f") I've put in the "birds" sound randomizer, and stick to looping that "bird" - so there will be a plethora of different bird sounds everywhere and you don't have to do the job of typing in different sounds for each sound source you place in the map.

Now tell me I'm not a genius


© GhostRecon.net