Skip to content
Alessandro Febretti edited this page Feb 10, 2015 · 13 revisions

Last revision: ver. 5.2-alpha3 - 4 March 2014

DEPRECATION NOTE: On windows, you can use the scsound module to easily setup and enable omegalib sounds support. Just enable the scsound module in the omegalib cmake configuration.

This page introduces the Omicron SoundAPI which is integrated into Omegalib to provide audio feedback for applications. Some of the features of the SoundAPI are:

  • Playing mono .wav files from a location in virtual space and localizing the audio across a speaker array
  • Playing stereo .wav files as a 2-channel background audio track
  • Modifying the attributes of the sound during runtime such as looping, volume, pitch, fading, and adding reverb
  • Full documentation: Omicron SoundAPI Reference

This guide will cover the following topics:

  • Installing and configuring a CAVE2 SuperCollider sound server
  • Configuring Omegalib to connect to your sound server
  • Adding sounds to your Omegalib application in C++ or Python

Installing SuperCollider on Windows for CAVE2 Desktop Development

Required:

  1. Download the required files and install SuperCollider.
    • For 'cave2_osc_desktop.scd', click 'view raw' to download.
  2. Create a directory to be the sound server root (such as C:\SoundServer) and place 'cave2_osc_desktop.scd' in that directory.
  3. Configure the sound server:
    • Line 18 of 'cave2_osc_desktop.scd' specifies the root directory sounds will be placed
    • Below is the default for CAVE2. Change this to "C:/SoundServer/sounds/"
// This specifies the base directory of all sounds
// Note: make sure the path ends with a '/'
var soundPath = "/Users/evldemo/sounds/"; 
  • NOTE If you are running the sound server on your local machine, set the path to empty (""): since you won't be coping files over to a remote server, files will already have the right path when passed to the sound server.
  1. Create a batch script to run the server
    • Create a file called 'SoundServer.bat', open in a text editor, and type the following:
@echo Off
REM Path to local SuperCollider Install
cd "C:\Program Files (x86)\SuperCollider-3.6.3"

REM Path to SuperCollider configuration script
sclang.exe "C:/SoundServer/cave2_osc_desktop.scd"
  1. Run SoundServer.bat to start the sound server! You should see the following message in the terminal:



+++++ !!! CAVE2 (DESKTOP DEVELOPMENT) AUDIO SERVER IS LOADED !!! +++++



The file path 'C:/SoundServer/sounds/' will be pre-pended to all loaded sounds.

Installing SuperCollider on OSX for CAVE2 Desktop Development

Required:

  1. Download the required files and install SuperCollider.
    • For 'cave2_osc_desktop.scd', click 'view raw' to download.
  2. Create a directory to be the sound server root (such as /Users/userName/SoundServer/) and place 'cave2_osc_desktop.scd' in that directory.
  3. Configure the sound server:
    • Line 18 of 'cave2_osc_desktop.scd' specifies the root directory sounds will be placed
    • Below is the default for CAVE2. Change this to empty string ("")
// This specifies the base directory of all sounds
// Note: make sure the path ends with a '/'
var soundPath = ""; 
  1. Add cave2_osc_desktop.scd to SuperCollider's startup file:
    • Go to "/Users/userName/Library/Application Support/SuperCollider/"
    • Add the following to startup.scd file (you may need to create it)
//boot server on application load
s.boot;

//load audio server on load 
s.doWhenBooted({thisProcess.interpreter.executeFile("/Users/userName/SoundServer/cave2_osc_desktop.scd")});
  1. Run SuperCollider. You should see the following message in SuperCollider's terminal window:



+++++ !!! CAVE2 (DESKTOP DEVELOPMENT) AUDIO SERVER IS LOADED !!! +++++



The file path '/Users/userName/sounds/' will be pre-pended to all loaded sounds.

Setting up the Asset Cache Server to automatically transfer sound files

Omicron's AssetCacheService allows the transfer of assets from an Omicron/Omegalib application to a target machine running an AssetCacheServer - in this case to the CAVE2 sound server. If you are running a local sound server for desktop development, it may be easier to copy the files manually to you sound server directory as this currently requires building Omicron from source.

If you are connecting to the CAVE2 audio server, this setup has been done for you.

  1. WIP

Configuring Omegalib to connect to a CAVE2 Sound Server

  1. Open default.cfg in your Omegalib install and uncomment a sound enabled configuration (like desktop-sound.cfg)
config:
{
//systemConfig = "system/desktop.cfg";
systemConfig = "system/desktop-sound.cfg";
//systemConfig = "evl/lyra-xinerama.cfg";
//systemConfig = "system/test-multipipe.cfg";
//systemConfig = "system/cave-emu.cfg";
//systemConfig = "system/test-multinode.cfg";
//systemConfig = "system/test-customTile.cfg";
//systemConfig = "system/test-wand-emulation.cfg";
//systemConfig = "system/test-tracker.cfg";
};
  1. Configure the sound parameters in 'desktop-sound.cfg':
// Approx. line 100
// If you are running a sound server on the same machine as Omegalib, the only change
// you may have to make is disabling the asset cache if you are not running a local asset cache server
sound:
{
  soundServerIP = "127.0.0.1";
  soundServerPort = 57120;
  soundServerVolume = 0;

  assetCacheEnabled = false; (default: true)
  assetCachePort = 22500; (default: 22500)

  volumeScale = 0.5;

  // Remember these paths are appended to the root sound directory specified by the sound server
  showMenuSound = "menu_sounds/menu_load.wav";
  hideMenuSound = "menu_sounds/menu_closed.wav";
  selectMenuSound = "menu_sounds/menu_select.wav";
  scrollMenuSound = "menu_sounds/menu_scroll.wav";

  menuSoundVolume = 0.2;	// 0.0 to 1.0
  menuSoundWidth = 2.0;	// 1 to 20
  menuSoundMix = 0.0;	// 0.0 to 1.0
  menuSoundReverb = 0.0;	// 0.0 to 1.0
};

Adding sounds to an Omegalib Application

Placing your sound files on the CAVE2 Sound Server

Using the Omicron AssetCacheManager, sound files in Omegalib can be automatically copied from your application folder to the CAVE2 audio server. This requires the AssetCacheServer to be running on the sound server. Otherwise you will have to manually place your sound files on the sound server directory.

Using the soundExample project:

soundExamples.py
laser.wav
/music/FrozenStar.wav
/music/FailingDefense.wav
/my_menu/hide.wav
/my_menu/show.wav
/my_menu/select.wav
/my_menu/scroll.wav

Since soundExamples.py uses the follow code to load the sounds:

env.setAssetDirectory("soundExamples"); # Suggestion: Use you application name

s_laser = env.loadSoundFromFile("laser", "laser.wav");
s_music = env.loadSoundFromFile("music", "/music/FrozenStar.wav");

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");

The sound files will be copied to the following location on the CAVE2 audio server:

/Users/evldemo/sounds/soundExamples/music/FrozenStar.wav
/Users/evldemo/sounds/soundExamples/my_menu/hide.wav
/Users/evldemo/sounds/soundExamples/my_menu/show.wav
/Users/evldemo/sounds/soundExamples/my_menu/select.wav
/Users/evldemo/sounds/soundExamples/my_menu/scroll.wav

All sound effects should be mono .wav files. Background music files using playStereo() can be stereo .wav files.

Python example

Note: This example is currently a work in progress. Some features like fade() for stereo sounds may not currently work in the demo version of the CAVE2 Sound Server

from math import *
from euclid import *
from omega import *
from cyclops import *

#--------------------------------------------------------------------------------------------------
# Scene Setup

light = Light.create()
light.setColor(Color("#ABABAB"))
light.setAmbient(Color("#020202"))
light.setPosition(Vector3(0, 50, -5))
light.setEnabled(True)

scene = getSceneManager()
scene.setMainLight(light)

# setup skybox
skybox = Skybox()
skybox.loadCubeMap("common/cubemaps/stars1", "png")
scene.setSkyBox(skybox)

#--------------------------------------------------------------------------------------------------
# Sound Setup

# Get the sound environment
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/evldemo/sounds/'
# and will append that file path to any additional paths
# All file path here are for the sound server!
env.setAssetDirectory("soundExample"); # Suggestion: use your application name

# Using s_ to denote a sound object verses a sound instance (si_)
# This looks for a sound file at '.../appDirectory/laser.wav'
# And will transfer it to the sound server at '/Users/evldemo/sounds/soundExample/laser.wav'
# Note that the assetDirectory path 'soundExample' has been added only on the sound server
s_laser = env.loadSoundFromFile("laser", "laser.wav");

# This looks for a sound file at '.../appDirectory/music/FrozenStar.wav'
# And will transfer it to the sound server at '/Users/evldemo/sounds/soundExample/music/FrozenStar.wav'
s_music = env.loadSoundFromFile("music", "/music/FrozenStar.wav");
s_combatMusic = env.loadSoundFromFile("music", "/music/FailingDefense.wav");

# Here we could replace the default menu sounds specified in the Omegalib configuration file for our application 
s_menuShow = env.loadSoundFromFile("showMenuSound", "/my_menu/show.wav");
s_menuHide = env.loadSoundFromFile("hideMenuSound", "/my_menu/hide.wav");
s_menuSelect = env.loadSoundFromFile("selectMenuSound", "/my_menu/select.wav");
s_menuScroll = env.loadSoundFromFile("scrollMenuSound", "/my_menu/scroll.wav");

# Set the volume scale of the menu sounds (0.0 - 1.0, default: 0.5)
s_menuShow.setVolumeScale(0.2)
s_menuHide.setVolumeScale(0.2)
s_menuSelect.setVolumeScale(0.2)
s_menuScroll.setVolumeScale(0.2)

# 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_combatMusic = SoundInstance(s_combatMusic)

# Play our initial background looping music at the application start
si_music.setVolume(0.5)
si_music.setLoop(True)
si_music.playStereo()

# Starts playing muted. We'll fade to this sound later
si_combatMusic.setVolume(0)
si_combatMusic.setLoop(True)
si_combatMusic.playStereo()


s_music5 = env.loadSoundFromFile('music5', '/music/TMP-MainTitle.wav')
si_music5 = SoundInstance(s_music5)
#--------------------------------------------------------------------------------------------------
def fadeToCombatMusic():
	# Fade from current volume to 0 over 3 seconds
	si_music.fade( 0.0, 3 )
	
	# Stop and play form beginning
	#si_combatMusic.playStereo()
	
	# Fade from current volume to 0.4 over 5 second
	si_combatMusic.fade( 0.4, 5 )

#--------------------------------------------------------------------------------------------------
def fadeToCalmMusic():
	# Fade from current volume to 0.5 over 3 seconds
	si_music.fade( 0.5, 3 )
	
	# Fade from current volume to 0.0 over 3 seconds
	si_combatMusic.fade( 0.0, 3 )

#--------------------------------------------------------------------------------------------------
def toggleMusic():
	if( si_music.isPlaying() ):
		# Immediately stop all music
		si_music.stop()
		si_combatMusic.stop()
	else:
		# Start all music
		si_music.playStereo()
		si_combatMusic.playStereo()
	

#--------------------------------------------------------------------------------------------------
# Menu
mm = MenuManager.createAndInitialize()

# Get the default menu (System menu)
menu = mm.getMainMenu()
mm.setMainMenu(menu)

musicMenu = mm.createMenu("musicMenu")
musicMenu = menu.addSubMenu("Music")

toggleMusButton = musicMenu.addButton("Enable music", "toggleMusic()")
combatButton = musicMenu.addButton("Combat music", "fadeToCombatMusic()")
calmButton = musicMenu.addButton("Calm music", "fadeToCalmMusic()")


# Set menu as checkable radio buttons
combatButton.getButton().setCheckable(True)
calmButton.getButton().setCheckable(True)
toggleMusButton.getButton().setCheckable(True)

combatButton.getButton().setRadio(True)
calmButton.getButton().setRadio(True)

toggleMusButton.getButton().setChecked(True)
calmButton.getButton().setChecked(True)

Troubleshooting

If you receive the error 'SC_PortAudioDriver: PortAudio failed at Pa_OpenDefaultStream with error: 'Device unavailable':

  • Verify that you have a microphone plugged into the microphone input of your machine (seen on Windows 8)

If your application launches and locks up at 'Connected: setting cache':

  • Try opening your system/desktop.cfg (or system/desktop-sound.cfg) and adding the line assetCacheEnabled = false; to the "sound:" section of the config
Clone this wiki locally