Skip to content

Audio Guide

Peter Robinson edited this page Jun 1, 2020 · 1 revision

Introduction

In Torque2D audio is handled by OpenAL. To use an audio file you have to first create an Audio Asset which is explain in a different section of the wiki. There are a number of global audio functions that allow you to completely control OpenAL. However, the average user will probably only need the most basic functions to start and stop an audio file.

Basic Usage

Once you’ve created an Audio Asset, playing the asset takes a single function call.

%music = alxPlay(“MyMod:ActionMusic”);

This example would start the audio asset called ActionMusic which was loaded in MyMod. The return value is a handle that we can use to call additional functions that will have an impact on the audio. If the handle is 0 then something went wrong.

We can stop the audio file by using the handle in the stop function.

alxStop(%music);

If you’d rather stop all audio or you don’t have the needed handle you can use the stop all function.

alxStopAll();

If you only want to temporarily stop the audio and then resume it again at the same place you can use the pause and unpause functions.

alxPause(%music);
alxUnpause(%music);

Finally, you can determine if an audio file is playing.

alxIsPlaying(%music);

This will return 1 if the audio is playing and 0 if the audio is not playing.

Channels

Understanding how channels work is a major part of using audio. If you’ve done much with audio this is probably worth skipping, but if you’re completely new at working with audio then there are some basic things here that you’ll want to understand.

First, channels control volume. There are 32 channels in total (0 – 31) and each has its own volume. Creating as audio asset with a channel and a volume will set the volume on that channel. This will affect the volume of all audio files that play on that channel. So if two audio assets have the same channel and competing volumes then one of the assets will win out and both assets will play at the same volume.

Next, you can change the volume of a channel directly, which might prove to be less confusing and avoid problems. You can get or set the volume of a channel like so.

alxSetChannelVolume(0, 0.7);
%volume = alxGetChannelVolume(1);

A simple and common setup would be to use one channel for music and another for sound effects. Your game can then allow the player to control these two volumes separately.

Sound API

The following is a list of the most useful audio functions with descriptions.

alxPlay(audioAssetID)

Plays the audio asset and returns a handle or 0 on error.

alxIsPlaying(handle)

Returns true if the sound given by the handle is playing and false if not.

alxStop(handle)

Stops the currently playing sound that is given by the handle.

alxStopAll()

Stops all currently playing sounds.

alxPause(handle)

Pauses the currently playing sound that is given by the handle.

alxUnpause(handle)

Resumes the paused sound that is given by the handle.

alxGetAudioLength(audioAssetID)

Returns the length of the audio asset in milliseconds.

alxGetStreamDuration(handle)

Returns the length in seconds of the sound given by the handle or -1 on error.

alxGetStreamPosition(handle)

Returns a value between 0 and 1 that represents the percent of the audio that has been played for the sound given by the handle or -1 on error.

alxGetChannelVolume(channelID)

Returns a value between 0 and 1 that represents the volume for the given channel.

alxSetChannelVolume(channelID, volume)

Sets the volume for the given channel to a volume between 0 and 1.

OpenALInitDriver()

Initializes the OpenAL driver and returns true on success.

OpenALShutdownDriver()

Closes the OpenAL driver. No sound functions can be called until it is initialized again.

Advanced API

These additional functions give more control over the audio environment, allowing you to control things like reverb and implement 3D sound (or 2D in this case). Their use is beyond the scope of this guide but they’re listed here for completeness.

  • alGetListener3f(ALEnum)
  • alGetListeneri(ALEnum)
  • alGetString(ALEnum)
  • alListener3f(ALEnum, x, y, z)
  • alxCreateSource(audioAssetID)
  • alxGetListenerf(ALEnum)
  • alxGetSource3f(handle, ALEnum)
  • alxGetSourcef(handle, ALEnum)
  • alxGetSourcei(handle, ALEnum)
  • alxGetListenerf(ALEnum, value)
  • alxSource3f(handle, ALEnum, x, y, z)
  • alxSourcef(handle, ALEnum, value)
  • alxSourcei(handle, ALEnum, value)

Positional Audio

Positional Audio allows the engine to change the sound based on the position of the object making the sound relative to the camera. As you might expect, this allows for some very cool effects and can add a deeper level of immersion into a game.

The Audio Listener

The first step to using Positional Audio is to set one of your scene windows as the listener.

MySceneWindow.setAudioListener(true);

You'll have to manually enable this functionality in script. Having more than one scene window be the active listener in script will cause unpredictable behavior as they both try to update the position of the listener. Ensure that only one window is the listener. Zooming is also ignored by Positional Audio.

Playing a Sound

To play a sound directly at the position of any object, simply call playSound on that object and pass in the name of the AudioAsset.

MySceneObject.playSound("ToyAssets:SuperCoolSoundAssetID");

This will play the sound and dispose of it when complete. To create a looping sound, an AudioDescription will need to be passed in as a second parameter. An AudioDescription is a special object that gives various additional information about a sound. Here is an example AudioDescription:

new AudioDescription(MY_ADESC) {
    is3D = true;
    isLooping = true;
    ReferenceDistance = 25.0;
    MaxDistance = 100.0;
};

Audio Debug Mode

You can see a simple visualization mode for audio sources played using Positional Audio:

MyScene.setDebugOn("audio");

The debug only illustrates the MaxDistance and ReferenceDistance as circles and might help determine why a sound is not working as expected.

Additional Notes on Usage

Off Screen Sounds

OpenAL automatically performs automatic culling of sounds which should not be heard. If a non-looping sound is started outside of the listener's range, it will not be created. You can easily circumvent this by having an AudioDescription with a larger MaxDistance.

Multiple Sounds

By default, the OpenAL implementation will detect how many audio sources can be played at the same time. The default is 16 but this depends on the audio hardware.

Also, loading all sounds at once will cause framerate stutters, even if they are preloaded. One way to solve this is by spreading out the creation code for your objects by 20-50 milliseconds by using scheduling functions. You might also consider using a non-animated loading screen.

Having multiple sounds at maximum volume (1.0) directly in front of the listener will cause distortion.

Stereo and Mono

Positional Audio sounds should by monophonic. Never try to pan stereo sounds as doing so can cause glitches and may damage audio equipment. Sounds that are played with the regular Audio API are free to be Stereo sounds. Plan ahead.

Positional Audio API

These functions are members of the SceneObject class that are used with Positional Audio.

PlaySound(AudioAssetID, AudioDescription)

Plays a sound at the sceneObject's position. The AudioDescription is optional. A default AudioDescription will be used if one is not supplied. The new sound will change it's position with the object.

StopSound(SoundIndex)

Takes the zero-based sound index of a sound playing at this object's position and stops the sound.

GetSoundCount()

Returns the number of sounds playing at this object's position.

GetSoundatIndex(SoundIndex)

Returns a handle to the sound specified by the SoundIndex. The handle can then be used to perferom any OpenAL operation on it.

Clone this wiki locally