-
Notifications
You must be signed in to change notification settings - Fork 16
SoundAPIReference
Last revision: ver. 5.3 - 5 March 2014
The Omicron Sound API allows CAVE2 developers a simple way to trigger, place, and update sounds in virtual space. The API sends simple Open Sound Control (OSC) messages to the CAVE2 Audio Server developed by JD Pirtle.
The coordinate system used by the sound API is the same as the tracker: origin on the floor at the center of CAVE2, Y-up. Positions are stored as vector3 floats in meters. Orientations in quaternions.
Currently the CAVE2 Audio Server accepts 48 kHz wav files. For sounds to correctly play in 3D space using the play() function, the sound file must only have a single audio track (mono). Stereo sound files using playStereo() can have two (stereo) audio tracks.
The CAVE2 Tracking/Speaker Coordinate System
Provides basic management of the sound server and sound objects. Uses the Ultra minimalistic OSC library (http://gruntthepeon.free.fr/oscpkt/).
Method(s) | Description | Associated OSC Messages |
---|---|---|
connectToServer(IP, port) |
Connects to a sound server at the specified IP address and port. | |
startSoundServer() |
Starts the sound server and loads the default synthdefs. | /startServer /loadSynth /loadStereoSynth |
stopSoundServer() |
Shuts down the sound server. | /killServer |
getEnvironment() , setEnvironment(SoundEnvironment)
|
Gets and sets the current sound environment. | |
sendOSCMessage(Message) |
Sends an OSC message to the server. | |
showDebugInfo(bool) |
Toggles console display of all debugging messages. | |
isDebugEnabled() |
Returns whether displaying debugging information to the console has been enabled. | |
getServerVolume() , setServerVolume(value)
|
Gets and sets the global sound server volume (-30 to 8, CAVE2 Omicron default is -16). | /serverVol (value) |
getSoundLoadWaitTime() , setSoundLoadWaitTime(value)
|
Gets and sets the delay in milliseconds after each loadSoundFromFile() call (default: 200) |
The sound environment class provides a set of default sound parameters used for all sound objects it creates.
Method(s) | Description | Associated OSC Messages |
---|---|---|
Environment Management | ||
stopAllSounds() |
Stops any currently playing sounds in the current sound environment | /freeNode (nodeID) |
cleanupAllSounds() |
Unloads all sounds in the current sound environment. | /freeBuf (bufferID) |
getSoundManager() |
||
getAssetDirectory() , setAssetDirectory(path)
|
Gets and sets the default directory path for all created sounds. | |
getRoomSize() , setRoomSize(value)
|
Gets and sets the default reverb room size for all created sounds as a normalized float (0.0-1.0) | /setReverb (nodeID, wetness, roomSize) |
getWetness() , setWetness(value)
|
Gets and sets the default reverb wetness/dryness for all created sounds as a normalized float (0.0-1.0) | /setReverb (nodeID, wetness, roomSize) |
Sound Management | ||
loadSoundFromFile(name, fileName) |
Creates an new sound object with the given name and path to the sound file. | /loadBuffer (See Sound::loadFromFile) |
createInstance(sound) |
Creates an new sound instance from the given sound object. | |
getListenerPosition() , setListenerPosition(pos)
|
Gets and sets the listener position. This corresponds to CAVE2's navigated position in the virtual space (meters, Y up). | |
getListenerOrientation() , setListenerOrientation(orientation)
|
Gets and sets the listener orientation. This corresponds to CAVE2's navigated position in the virtual space (Quaternion). | |
getUserPosition() , setUserPosition(pos)
|
Gets and sets the user position. This corresponds to tracked user's head position in tracker space (meters, Y up). Not fully supported yet - will assume user is at origin | |
getUserOrientation() , setUserOrientation(orientation)
|
Gets and sets the user orientation. This corresponds to tracked user's head orientation in tracker space (Quaternion). | |
worldToLocalPosition(position) |
Convert a position from virtual space to local tracker/speaker space based on the listener's current orientation and position. SoundInstance uses this automatically unless setLocalPosition() is used instead of setPosition() | |
localtoWorldPosition(position) |
Convert a position from local tracker/speaker to virtual space space based on the listener's current orientation and position. | |
getVolumeScale() , setVolumeScale(volume)
|
Gets and sets the normalized (0.0-1.0) volume scale multiplied to every sound instance associated with the environment. | /setVol (instanceID, volume) |
isForceCacheOverwriteEnabled() , setForceCacheOverwrite(value)
|
Gets and sets if loaded sounds should overwrite existing files on the sound server. | |
getSoundLoadWaitTime() , setSoundLoadWaitTime(value)
|
Gets and sets the delay in milliseconds after each loadSoundFromFile() call (default: 200) |
A sound object storing the bufferID, filepath to the sound, and the default sound properties. These correspond to Supercollider buffers. Sound objects will use the same room size and wetness values as the current environment by default. If these parameters are manually changed (i.e. setRoomSize() is used) the sound will use those values instead until resetToEnvironmentParameters() is called.
Method(s) | Description | Associated OSC Messages |
---|---|---|
loadFromFile(path) |
Loads a sound file withe the given path. | /loadBuffer (bufferID,path) |
getDefaultRoomSize() , setDefaultRoomSize(value)
|
Gets and sets the default reverb room size for this sound as a normalized float (0.0-1.0) | |
getDefaultWetness() , setDefaultWetness(value)
|
Gets and sets the default reverb wetness/dryness for this sound as a normalized float (0.0-1.0) | |
getDefaultWidth() , setDefaultWidth(value)
|
Gets and sets the default speaker width for this sound (1-20) | |
getDefaultPitch() , setDefaultPitch(value)
|
Gets and sets the default pitch for this sound (1.0 normal, 2.0 one octave up, 0.5 one octave down, -1 backwards) | |
resetToEnvironmentParameters() |
Resets this sound objects environment parameters (room size and reverb) to the environment settings | |
isUsingEnvironmentParameters() |
Returns false if the environment paremeters for this sound was manually changed using setRoomSize() or setWetness() |
The following is a snippet of the soundtest.cpp application which is included within Omicron. In you use the Omicron SoundAPI in conjunction with OmegaLib's rendering framework, you only need to get the sound environment and load sounds from it. All SoundManager initializations and setting the listener and user positions it provided by the OmegaLib engine class. For using the Omicron SoundAPI functions using Omegalib's python interface, see OmegaPythonReference.
Sound setup outside of Omegalib:
SoundManager* soundManager;
SoundEnvironment* env;
Sound* sound;
Sound* music;
SoundTest()
{
soundManager = new SoundManager("supercolliderIP",57120);
// Delay for loadSoundFromFile()
// Necessary if creating a new SoundInstance immediatly after calling loadSoundFromFile()
// Default is 500, although may need to be adjusted depending on the sound server
soundManager->setSoundLoadWaitTime(500);
// Show additional debug info related to Omicron<->SuperCollider messages
//soundManager->showDebugInfo(true);
// Start the sound server (if not already started)
soundManager->startSoundServer();
// Get default sound environment
env = soundManager->getSoundEnvironment();
ofmsg("SoundTest: Checking if sound server is ready at %1% on port %2%... (Waiting for %3% seconds)", %soundServerIP %soundServerPort %(soundServerCheckDelay/1000));
bool serverReady = true;
timeb tb;
ftime( &tb );
int curTime = tb.millitm + (tb.time & 0xfffff) * 1000;
int lastSoundServerCheck = curTime;
while( !soundManager->isSoundServerRunning() )
{
timeb tb;
ftime( &tb );
curTime = tb.millitm + (tb.time & 0xfffff) * 1000;
int timeSinceLastCheck = curTime-lastSoundServerCheck;
if( timeSinceLastCheck > soundServerCheckDelay )
{
omsg("SoundTest: Failed to start sound server. Sound disabled.");
serverReady = false;
break;
}
}
// If this is not set, you will have to set an absolute path below
// Note: The CAVE2 Audio Server assumes sound are in '/Users/demo/sounds/'
// and will append that file path to any additional paths
env->setAssetDirectory("myApp"); // Recommend using a project name
// This effectively looks for '/Users/demo/sounds/myApp/beep.wav'
sound = env->loadSoundFromFile("beep", "beep.wav");
// This effectively looks for '/Users/demo/sounds/myApp/music/filmic.wav'
music = env->loadSoundFromFile("music", "/music/bgmusic.wav");
}
~SoundTest()
{
// Call the SoundManager destructor, cleans up all sounds
soundManager->~SoundManager();
}
virtual bool handleEvent(const Event& evt)
{
switch(evt.getServiceType())
{
case Service::Mocap:
// Here we assume the mocap ID of the head tracked user is 0.
if( evt.getSourceId() == 0 )
{
// evt.getPosition() returns a Vector3f
soundManager->setListenerPosition( evt.getPosition() );
// evt.getOrientation() returns a Quaternion
soundManager->setListenerOrientation( evt.getOrientation() );
}
}
}
Sound setup using Omegalib in C++:
SoundEnvironment* env;
Sound* sound;
Sound* music;
virtual void initialize()
{
// SoundManager initializations, listener position, and cleanup handled by engine.
// Sound server IP and ports set by OmegaLib configuration file.
env = getEngine()->getSoundEnvironment();
// If this is not set, you will have to set an absolute path below
// Note: The CAVE2 Audio Server assumes sound are in '/Users/demo/sounds/'
// and will append that file path to any additional paths
env->setAssetDirectory("myApp");
// All sound files should be in .wav format
// For positional sounds, file should be mono.
// Rest of important sound code is in handleEvent()
// This effectively looks for '/Users/demo/sounds/myApp/beep.wav'
sound = env->loadSoundFromFile("beep", "beep.wav");
music = env->loadSoundFromFile("music", "/music/bgmusic.wav");
// Omegalib has a set of default menu sounds which play on menu opening, closing, selecting, and scrolling.
// These can be replace with custom sounds by using a specific name for the first parameter in loadSoundFromFile():
env->loadSoundFromFile("showMenuSound", "/my_menu/show.wav");
env->loadSoundFromFile("hideMenuSound", "/my_menu/hide.wav");
env->loadSoundFromFile("selectMenuSound", "/my_menu/select.wav");
env->loadSoundFromFile("scrollMenuSound", "/my_menu/scroll.wav");
// These can also be changed for all Omegalib applications in the configuration file.
}
Sound setup using Omegalib in Python:
env = getSoundEnvironment()
# If this is not set, you will have to set an absolute path below
# Note: The CAVE2 Audio Server assumes sound are in '/Users/demo/sounds/'
# and will append that file path to any additional paths
env.setAssetDirectory("myApp");
# Using s_ to denote a sound object verses a sound instance (si_)
# This effectively looks for '/Users/demo/sounds/myApp/beep.wav'
s_sound = env.loadSoundFromFile("beep", "beep.wav");
# This effectively looks for '/Users/demo/sounds/myApp/music/bgmusic.wav'
s_music = env.loadSoundFromFile("music", "/music/bgmusic.wav");
# Custom Omegalib menu sounds
env.loadSoundFromFile("showMenuSound", "/my_menu/show.wav");
env.loadSoundFromFile("hideMenuSound", "/my_menu/hide.wav");
env.loadSoundFromFile("selectMenuSound", "/my_menu/select.wav");
env.loadSoundFromFile("scrollMenuSound", "/my_menu/scroll.wav");
A sound instance object storing the associated sound object, instanceID, and sound parameters (volume, mix, reverb, etc.). These correspond to Supercollider nodes.
play() is used for mono .wav files that is localized in the virtual space. playStereo() is intended for stereo .wav files that will be played on four speakers in the front of CAVE2 (2-channel left/right setup).
Method(s) | Description | Associated OSC Messages |
---|---|---|
Playback | ||
play() |
Plays a sound with the default sound parameters. | /play (instanceID, bufferID, volume, xPos, yPos, zPos, listenerX, listenerY, listenerZ, width, mix, reverb, loop, pitch, playToTrigger, playToPositionTrigger, framePosition) |
playStereo() |
Plays a stereo sound with the default sound parameters. | /playStereo (instanceID, bufferID, volume, loop, pitch, playToTrigger, playToPositionTrigger, framePosition) |
play(pos,volume,width,wetness,roomSize,loop) |
Plays a sound with the specified sound parameters. Position is in navigated/world space (meters, Y up). | /play (instanceID, bufferID, volume, xPos, yPos, zPos, listenerX, listenerY, listenerZ, width, mix, reverb, loop, pitch, playToTrigger, playToPositionTrigger, framePosition) |
playStereo(volume,loop) |
Plays a stereo sound with the specified sound parameters. | /play (instanceID, bufferID, volume, loop, pitch, playToTrigger, playToPositionTrigger, framePosition) |
stop() |
Stops the sound from playing. | /freeNode (instanceID) |
fade(targetVolume, duration) |
Fades the sound instance from it's current volume to the target volume over the specified duration in seconds | /setVolEnv (instanceID, targetVolume, envelopeDuration) /setSterVolEnv(instanceID, targetVolume, envelopeDuration) |
Parameters | ||
getLoop() setLoop(loop)
|
Gets and sets the looping flag. | |
getPosition() , setPosition(pos)
|
Gets and sets the position of the sound in navigated/world space (meters, Y up). This function will convert world position to local tracker/speaker position based on the SoundEnvironment's listenerPosition. | /setObjectLoc (instanceID, xPos, yPos, zPos) |
getLocalPosition() , setLocalPosition(pos)
|
Gets and sets the position of the sound in local tracker/speaker space (meters, Y up). | /setObjectLoc (instanceID, xPos, yPos, zPos) |
getVolume() , setVolume(volume)
|
Gets and sets the normalized (0.0-1.0) sound instance volume. | /setVol (instanceID, volume) |
getWidth() , setWidth(width)
|
Gets and sets the number of speakers (1-20) to pan the sound. | |
isEnvironmentSound() , setEnvironmentSound(bool)
|
Gets and sets the environment flag (play on all 20 speakers) of the sound. | |
getWetness() , setWetness(wetness)
|
Gets and sets the wetness/dryness (0.0-1.0) of the sound instance. | /setReverb (nodeID, wetness, roomSize) |
getRoomSize() , setRoomSize(roomSize)
|
Gets and sets the reverb/room size (0.0-1.0) of the sound instance. | /setReverb (nodeID, wetness, roomSize) |
getPitch() , setPitch(pitch)
|
Gets and sets the pitch of the sound instance (1.0 normal, 2.0 one octave up, 0.5 one octave down, -1 backwards). | /setMonoRate(nodeID, pitch) /setStereoRate(nodeID, pitch) |
setCurrentFrame(frameNo) |
Sets the current frame position of the sound instance. | /setMonoFrame(nodeID, pitch) /setStereoFrame(nodeID, pitch) |
isPlaying() |
Return true if the sound server reports the instance is currently playing | |
isDone() |
Return true if the sound server reports the instance is done playing |
C++ Example:
virtual void initialize()
{
// Previous SoundManager/SoundEnvironment/Sound setup
// ....
// Play some background music at startup
// playStereo() is for ambient music and plays in a fixed left/right channel configuration
SoundInstance* musicInst = new SoundInstance(music);
musicInst->setVolume(0.2);
musicInst->setLoop(true);
musicInst->playStereo();
}
virtual bool handleEvent(const Event& evt)
{
if( evt.getFlags() == Event::ButtonLeft )
{
SoundInstance* soundInst = new SoundInstance(sound);
// Place the sound at the wand position
soundInst->setPosition( evt.getPosition() );
// We could also set other sound parameters before playing
soundInst->setVolume(0.7);
soundInst->setRoomSize(0.5);
soundInst->play();
}
}
Python Example:
# Previous SoundEnvironment/Sound setup
# ....
# Play some background music at startup
# playStereo() is for ambient music and plays in a fixed left/right channel configuration
si_music = SoundInstance(s_music)
si_music.setVolume(0.5)
si_music.setLoop(True)
si_music.playStereo()
def onEvent():
global playStopLight
global moveVector
e = getEvent()
if(e.getServiceType() == ServiceType.Wand):
if(e.isButtonDown( EventFlags.ButtonLeft )):
si_sound = SoundInstance(s_sound)
# Place the sound at the wand position
si_sound.setPosition( e.getPosition() )
# We could also set other sound parameters before playing
si_sound.setVolume(0.7)
si_sound.setRoomSize(0.5)
si_sound.play()
# Register our event function with Omegalib
setEventFunction(onEvent)