Timpani is the Bitsquid in-house sound engine. It consists of an editor where a sound designer can manage sounds, events and parameters and a runtime component that is responsible for playing those sounds in-game.
The basic workflow when using Timpani is:
Import raw wavs into the Timpani project.
Define compression settings for the target platforms.
Create more complicated sounds from the wavs (loops, randomizers, switches, etc).
Define parameters that affect how a sound is played (volume, pitch, etc).
Define named events that start and stop particular sounds
Gameplay programmers use the events defined by the sound designer to trigger sounds at particular points in the game.
By default, Bitsquid uses Timpani for all sound rendering. If you wish to use a different external sound engine (e.g., Wwise) you have to create and manage the bindings to that engine yourself.
Here is a short summary of the different features supported by Timpani:
Timpani works on all platforms supported by the Bitsquid engine (at the writing of this document: Windows, PS3, X360, MacOS and Android).
Timpani uses each platform's native mixer as backend. That means that some features are limited by what the platform can do. For example, not all Android phones support I3DL2 reverb.
To reduce sound memory you can downsample or compress the sound resources. Timpani supports Vorbis compression on all platforms. Vorbis decompression is multithreaded for maximum performance.
SPU-accelerated MP3 decompression is supported for PS3. MP3 decompression is not supported on other platforms, because you need a license to use MP3 on other platforms than PS3.
Hardware accelerated XMA decompression is supported for X360. XMA is a Microsoft-specific format and thus not supported on other platforms. On X360, XMA gives better performance but lower quality than Vorbis.
Environment reverb thorugh the I3DL2 standard is supported.
You can define custom environments in Timpani and switch between them using gameplay code.
Both headphones and a large variety of surround sound configurations are supported (2.1, 5.1, 7.1, etc).
Multichannel sounds can be played on surround systems. When using headphones, multichannel sounds are automatically downmixed to stereo.
Timpani also supports 3D positining of multichannel sounds. This is achived by separating out the channels to different positions in the 3D world.
Allows you to control the maximum number of playing instances of each sound.
Each sound is played on a bus with specific volume and pitch settings. This allows gameplay to control the volume for entire categories of sounds, such as sfx or music. You can define whatever categories you need.
The script never directly plays sounds, instead the script communicates with Timpani through events and parameters.
For example, the script can trigger the event sword_hit, with parameters material = "metal" and force = 20.
The sound designer can choose sound, volume and pitch based on the parameters. Later, the designer can go back and add more variation and randomness to the sound without any need for gameplay changes.
The designer can create hand drawn curves that specify how sound properties such as pitch and volume are affected by the input parameters to the sound, such as force.
The sounds in Timpani are laid out in a hierarchy. Properties changed on a parent node affect all children. This makes it easier to make changes that affect many sounds at once.
Picks a random sound to play from a list of options.
Picks a sound to play based on parameter settings. For example, if a bullet hits something, a switch node might check a material parameter to determine what material the bullet hit (metal, stone, wood, etc) and pick an appropriate sound.
Plays a sound with three parts: a lead-in, a looping segment and a lead-out. Can crossfade between the parts for a smoother sound. Useful for things like machine guns that have a warm-up and a cool-down phase.
Sounds can be previewed from within Timpani. The preview uses the real engine and is played in an environment where you can walk around with the listner, ensuring that what-you-hear-is-what-you-get. You can preview on any target platform from within Timpani.
Timpani comes with a merge tool that can be integrated with a source control system such as svn or hg. The Timpani files have been designed to merge cleanly when using the tool, ensuring that multiple people in a company can work on any part of the same Timpani file without stepping on each other's toes.
Timpani supports a custom listener mode specially adapted for 2D games.
Soundscapes allow level designers to place environment sounds in the level editor, such as roaring fires, tweeting birds or babbling brooks.
Environment sounds are played when the player comes within hearing distance and consume very few resources otherwise.
Timpani supports the normal editing features you would expect from an editing application, such as cut, copy, paste and undo.
Some features not (yet) supported by Timpani are:
For split screen games, you need to be able to have more than one listener in the world. This is a small fetaure that will be added as soon as a project needs it.
Currently, sounds must be completely loaded into the engine before you can play them. We plan to add support for sound streaming, i.e. to be able to dynamically load a sound as it is being played in order to save memory. Sound streaming is a small-to-medium sized feature that hasn't yet been added to the road map.
Dynamic range mapping for sounds is similar to tone mapping for lighting. The idea is to allow very loud sounds to be played and compensate by dynamically scaling down the volume of all other sounds. This is a small-to-medium sized feature that hasn't yet been added to the road map.
Currently, you can only edit properties for one sound at a time in the Timpani editor. It would be nice to support "multi-editing", i.e., to allow the user to select a number of sounds and change the properties of all of them simulatenously.
We would like to have better support for interactive music. Some sort of sequencer interface where you could setup tracks, loops, transition, riffs, etc.
This is a medium size feature. It hasn't been planned into the road map.
Using each platform's native mixer as the backend limits what we can do to the capabilities of the platform. It also means that it is hard to achieve perfect consistency with how a game sounds across different platforms.
To be able to do advanced real time effects and achieve better cross-platform consistency we would like to replace the different native mixers with our own cross-platform software mixer.
This is a major feature. It hasn't been planned into the road map.
Convolution reverb gives better quality reverb, but requires more processing. This feature depends on having a Cross-platform software mixer.
Time stretching sounds (rather than pitching them) can sometimes be useful. This feature depends on having a Cross-platform software mixer.
We don't plan to add MIDI support.
We don't plan to add a waveform editor. We believe that most people will want to do waveform editing in a separate program and then import the finished wavs into Timpani.
The examples in this document refer to the Bitsquid sound sample project, available as a Mercurial repository at https://files.bitsquid.se/samples/. If you want to follow along to the examples, make sure that you have the sound sample installed on your machine.
This section is primarily intended for the sound designers who will use Timpani to create the sounds of a game, but it can also be instructive for anybody else who comes into contact with sound.
We start with a quick introduction on how to get started with Timpani and then go into greater detail explaining the different features of the system.
Timpani works with two sets of files. One set is used for editing and one set is used by the game. To create the game files you need to Export your data from the editor to the game directory:
The editor files have a main file called *.timpani. The game files have a main file called *.timpani_master.
In the sample project the editor files are found in the directory sound/.timpani, while the game files are found in sound/timpani.
Many projects use a setup where the source assets (e.g., Max and Maya files) are stored in a separate repository from the game files. In that case you would put the *.timpani file together with the other source assets.
The files found in the editor directory are:
This is the main file that contains all the data for the timpani project. It should be checked into source control.
This folder stores the wav resources that you have imported into your Timpani project. You should typically not manipulate the files in this folder directly. Instead use the Import Wav Files... option in Timpani to import files.
This folder should be added to source control and checked in together with the *.timpani file.
This folder contains the wav files from Originals, converted and compressed for the different platforms supported by the project. You should not manipulate the files in this folder directly.
It is best to not check this folder into source control. Timpani can generate all the files in this folder from the Originals and will do that automatically when necessary. Checking this file into source control will just consume unnecessary memory in the repository and make synching slow.
This file contains Timpani settings specific to a particular user. It should not be checked into source control, since each user should have her own settings.
In the exported game directory we also have a number of files. They should all be checked into source control:
This is the master file for the Timpani project. It contains most of the data.
This file contains information about a sound bank. A sound bank is a collection of sound resources that are loaded together by the engine. They will be explained in more detail later.
This directory contains all the compressed sound files used by the game.
To begin working with Timpani, launch it from the Tool Center and either open an existing *.timpani project or create a new one.
One of the first things you should do with a new project is to configure the Project Settings... and Application Settings....
In the Project Settings dialog you specify which platforms you target. Timpani will generate sound files for all checked platforms, so make sure you don't check more than you need or you will create a lot of unnecessary resources in the project.
The Application Settings specify the executables that will be used for compressing sounds. You can leave it at the default settings, but you should make sure that you have the programs installed.
For example, if you want to compress Vorbis sounds, you should install oggenc2.exe from http://www.rarewares.org/ogg-oggenc.php and make sure that it is in your path.
The next step is to import some wavs. Save your project, choose Project > Import Wav Files... and pick some files to import.
The import dialog gives you a preview of the wavs you are about to import. It also offers to automatically create sounds and events corresponding to the wavs, which is usually a good idea.
In Timpani parlance a wav is a piece of raw audio data. A sound is something that can be played. It can be a raw wav or something more complicated, such as a randomizer that randomly picks one wav from a set of alternatives. An event is something that can be triggered from the script and cause something to happen in the sound system. The most common case is that an event either stops or starts a particular sound.
Now we are almost ready to listen to the data, all we need to do is to export it. Choose Project > Export and save the file inside your project.
Note: You only need to explicitly Export once. In the future, Timpani will remember where you exported your data and automatically re-export to the same location when you want to Preview.
Now you can listen to one of your sounds by selecting it in the Sounds or Events folders and choosing Play > Play or pressing F5.
Attenuations are used to specify how sounds fade over distance. You can create as many attenuations as you need in the Attenuations folder.
A range of 50 m means that the sound will fade to zero amplitude over a distance of 50 meters. By default, the sound falls off linearly with distance. You can select different types of falloff using the dropdown menu. Select Custom to use a custom hand-drawn falloff curve.
Note: A sound that is played out of hearing distance will still consume a voice. The reason is that sounds and listeners may move during the duration of the sound so that it comes within hearing distance before it has finished playing.
To prevent far away sounds from being played, use the culling distance in the event interface. (TO BE IMPLEMENTED)
To specify which attenuation a sound should use, edit the Attenuation property in the sound's property window:
As with other sound properties, the attenuation setting is inherited through the hierarchy. So if you haven't set an attenuation for a sound, it will automatically use the attenuation of its parent, grand-parent, etc in the hierarchy.
Conversion Settings control how wavs will be compressed on different platforms. You can create as many different conversion settings as you need under the Conversion Settings folder:
In the conversion settings interface you specify, for each platform, what format, bit rate and sample frequency should be used for the wavs.
Note that all formats are not available on all platforms. For example, MP3 is only available on PS3, because the PS3 has a SPU-accelerated MP3 decompressor. Also, you can use MP3's without a license on the PS3. XMA is only available on X360.
The bitrate setting only applies to Vorbis and MP3 that can be compiled to target specific bit rates.
When selecting the compression format for your sounds, you have to strike a balance between quality, memory use and performance.
Uncompressed sounds have the best quality (same as the original file). As you compress them, some of the quality is lost. Among the compressed formats, Vorbis and MP3 sound better than XMA, which can introduce artifacts for certain sounds.
Uncompressed sounds use a lot of RAM. Compressing the sounds means that you can fit more wavs in the same amount of memory and achieve a greater degree of variation.
Uncompressed sounds do not require any extra processing power to play. XMA sounds are also nearly free, because they are decmpressed by custom hardware. MP3 is "almost free" on PS3, because usually you have enough spare SPU power lying around. In contrast, Vorbis is comparatively expensive. On PC, you typically do not have to worry that much, but on lower end platforms, decompressing many Vorbis streams can be expensive. Consider just compressing the files that are big and infrequently played (music, dialog), while leaving frequent sounds (guns, ricochets) uncompressed.
You specify which conversion settings a wav should use in the properties window for the wav:
Timpani doesn't use a fixed program for compressing audio. Instead, it lets you plug-in whatever external command-line sound compression tool you prefer. You specify what tools to use in the Application Settings dialog:
For the resample and bitrate parameters to work propertly, you must feed them to a conversion tool that is capable of handling them.
When you are exporting a big Timpani project for the first time, all the wavs in the project must be converted to the platform specific formats, which will take a significant amount of time. However, the converted files are cached in the Converted folder and subsequent exports run much faster.
Environments specify I3DL2 reverb properties for sounds. When you start a new Timpani project, it always includes the default I3DL2 reverb environments. If you want to, you can create your own environments with customized settings:
In the game, the environments are managed by the gameplay programmer. The gameplay programmer tells Timpani which environment to use in different parts of the game.
You can use the environment drop down menu in the Preview window to hear how different sounds sound in different environments.
You may want to create sounds that are not affected by the environment reverb. For example, it may sound silly if the menu beeps echo, just because the player is standing in a cave.
You can control how much Reverb a sound should get with the Reverb slider for the sound:
Drag the slider all the way to the left to disable reverb completely.
Just as pitch and volume, reverb settings accumulate through the hierarchy. So the actual reverb setting of a node in the tree is the sum of its reverb setting and the reverb settings of all its parents.
Events are signals triggered by the gameplay layer to affect the sound system. Typically, events are used to start and stop the playing of sounds:
An event is identified by its Name. This is what the gameplay programmer uses to trigger events.
At the start of a project, the sound designers should sit down with the gameplay programmers and decide what the sound events in the game should be and how they should be named.
As sound designer you have full control over what happens when an event is triggered. You define that as a list of Actions that should be performed.
The following actions are supported:
Plays the specified sound. For the Play action, you can specify the following options:
Specifies what should happen when a sound is played on a moving unit.
If you specify Move with object the sound source will follow the movement of the unit. This should be used for most sounds.
If you specify Stay at spawn position the sound source will stay at the position where the unit was when the sound was spawned. This might make sense for things such as gun shots. Since the gun shot noise comes from a single point in time, you don't expect it to move around, even if the player is running with the gun.
This option specifies what should happen if the unit that the sound is played on is destroyed. The two options are to either Do nothing or Stop the sound.
Stops the specified sound.
This action only works on Loop sounds. It tells the sound to exit the loop segment and play the fade-out sound.
Pauses the sound. Note that sounds that are paused still consume a voice (because they need to be able to start instantly). Thus, you should avoid having lots and lots of paused sounds.
Resumes a sound that was paused with Pause.
For actions other than Play to work, they must be triggered on the same object/unit that the original sound was played on. There may be multiple instances of the same sound (e.g., button_trigger ) simulatenously, and this is how Timpani knows which of them should be affected.
The At column allows you to delay some of the actions. Normally, the actions are performed instantly when the event is triggered. With At = 2, the action occurs 2 seconds after the event was triggered.
The Limit checkbox lets you limit the number of instances of the same sound that can be playing simultaneously. This can be used to save voices. For example, there is probably no reason to have 100 simulatenous ricochet sounds playing -- the player will not be able to hear them all anyway. By only playing the 4 ricochets closest to the player you save voices for more important sounds.
Buses are used to control the playback properties (pitch, volume, etc) of entire categories of sound, either statically (through Timpani sliders) or dynamically with script calls (for example, to allow the player to set music and sfx volume in the game's settings).
Each sound in Timpani belongs to one particular bus. Essentially, the buses work as the channels on a mixer board.
For each bus, you can specify its volume, pitch and the strength of reverb. The settings affect all sounds played on that bus.
The buses are ordered in an hierarchy and the settings for a parent affect all its children. So if the Master Bus has a volume setting of -10 dB and the sfx bus has a volume setting of -20 dB, sounds played on the sfx bus will be played with the volume -30 dB.
You specify which bus a sound should use in the properties window for the sound:
The bus setting is inherited through the sound hierarchy, so if you haven't specified a bus for a sound, its parent's sound will be used.
Sound banks are used to group sounds together for loading/unloading to memory.
A sound bank is a group of sounds that are loaded and unloaded together by the game. A sound can only be played if it exists in one of the sound banks that have been loaded by the game.
You are free to organize your sound banks however you want, but typically you would put the sounds that are used together in the same sound bank -- for example all the sounds corresponding to a particular enemy or a particular weapon. That way you can make sure that that sound bank is loaded whenever that enemy/weapon is used in the game.
You define the sound bank by adding Sound folders to it. The sound bank will contain all the sounds found in those folders.
To find out how much memory the sound bank will use on the different target platforms, press the Preview button:
Here you can see the compressed size of the sounds in the sound bank on each platform as well as the total size. Press the Play button to listen how each version of the sound sounds.
A Sound is something that can be played by an event. Sounds are arranged hierarchally in the Sounds folder. You can create your own folders under the Sounds folder to organize your sounds. Right click the Sounds folder to create new folders and sounds.
Sound mixer properties are inherited through the hierarchy. If you set the volume of the root Sounds folder to -10 dB, all sounds in the game will be played at -10 dB, in addition to whatever local volume modifications each sound makes.
You can take advantage of this and set properties on sound folders to avoid having to change the mixer properties for lots and lots of individual sounds. The mixer properties for a sound look like this:
Specifies the Bus that the sound should use.
Specifies the volume of the sound in dB. The volume has two parts, a static part and a random part (+/-).
The static part is a fixed volume modification. The random part is randomized every time the sound is played. If you have specified a volume of -10 (+/-) 5 dB, each time you play the sound, the volume will be a random value in the range -15 to -5 dB.
Note that volumes are added through the sound hierarchy. If a sound has -10 dB, its parent has -5 dB, and its grand parent has -20 dB, the total volume when the sound is played will be -35 dB.
Specifies the pitch of the sound in cents. Just as volume, the pitch has a static and random part and is inherited through the hierarchy.
Specifies the volume of the sound's reverb. A value of 0 dB means that the sound will be played with full reverb. If you drag the slider all the way to the left, reverb will be disabled for the sound. What the reverb sounds like depends on which Environment is being used.
Specifies which Attenuation curve the sound should use.
This parameter is used when multichannel sounds are played positioned. It specifies how far from where the sound is played each channel is positioned.
E.g., if you use a channel separation of 3.0, the left channel will be played 3.0 meters to the left of the sound source and the right channel 3.0 meters to the right of the sound source. The effect of this is that when you are far away (further than 3 meters), the sound will have a clear directionality (you will hear both channels coming from the right of you). However, as you get closer, you will get less and less directionality of the sound, and more and more of the stereo effect from the original recording, which gives you the feeling that you are "inside" the sound. So you can regard this as a measure of the "size" of the sound.
Note that the channel separation only affects the directionality of the sound. The attenuation is still computed as if all channels where playing at the location of the sound source.
Specifies how strong the directionality effect of positioned sounds are as a value in the range 0.0--1.0. A value of 0.0 means no directionality. The sound will play with equal volume in the L and R channels regardless of if it is to the left of you or to the right of you. A value of 1.0 means full directionality, meaning that a sound to the right of you, will play with zero volume in the L channel and full volume in the R channel. Values between 0 and 1 selects intermediate strengths for the effect.
For multichannel sounds, you can combine Channel Spearation and Panning Strength. For example, with a panning strength of 0.8 and a channel separation of 2 m, you will always have at least 20 % "stereo effect" in the sound, regardless of how far away you are (which gives a fullness to the sound). As you get closer to the sound and start to approach the 2 m range, the "stereo effect" will get stronger and stronger, giving you a greater feeling that you are "inside" the sound.
Curves can be used to convert values from input parameters to settings for volume and pitch.
Parameters are just named values that can be supplied by the game play programmer. For example the game play programmer may play a sword_hit event with a parameter of force = 0.5. As sound designer you can then create a curve that describes how that event should affect the volume or pitch of the sound.
Just as with events, the sound designers have to sit down together with the gameplay programmers and decide on what parameters there should be in the sound system and how they should be used. The gameplay programmer can supply multiple parameters when playing a sound, such as force = 0.5, angle = 0.7.
Timpani supports five different types of sounds: simple sounds, randomizers, silent sounds, switches and loops.
Simple sounds are sounds that just play a wav straight up:
Specifies whether the sound should loop or not.
The wav that this sound plays.
Randomizer sounds pick one of its children at random and plays that sound:
For each child of the randomizer you can specify a Weight. The weight is the likelyhood that that particular sound will be played. If one sound has a weight of 10 and the other sounds a weight of 1, the sound with weight 10 will be played 10 times as often as the other sounds.
Note that the sounds under the randomizer do not have to be simple sounds. You can put something more complex, such as a second randomizer, under the randomizer.
The randomizer has two modes:
Each time the sound is played, a random sound will be picked. Sometimes this can result in the same child being picked two times in a row.
As above, but the same child will never be picked two times in a row.
A silent sound is a sound that doesn't play anything. It doesn't consume any system resources.
The main use for silent sounds is as one of the options of a randomizer. If you want a randomizer that sometimes play a sound and sometimes does nothing, you can use a silent sound as one of its children.
Switch sounds are similar to randomizers in that they have a number of children and picks one of them to play. But unlike randomizers, switch sounds do not pick randomly, instead they pick which sound to play based on the parameters supplied by the gameplay programmer:
With a switch node, each sound is given a condition and the sound whose parameters matches the current parameter settings will be played. Parameters can be strings or numbers and you can compare them with >, <, =, !=, <= and >=. In addition, you can use and and or to form more complicated conditions.
material == "iron" force >= 100 material != "wood" and force >= 100 material == "iron" or material == "wood" and force >= 100
If several of the children have conditions that match the parameters, the child will be picked at random from the matching ones.
If a sound has an empty condition, it will be picked if no other conditions match.
In addition to the parameters supplied by the gameplay Timpani automatically generates a parameter that can be used for switching:
The distance from the sound source to the listener in meters when the sound is played.
You can use the distance parameter to setup switches that trigger different sounds based on how far away from the listener the sound is triggered.
Loop sounds can be used for looping sounds that need a lead-in when started and a lead-out when finished.
A typical example is a machine gun. You have a warm-up phase with one sound when the machine gun is spinning up. Then you have a continuous loop while the gun is shooting. And finally, when it stops shooting, you have a wind-down sound:
A loop sound has three child sounds corresponding to the warm-up, main loop and cool-down phases. (You don't have to specify all three sounds if you don't need all of them.)
The loop sound will automatically crossfade between the sounds when it transitions between the different stages in order to provide an overall smooth sound experience. There are two modes that can be used for fading:
In this mode it is assumed that there are no fades burnt into the wav files, so Timpani will crossfade by applying a volume fade to the sounds during the transitions. The fades are controlled by three values:
The time it takes to fade from the warm-up sound to the main loop sound. During this time, the warm-up sound will fade from amplitude 0.0 to amplitude 1.0 and the loop sound from 0.0 to 1.0.
The time over which one cycle of the loop will crossfade into the next one.
The time for crossfading between the main loop to the cool-down sound.
In this mode it is assumed that the fades are burnt into the wav files. I.e., that the wav files them selves have lead-in and cool-down sections.
When this mode is used, Timpani does not apply any volume fades to the sounds, because it assumes that those fades are already burnt into the wav files, except for in one particular case -- during the transition from the loop to the cool down sound. To enable that transition to occur at any point in the loop, and not just at the end of one loop iteration, Timpani needs to fade out by volume (since there is no burnt-in fade in the middle of the loop wav).
The overlap transitions are controlled by five parameters:
The amount of "outro" time burnt into the warm-up sound. Timpani will play the sounds so that this part overlaps with the main part of the loop sound.
The amount of "lead-in" time for the main loop sound. Timpani will start playing the lead-in so that when the previous sound enters its outro, the loop leaves the lead-in part and enters the main sound.
The amount of "outro" time burnt into the main loop sound.
The amount of "lead-in" burnt into the cool down sound. This will overlap with the main loop sound, when the loop is exited.
Controls the volume fade mentioned above -- how quickly the main loop sound will fade when we transition to the exit loop.
Note that if you Stop a loop sound it will stop immediately. The cool-down sound will not be played. To here the cool down sound you must use the action Exit loop instead of Stop on the loop sound.
Wavs are the raw sound files that have been imported into Timpani:
You can arrange your wavs in folders to keep better track of them.
The Conversion Settings specify the conversion settings that should be used for a wav. It is inherited by default, so you can specify the conversion settings on a folder to affect all the wavs in that folder.
To bring in new wavs use the Project > Import Wav Files... menu option, or right click on the wav folder you want to import wavs into. The Wavs you import end up in the Originals folder next to your Timpani project file. You should check this folder into source control.
Deleting a wav from the Wavs folder doesn't delete the file from the Originals folder on disk. To do that, you should run Project > Check Wavs.... That will give you a report of any unused or missing files in the Originals folder and give you the option of deleting them.
The In-game player allows you to preview your sounds on the target platform. Select a sound or an event in the tree view and press F5 to bring up the in-game player:
If you have set up your target in Tool Center to be a PS3 or an X360, the game will launch on the specified target hardware so that you can listen to your sounds on that platform.
The in-game player gives you a free flight camera (hold down space to rotate) that lets you fly around and listen to the sound from different locations. In addition it offers the following controls:
Lets you repeat the last sound played or stop it without going back to the main Timpani window.
Sets the source of the sound. You can choose between playing the sound as a 2D sound (without positioning), a stationary 3D sound or using one of several moving 3D source patterns.
Lets you choose the reverb environment to try out how the sound sounds with different reverb settings.
Lets you switch between the two listener types supported by the Bitsquid engine: a traditional first-person 3D listener and a 2D listener adapted for 2D games.
Soundscapes are Bitsquid's technique for filling levels with lots of sound sources.
To create an interesting sound environment you typically want to have a large amount of sound sources in a level. For example, you may want to have buzzing from light fixtures, roaring fires, babbling brooks, tweeting birds, etc. There may be 100s or 1000s of such sound sources in a level. If you played them all as looping sounds you would quickly run out of voices.
The solution is soundscapes. Soundscapes allow you to place lots of sound sources in the level editor (or from the script). These sounds will start playing when the player gets close enough and stop playing when she moves away from the sound source. Thus, even though there are a lot of sound sources in the level, only a few voices are consumed.
See the level designer section of this document for more information on how to create soundscapes.
Multichannel audio deals with the problem of how to map an input file with n sound channels to a speaker configuration with m speakers.
In Timpani a sound can be played in two different ways:
are played at a specific 3D position in the game world. This gives rise to two effects:
The volume of the sound is affected by the distance between the sound and the listener.
The different speakers play the sound at different volumes, based on the direction from the listener to the sound. This effect is sometines called ILD (interaural level difference).
are played without a 3D position. They don't get distance attenuated or direction panned.
Positioned multichannel sounds are played using channel separation. What this means is that each channel of the sound is extracted and positioned separately in the 3D space. The right channel is positioned slightly further towards the listeners right ear, the left channel towards the listeners left ear, etc.
This means that when the listener is far away from the source, she will here it coming from a particular point in space. If that point is to her right, she will hear both channels in the right ear. As she get closer she will hear more and more of the stereo effect. When she stands at the location of the source, she will hear the right channel in the right ear and the left channel in the left ear.
For unpositioned sounds what happens depends on the number of input channels:
The sound is played with the same volume on all speakers.
The sound is played with full amplitude (0 dB) on the front speakers (left channel to FRONT LEFT, right channel to FRONT RIGHT) and slightly lower (-6 dB) on side and back speakers (SIDE LEFT, SIDE RIGHT, BACK LEFT, BACK RIGHT) -- if they exist.
If the player's speaker system has the same number of channels as the audio file, there will be a 1:1 mapping between the input channels and the output channels.
If the player's speaker system has more channels than the input, the extra channels will be silent.
If the player's speaker system has fewer channels than the input, Timpani attempts to intelligently downmix the input sound to the speaker system. For example, if the player is listening on head phones, all left sound channels will be mixed to the left headphone, all right channels will be mixed to the right headphone and all center channels will be equally mixed to the two headphones.
In the future we plan to offer even greater control over how a sound is mixed to different channels -- for example to make it possible to specify that a sound should be played on a particular speaker.
As a sound designer, keeping track of the amount of memory used by the sound system is important.
Timpani uses both static and dynamic memory. The static memory is the data used by the sound resources themselves (compressed wavs). The dynamic memory is temporary memory that Timpani uses while playing sounds. The static memory is usually a lot larger than the dynamic memory, so for memory optimizations, you should focus on the static memory.
The static memory use is determined by the size of the currently loaded set of sound banks. You can examine the size of a soundbank by using the Preview... button in the Soundbank Properties window:
Here you can see the size of the sound bank on every platform (120 K) and also the memory used by each individual sound on the different platforms.
Note: Timpani does not yet support disk streaming of playing sounds. All sounds in the sound bank are always fully loaded in memory. We plan to add disk streaming support.
Note that if the same source file appears in two different sound banks and both those sound banks are loaded, the sound will be loaded twice, so try to avoid such situations.
In-game you can use the Audio Perfhud to see how much memory the sound system is using. Type:
in the console to activate the audio perfhud.
Timpani banks shows how much memory is used by the Timpani sound banks and Timpani master how much memory is used by the timpani master file.
The two main strategies to reducing sound memory usage are:
Use fewer/shorter sounds
In addition to raw PCM data, Timpani supports three compression formats:
Ogg Vorbis based compression. This is recommended on PC. On consoles, the Vorbis decompressor can consume a lot of CPU. Therefore, you should only use it in a few select places (such as for your music files).
MP3 compression. MP3 compression is only supported (and recommended) on PS3. Sony has a special deal that allows MP3s to be used royalty-free on PS3. Also there is an efficient SPU-decompression library.
Only supported (and recommended) on X360. The X360 has fast hardware support for decompressing XMA files, so they can be used without any CPU cost.
You specify which compression format you want to use in the Conversion Settings for the sound.
As a level/game designer you will typically interact with Timpani in two ways:
Trigger Timpani events from Flow
Placing sounds in a level (using soundscapes)
Tells the engine that this Flow chart needs a particular sound bank to be noded. If you include a Timpani Bank node in your Flow chart, that bank will be automtaically be loaded when the level or unit that owns the flow is loaded.
Typically you would add Timpani Bank nodes for all the sounds used in your flow chart. If you have forgotten to add a timpani bank (and the bank hasn't been loaded in some other way, for example by the script) you will get an error when you try to play the sound.
(The reason why you have to specify which banks to load is that the same sound may exist in several different banks, so just specifying which sounds to play doesn't give the engine enough information to know which banks to load.)
Triggers the Timpani event with the specified name. This is what you would use to play sounds from Flow.
Specifies the unit that the sound should be played on.
If specified -- the sound will be played on the object with this name in the unit.
If you want to play the sound at a fixed position in the world instead of on a unit, you can use this parameter.
The event Trigger triggers the event and Stop forces the sound to stop if it is playing. The Event Id can be connected to other nodes to affect the playing sound.
Sets a numeric parameter on the sound. You specify the name of the parameter and the value you want to set it to.
Sets a string parameter on the sound.
Soundscapes refer to sounds placed in the level editor. Such sounds will start playing as soon as the player gets near them and stop playing when the player move away. Just as with other level editor objects, you pick what sound to spawn using the Scenery Browser and spawn it with the Place tool:
Placed sounds are represented by a sound source icon in the level editor.
Sound sources can be given a shape that is either a box or a sphere. If a sound source is given the shape of a box, the sound will be audible throughout that entire box. For example, you can use a box to play a cricket sound over an entire field.
The Properties window lets you configure the shape of the sound source and where in the shape the sound should be played.
Specifies the shape of the sound volume for the source (a Sphere or a Box).
Specifies the size of the shape with three values. For a Sphere, all three values should be the same and specify the radius of the sphere. For a Box the values specify its half-extent along the x-, y- and z- axes. The level editor window shows the shape of the sound source when it is selected.
Specifies the distance at which the sound should start playing. A value of 50 means that if the listener gets within 50 meters of the shape, the sound will start playing. Typically the range should match the attenuation range of the sound, so that the sound starts playing as soon as it would be audible to the player. But sometimes it makes sense to have a range of 0, so that the player only hears the sound when she is inside its shape.
Specifies where in the shape the sound source should be positioned. The possible values are:
The sound source will be moved so that it is always as close to the listener as possible. This is useful for sounds that should emenate from the entire volume, e.g. things like a babbling brook. You always want the sound to be played at the point in the brook that is closest to the player, not at some distant point, so that it sounds like the entire brook gives off sound.
The sound source will be positioned at a random point in the shape. You might want to use this for "splash" sounds in the brook, since they should occur at random locations in the brook (triggered by fish).
The sound will be positioned at a random point around the listener. This is useful for sounds that shouldn't come from any particular location, such as traffic noise or bird tweets.
The sound will not be positioned, but instead play as a 2D sound.
Specifies the minimum and maximum distance form the listener where the sound can appear.
In Closest to listener mode, the sound will never be placed closer to the listener than the specified minimum distance.
In Random around listener mode, the sound will be placed at a random distance from the player, between the min and max values specified.
In the other modes, this parameter is ignored.
For non-looping environment sounds, this parameter specifies how long from a sound has finished playing it can start playing again. The value is randomized between the mean and max values. A value of 5--20 means Timpani will wait between 5 to 20 seconds until it will play the sound again.
To use Timpani you must specify the path to the *.timpani_master file that you want to use in your settings.ini file.
In settings.ini add a line like this:
timpani = "timpani/test"
Timpani will look for a file called timpani/test.timpani_master during the boot process of the game and use that file to initialize the timpani system.
You should also make sure that the master file is added to your boot resource package so that it gets loaded during boot. I.e., in your boot resource package you should have a line like:
timpani_master = [ "timpani/test" ]
If you haven't specified a timpani_master file in settings.ini, no Timpani sounds will be played.
To be able to play Timpani sounds you must also load one or more sound banks. The easiest way of doing that is through Flow. Place a Timpani Bank node in a level's or a unit's flow and the timpani bank you specify will be loaded together with the level/unit. You can also hard code the paths to sound banks in your resource packages.
When you call Application.new_world() you can decide whether sounds should be enabled for that world or not. The sound system doesn't consume much resources when no sounds are playing, but it is still usually a good idea to disable sound for the worlds where you don't intend to use it.
To play sounds from the script, use one of the trigger_event functions
local id = TimpaniWorld.trigger_event(tw, unit, "button_trigger")
You get access to the Timpani world with:
local tw = World.timpani_world(self.world)
To affect a playing sound, use functions such as:
TimpaniWorld.stop(tw, id) TimpaniWorld.set_parameter(tw, id, "material", "iron") TimpaniWorld.set_parameter(tw, id, "strength", 0.5)
In order to hear sounds correctly, you must move the listener in Timpani:
local tm = self:player_pose() TimpaniWorld.set_listener(tw, 0, tm)
If you don't move the listener from the script, it will remain in (0, 0, 0), and you will only hear the sounds close to origo, regardless of where the camera is.
For first person games, you typically want to orient the listener to match the camera's orientation.
For third person games, you have to decide if you want to put the listener where the camera is, where the player is or some combination thereof (for example, you may want to use the player's position, but the camera's rotation).
For 2D games, traditional 3D listeners don't work very well. What you want when playing a 2D game is typically to hear sounds that are played in the left area of the screen in the left speaker and sounds in the right area of the screen in the right speaker. But there is no place in the world where you can put the listener to achieve this effect.
For this reason, Timpani has a special 2D listener mode. When using this mode, you should position the listener at the position in the 3D world that corresponds to the screen center and orient it so that the x-axis points towards the right screen edge and the y-axis towards the top screen edge. Furthermore, you should set the size of the listener so that it corresponds to the size of the viewport in the 3D world.
See core/editor_slave/timpani_player.lua and core/editor_slave/topdown.lua for an example.
TimpaniWorld.set_listener(tw, 0, tm) TimpaniWorld.set_listener_size(tw, 0, size)
Note: The Timpani API is prepared for having more than one listener, but currently only one listener is supported. Multiple listeners are used for split-screen games, where you have multiple players in the 3D world and want the speakers to play a mix of what each player would hear.
If you plan to make a split-screen game, talk to us about getting multiple listener support scheduled in the roadmap.
Bus volumes can be used to implement volume settings for music and sfx, or to achieve special effects. For example, you may want to simulate temporary deafness from an explosion by lowering all in-game sounds. Similarily, you could simulate dizzyness or an underwater effect by playing with pitch.
The reverb environment is set from script with:
Note: Even though the environment is set on the timpani world, the effect is in fact global and affects all sound worlds. We currently don't support having separate reverb environments for each in-game world. The reason is that most platform backends only support a single reverb environment. This may change in the future.
The level editor boot script must make sure to preload the level resources. This preload brings in the sound banks which makes it possible for timpani to bring in the sounds. The level editor boot script should contain the following line:
Also, make sure your test.ini file points to a timpani master file:
timpani = "timpani/test"