TorqueGameEngineAdvanced/1 8 Beta/SFX/Overview

From TDN

This page is a Work In Progress.

Contents

Introduction

SFX is the new 2D and 3D audio system for Torque. It was designed to provide the basic features for sound playback across multiple platforms, sound devices, and audio libraries.

This is only a brief overview of how the system works and provides a starting point for further study.

Providers

The SFXProvider is the abstraction for the low level sound system which will vary on different platforms. There is only one active provider at any time and it is used to create an instance of the SFXDevice.

There are currently a few different providers available:

DirectSound

The DirectSound API is the original DirectX audio playback and recording library for Microsoft Windows. While it supports hardware acceleration of sound mixing it was plagued by bad driver support. Microsoft is no longer extending DirectSound and it should be avoided in future projects.

XAudio

The XAudio provider is exclusive to Microsoft Windows and XBox and is the replacement for DirectSound. It is a pure software mixer which makes it more reliable and consistent in performance. It is recommended as the standard SFX provider on Microsoft platforms.

OpenAL

The Open Audio Library sound provider for SFX is cross platform and supported on Windows, OSX, and various open source operating systems.

FMOD

The FMOD audio library is a commercial product which itself abstracts various audio APIs and platforms. In this respect it is a redundancy with functionality already in SFX, but it also supports some higher level features and improvements which you could potentially tap into for your specific game.

At this time the FMOD provider works with both Windows and OSX and is licensed separately from Torque.

Null

The null provider acts like a normal sound provider, but it does not playback any audio. Its only provided for testing and debugging.

Devices

Each provider in SFX will have one or more output devices. The devices usually match audio outputs on the platform like multiple sound cards, specific physical audio jacks, and sometimes different APIs. In general the first returned device from the provider is the appropriate default device for that platform.

The SFXDevice itself is the one that creates and manages the playback of sound sources.

While it is not exposed a sound listener is created within the SFXDevice for playback of positional 3D audio. At the time of this writing Torque does not support multiple listeners.

Sources

A source in SFX is a controller for playback of audio. You can create a source instance via C++ and/or TorqueScript and use it to manage playback and sound properties such as spacial positioning, velocity, cone settings, volume, and pitch.

All SFXSources are virtual in that you may have many more sources created and playing then the amount of resources you have available for playback. The sources are sorted based on their relative volumes and playback start time to ensure that louder more recent sources take priority.

The SFXSource exist outside of the provider/device system so that switching from one to another will not cause sources to be destroyed or playback to stop.

Profiles and Descriptions

In SFX the sound profile and descrption work together to define a sound for playback including the path to the file on disk and the default properties for how sounds are to be played at the time of creation.

Like other datablocks the SFXProfile and SFXDescription are used mainly to limit network bandwidth during gameplay by sending the path and settings to the client once at startup.

Streaming

The current version of SFX does not abstract support for threaded sound streaming from disk. This means that all playing sounds must be loaded in their entirety in memory before playback can begin. This will affect you most with long sound files like music, but it also limits the ability to play streaming audio from the GuiTheoraCtrl.

This limit will be corrected in the next release.

Basic Reference

This was taken from different froum threads, where Tom Spilman and Rene Damm, introduced some basics on the use of the SFX system.

An SFXSource is a proper SimObject.

%source = SFXPlay( MyProfile );
%source.setVolume( 0.5 );
%source.setPitch( 0.5 );
%source.setTransform( "10 10 20" );

It also has other functions like play(), stop(), pause(), isPlaying(), isPaused(), etc. You can see more details in the C++ reference docs for SFXSource and also in the Torsion code browser window.


Things like this are safe now too: since its a real SimObject, isObject() will return false if the play once source was finished and has been deleted.

%this.someSource = SFXPlayOnce( MyProfile );
 
// Then sometime later...
if ( isObject( %this.someSource ) )
  %this.someSource.pause();


Look for sfxPause() and sfxResume() in script. These use the global SFXSourceSet to loop thru all the active sources in the game and pause/resume them. If you wanted for instance to pause all the game sounds, but leave your gui sounds:

new SimSet( PausedSimSounds );
sfxPause( $SimAudioType, PausedSimSounds  );
sfxPause( $MessageAudioType, PausedSimSounds  );
 
// Then when you want to resume them...
sfxResume( PausedSimSounds  );


OnSoundComplete callback mimic:

sfxPlayOnce( MySoundProfile );
 
function SFXSource::onStatus( %this, %status )
{
   if ( %status $= "stopped" )
      echo( "The source stopped!" );
}


SFXPlayOnce vs SFXPlay

%source = SFXPlayOnce( MyProfile );
// or
%source = SFXPlay( MyProfile );

In the example above, both lines of code achieve exactly the same.

sfxPlayOnce is basically just a convenience function. The order of things in SFX dictates that you need to have an SFXDescription (how the sound is played) and SFXResource (internal; what the sound is) and an SFXProfile that brings both together. Then, an SFXSource is created from the SFXProfile that drives the actual playback. This is invariant, i.e. it always happens.

However, as this is a huge overhead if you just want to play a single sound once, sfxPlayOnce takes care of all this allowing you to, for example, play directly from a file with just an SFXDescription. The temporary SFXProfile being created as well as the SFXSource are thrown away after playback has finished.

sfxPlay behaves exactly like sfxPlayOnce if you give it a profile and only is different if you call it with an SFXSource argument--in which case it is equivalent to SFXSource.play().


3D Audio following a moving object

%obj.playAudio(0,sfxName);


If you want to play a sound and have it move with an object, there is a function called playAudio that you can use on a player (probably works on all shapeBase objects).

I think the first parameter (0) is the mount point number you want the sount to come from, although I haven't looked at the c++ code to check that.

Best Practices

This was taken from a froum thread, where Robert Blanchet Jr. made some recomendations on the proper use of the SFX system.

1) Make sure each of the defined SFXProfile's fileName doesn't specify an extension. An extension does not need to be specified and by not explicitly saying .ogg or .wav it will allow you to change from one format to the other without having to change the scripts.

2) Make sure that server SFXProfiles and SFXDescriptions are defined with the datablock keyword, and that client SFXProfiles and SFXDescriptions are defined with the 'new' keyword. If you don't know (you really should know tho!), specify with datablock.

3) Make sure SFXDescriptions exist for your SFXProfiles. Also make sure that SFXDescriptions are defined BEFORE SFXProfiles. This is especially important if your SFXProfiles are located in different files than your SFXDescriptions. In this case, make sure the files containing SFXDescriptions are exec'd before the files containing the SFXProfiles.