osgAL is a toolkit for handling spatial (3D) sound in the OpenSceneGraph rendering library. It utilizes OpenAL++ which is an portable object oriented toolkit ontop of OpenAL. It has been compiled and tested under Windows (.NET2003) and Linux (gcc3.2).
osgAL depends on OpenAL++ and OpenSceneGraph. It has been compiled with OSG 0.9.7. Download and build OpenAL++ and OSG and install header files and library files where the compiler can find them.
Under Windows, you have to setup the INCLUDE, LIB and PATH path, which can be done with the Environment variables
DOS> set INCLUDE=%INCLUDE%;c:\tools\openalpp\include
DOS> set LIB=%LIB%;c:\tools\openalpp\lib
DOS> set PATH=%PATH%;c:\tools\openalpp\bin
respectively.
There are five main classes:
A SoundState is a small lightweight class that contains a reference to a osgAL::Sample and the settings for a Sample. This class does nothing more than keeping this Sample and its associated attributes together. It can either have a osgAL::SoundSource (usually a limited resources, 32 or more) associated to it. Sometimes it is necessary to allocate a hardware soundsource to a soundstate, for example looping sounds with ambient sound or music.
SoundSource is derived from osg::Node and can be inserted into the scenegraph wherever one wants it to be. During update traversal it will calculate its world position and position the associated SoundState to right orientation and position. No culling is done currently.
The SoundManager is responsible for handling queued SoundStates (for sound events described below) and to store all SoundStates to make it possible to find them later on.
A node that during cull traversal updates the SoundManager and updates the transformation for the current listener from the current modelView matrix. This could be done manually, but this node makes it all happen automatically during the cull traversal, which reduces the need of inserting code in the viewer run loop.
This is a callback class, called during the update of the transformation of the SoundNode. If enabled this callback will shoot a ray from the listener to this SoundNode. If this ray is unoccluded nothing will happen. But if this ray is occluded by some geometry, the gain of the SoundState associated to this node will be reduced by some amount. The functionality of this callback can be extended by inheriting from OccludeCallback and attaching it to the SoundNode.
There is a concept that I call event, for example an explosion is a typical event where a short sound is played once. Another example is the contact sound generated from two colliding objects. When using for example rigid body dynamics, there can be a lot of sound events when objects collides, therefore, the osgAL::SoundManager has a method called pushSoundEvent(osgAL::SoundState *, int priority)
This method takes a SoundState as argument. By making a copy of this SoundState (it uses an internal flyweight pattern to avoid creating new SoundStates on the fly) it builds up a queue of SoundStates. Theese SoundStates are played one by one by the SoundManager during its update() call. This makes it possible to have a lot of SoundStates "playing" when there is a real shortage of hardware sound sources (usually 32 or so).
osgal.cpp - Code for testapplication.
osgalmultiple.cpp - Shows dynamic allocation/deallocation of samples.
osgalocclude.cpp - Demonstrates a simple sound occlusion example.
Change directory to the data sub-directory that contains the bee.wav sample file (data). Start the test application with osgal (make sure you have the path to the dynamic libraries (OSG, Producer, OpenThreads, OpenAL++ and osgAL).
The examples demonstrates the basic functionality of the OSGAL toolkit: