![](/user_photo/_userpic.png)
3D Game Programming All In One (2004)
.pdf![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI581x1.jpg)
548 Chapter 19 ■ Creating and Programming Sound
Table 19.8 Project Menu
Menu Item |
Description |
Import Audio |
Imports audio into your project. Use this function to add another track to a |
|
project with at least one existing track. You can also mix the imported track |
|
with an existing track. |
Import Labels |
Imports a text file that contains time codes and labels, turning them |
|
collectively into a label track. |
Import MIDI |
Imports a MIDI file into a note track. MIDI files can be viewed but not |
|
played, edited, or saved. |
Import Raw Data |
Allows you to open a file in virtually any uncompressed format. Audacity |
|
will examine the file contents to determine their format. You will need to |
|
listen to the result in order to decide if the program made the right format |
|
choice. You can use the dialog box the function displays to direct the |
|
program in its attempts. Sometimes a successful operation has a bit of noise |
|
at the beginning, caused by the unrecognized header format. The rest of the |
|
data usually plays correctly. You can then edit out the noise. |
Edit ID3 Tags |
Opens a dialog box allowing you to edit the ID3 tags associated with a |
|
project. These are used for MP3 exporting. |
Quick Mix |
Mixes selected tracks down to one or two tracks. Note that if you try to mix |
|
two loud tracks together, you may get clipping that sounds like pops, clicks, |
|
and noise. To avoid this, you should first adjust the gain (amplification) of |
|
the tracks to a lower level. |
Align Tracks Together |
Adjusts the time offset of selected multiple tracks to make them start at the |
|
same time. The starting time is adjusted to the average of all tracks' original |
|
starting times. |
Align with Zero |
Resets the time offset of elected multiple tracks to zero. |
New Audio Track |
Creates a new audio track with no data. |
New Label Track |
Creates a new label track. |
Remove Track(s) |
Removes the selected track or tracks from the project. You only need to |
|
select a portion of a track for it to be removed. |
Add Label At Selection |
Creates a new label at the current selection. |
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI582x1.jpg)
Audacity |
549 |
|
Table 19.9 |
Effect Menu |
|
|
Menu Item |
Description |
|
|
Amplify |
Increases or decreases the volume of a track or set of tracks. Audacity computes |
|
|
|
for you the maximum amount you could amplify the selected audio without being |
|
|
|
so loud that the signal is clipped. |
|
|
BassBoost |
Amplifies the lower frequencies yet leaves most of the other frequencies |
|
|
|
untouched. Recommended maximum boost is 12 dB. |
|
|
Echo |
Repeats the audio you have selected again and again, softer each time. There is a |
|
|
|
fixed time delay between each repeat. |
|
|
Fade In |
A linear fade-in to the selected audio data. |
|
|
Fade Out |
A linear fade-out to the selected audio. |
|
|
FFT Filter |
Applies a Fast Fourier Transform. The FFT Filter dialog is not properly finished, but |
|
|
|
the function works properly. |
|
|
Invert |
Flips the audio samples upside down. |
|
|
Noise Removal |
Removes constant background noise, such as fans, tape noise, or hums. Does not |
|
|
|
work well for removing background speech or music. |
|
|
Phaser |
Combines phase-shifted signals with the original signal. |
|
|
Reverse |
Reverses the selected audio temporarily; after the effect the end of the audio will |
|
|
|
be heard first and the beginning last. Useful for listening to old Beatles music! |
|
|
Wahwah |
Give us a little wah-wah, George! Uses a moving bandpass filter to create the |
|
|
|
famous wah-wah sound. This function also adjusts the phase of the left and right |
|
|
|
channels of a stereo recording, to make the effect travel between the speakers. |
|
|
Freeverb2 |
Provides sliders to adjust reverb effects. Experiment with the sliders to achieve |
|
|
|
some interesting reverberating sounds. |
|
|
|
|
|
Many Menu items can be invoked by the use of the standard Windows accelerator key combinations, such as Ctrl+W to close a window. Table 19.10 lists the shortcut keys.
n o t e
The version of Audacity used here is version 1.0, which is a stable release but does lack a few features, the most notable of which is the ability to resample audio files.
You may be interested in version 1.2, which was released after this chapter was written. It includes many of the features missing from version 1.0. You can download Audacity 1.2 at http://audacity.sourceforge.net/.
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI583x1.jpg)
550 Chapter 19 ■ Creating and Programming Sound
Table 19.10 Shortcut Keys
Menu Item |
Shortcut |
File, New |
Ctrl+N |
File, Open |
Ctrl+O |
File, Close |
Ctrl+W |
File, Save Project |
Ctrl+S |
File, Preferences |
Ctrl+P |
Edit, Undo |
Ctrl+Z |
Edit, Redo |
Ctrl+R |
Edit, Cut |
Ctrl+X |
Edit, Copy |
Ctrl+C |
Edit, Paste |
Ctrl+V |
Edit, Delete |
Ctrl+K |
Edit, Silence |
Ctrl+L |
Edit, Split |
Ctrl+Y |
Edit, Duplicate |
Ctrl+D |
Edit, Select All |
Ctrl+A |
View, Zoom In |
Ctrl+1 |
View, Zoom Normal |
Ctrl+2 |
View, Zoom Out |
Ctrl+3 |
View, Fit in Window |
Ctrl+F |
View, Plot Spectrum |
Ctrl+U |
Project, Import Audio |
Ctrl+I |
Project, Add Label at Selection |
Ctrl+B |
OpenAL
Torque, along with many other game engines, uses OpenAL—an open-source audio API (Application Programmer's Interface). In this book we won't be directly addressing programming with OpenAL, but we do need to ensure that OpenAL is installed with the correct version. The Torque installation procedure you followed in an earlier chapter will have taken care of that for you. In your root main directory, make sure that the file OpenAL32.dll is there. If it isn't, you will need to reinstall Torque. If you use the stock Options menu in the Torque demo games, then make sure you enable the OpenAL interface there.
Audio Profiles and Datablocks
Torque uses the concept of datablocks and profiles to help define and organize resources for use in the game. We encountered this concept when building our Emaga sample games in earlier chapters.
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI584x1.jpg)
Audio Profiles and Datablocks |
551 |
There are essentially two ways to make sounds occur in a Torque game. We can directly activate a sound (or music, for that matter) with program code, or we can attach sounds to in-game objects and let the Torque Engine activate and control the sounds indirectly on our behalf.
Most of the time we will use the latter—indirect—approach because once the relationship of sound-effects file to object has been defined in the right place, we don't need to worry about it anymore.
However, the first approach—direct activation—is more flexible. We'll look at both approaches in the remainder of this chapter.
Audio Descriptions
Audio datablocks are used no matter whether we directly or indirectly activate sounds. Audio datablocks are defined using the keyword AudioDescription when they are defined. Here is an example of an audio datablock:
new AudioDescription(AudioTest)
{
volume = 1.0;
isLooping= false;
is3D |
= |
false; |
type |
= |
0; |
};
In this example, AudioTest is the handle to this description.
The volume property indicates the default volume for this channel. This property is itself not changeable, but when the audio channel is used, the volume can be changed via script statements.
The property isLooping indicates whether to repeat the sound after it has finished playing.
The is3D property is used to tell Torque whether this channel needs to be processed to produce positional information.
The type property is essentially the channel for this sound. All sounds on a given channel can be controlled via script statements that are channel specific.
With this datablock we have defined the nature of the AudioTest sound, so to speak—its characteristics. However, there's obviously not enough here to actually produce any sound. We need at least a sound file with a sample waveform in it, and then we need to associate that file with the appropriate AudioDescription. This is how we do it programmatically:
$Test = alxCreateSource("AudioTest",expandFilename("~/data/sound/test.wav"));
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI585x1.jpg)
552Chapter 19 ■ Creating and Programming Sound
This statement creates an audio object. The first parameter is the datablock we saw earlier. The second parameter first invokes a call to the expandFilename function, which knows how to make sure it finds the correct full path of the file. The return value is a handle to the actual audio object created by Torque.
Now to activate the sound, we simply call the following:
alxPlay ($Test);
As you see, we just needed to tell alxPlay the name of the object, and away it goes.
We can adjust the volume for this playback, but we need to do it before we play the sound. We do that this way:
alxListenerf(AL_GAIN_LINEAR, %volume);
$Test = alxCreateSource("AudioTest",expandFilename("~/data/sound/test.wav")); alxPlay ($Test);
The alxListenerf function sets the volume for the listener (the player) and does it using a linear (versus logarithmic) gain (amplification) adjustment. With a linear gain, a volume of 0.5 is half as loud as a volume of 1.0. With the nonlinear (logarithmic) gain, a volume of 0.5 is about two-thirds as loud as a volume of 1.0.
Note that this volume adjustment is performed on the value of the volume in the datablock, where the volume was set to 1.0.
So if we call alxListenerf with a volume of 0.75, then the actual volume would be 0.75 multiplied by 1.0, or 0.75—and all loudness calculations would follow from that. If we call alxListenerf with a volume of 0.75, and if the datablock's volume had been set to 0.5, then the actual volume would be 0.75 multiplied by 0.5, or 0.375.
Now using alxPlay this way is useful for sounds that have no positional information requirements, like GUI button beeps or the sound of a player's throbbing headache. But what if we want to place the sound in the game world?
In this case, we need to first create a profile:
new AudioProfile(AudioTestProfile)
{
filename = "~/data/sound/test.wav"; description = "AudioTest";
};
Notice that now the file name is contained in the profile. The second property, description, points to the datablock we defined earlier. We then activate the sound as follows:
alxPlay(AudioTestProfile, 100, 100, 100);
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI586x1.jpg)
Audio Profiles and Datablocks |
553 |
Notice now that the function call refers to the profile, not the description datablock. The three parameters that follow define a location in 3D coordinates in the game world. The sound, when played, will seem to come from that location. It's important to understand that when activating sounds in this manner, you must ensure that the sound file contains a monophonic sound, and not stereo. Also, the is3D property in the datablock must be set to false.
t i p
Take note of whether you are creating the AudioDescription or AudioProfile on the client or the server.
On the client, you define it this way:
new AudioDescription(AudioTest)
{
};
and
new AudioProfile(AudioTestProfile)
{
}
If the code resides on the server, do it this way:
datablock AudioDescription(AudioTest)
{
};
and
datablock AudioProfile(AudioTestProfile)
{
}
In point of fact, this rule applies for all datablock types, because the server can only define true datablocks.
Trying It Out
Let's try it out, using your Emaga6 sample game. Open up your root main file (main.cs) and add the following lines to the very top:
new AudioDescription(AudioTest)
{
volume = 1.0;
isLooping= false;
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI587x1.jpg)
554 Chapter 19 ■ Creating and Programming Sound
is3D |
= |
false; |
type |
= |
0; |
};
new AudioProfile(AudioTestProfile)
{
filename = "~/data/sound/test.wav"; description = "AudioTest";
preload = true;
};
function AudioTestA(%volume)
{
echo("AudioTest volume="@%volume); alxListenerf(AL_GAIN_LINEAR, %volume); $pref::Audio::masterVolume = %volume;
$AudioTestHandleA = alxCreateSource("AudioTest", expandFilename("~/data/sound/test.wav"));
echo("AudioTest object="@$AudioTestHandleA); alxPlay($AudioTestHandleA);
}
function AudioTestB(%volume)
{
echo("AudioTest volume="@%volume); alxListenerf(AL_GAIN_LINEAR, %volume); $pref::Audio::masterVolume = %volume; alxPlay(AudioTestProfile, 100, 100, 100);
}
Now launch your game. After you've spawned in, open the console window (using the Tilde key) and type in the following:
AudioTestA(1.0);
You should hear the "electronic drip" test sound. Play with the volume setting, trying different values less than 1.0.
Next type this into the console window:
AudioTestB(1.0);
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI588x1.jpg)
Koob 555
You should hear the electronic drip test sound again, but this time seeming to come from a specific direction.
Again, play with the volume setting, trying different values less than 1.0. You can also play with the 3D coordinate values in the call to alxPlay() in the AudioTestB() function.
Koob
In the following chapter, and in later chapters, we will be using audio features a great deal more, so take the time in the balance of this chapter to add some more files to your sample program.
First, copy your Emaga6 directory and name the copy "koob". Or use any other name— but I'll be using koob.
Now create a new directory: C:\koob\control\data\sound. Record a sound, any sound, in a WAV file. Make sure that the file is not a stereo file. Copy your new sound file into C:\koob\control\data\sound and name it "test.wav".
Next create a new script file: C:\koob\control\client\misc\sndprofiles.cs. Insert the following lines of code:
// Channel assignments (channel 0 is unused in-game).
$GuiAudioType |
= 1; |
$SimAudioType |
= 2; |
$MessageAudioType = 3; |
new AudioDescription(AudioGui)
{ |
|
volume |
= 1.0; |
isLooping= false; |
|
is3D |
= false; |
type |
= $GuiAudioType; |
}; |
|
new AudioDescription(AudioMessage)
{ |
|
volume |
= 1.0; |
isLooping= false; |
|
is3D |
= false; |
type |
= $MessageAudioType; |
}; |
|
new AudioProfile(AudioButtonOver)
{
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI589x1.jpg)
556 Chapter 19 ■ Creating and Programming Sound
filename = "~/data/sound/buttonOver.wav";
description = "AudioGui";
preload = true;
};
This sets up some datablocks and a profile for use on our client.
Next create a new script file: C:\koob\control\server\misc\sndprofiles.cs. Insert the following lines of code:
datablock AudioDescription(AudioDefault3d)
{
volume |
= 1.0; |
isLooping= false; |
|
is3D |
= true; |
ReferenceDistance= 20.0; |
|
MaxDistance= 100.0; |
|
type |
= $SimAudioType; |
}; |
|
datablock AudioDescription(AudioClose3d)
{ |
|
volume |
= 1.0; |
isLooping= false; |
|
is3D |
= true; |
ReferenceDistance= 10.0;
MaxDistance= 60.0;
type |
= $SimAudioType; |
}; |
|
datablock AudioDescription(AudioClosest3d)
{
volume = 1.0;
isLooping= false;
is3D = true;
ReferenceDistance= 5.0;
MaxDistance= 30.0;
type |
= $SimAudioType; |
}; |
|
// Looping sounds
datablock AudioDescription(AudioDefaultLooping3d)
{
volume = 1.0;
Team LRN
![](/html/611/317/html_sHJTiqw2WZ.3we_/htmlconvd-st7iTI590x1.jpg)
Koob 557
isLooping= true;
is3D |
= |
true; |
ReferenceDistance= 20.0; |
||
MaxDistance= 100.0; |
||
type |
= |
$SimAudioType; |
};
datablock AudioDescription(AudioCloseLooping3d)
{
volume |
= 1.0; |
isLooping= true; |
|
is3D |
= true; |
ReferenceDistance= 10.0; |
|
MaxDistance= 50.0; |
|
type |
= $SimAudioType; |
};
datablock AudioDescription(AudioClosestLooping3d)
{
volume = 1.0;
isLooping= true;
is3D = true;
ReferenceDistance= 5.0;
MaxDistance= 30.0;
type = $SimAudioType;
};
// Used for non-looping environmental sounds (like power on, power off) datablock AudioDescription(Audio2D)
{
volume = 1.0; isLooping = false; is3D = false;
type = $SimAudioType;
};
datablock AudioDescription(AudioLooping2D)
{
Team LRN