OpenAL++

A forum to store posts deemed exceptionally wise and useful
Post Reply
rooly
Posts: 224
Joined: Tue Oct 25, 2005 4:32 pm
Location: Louisiana, USA, backwater country
Contact:

OpenAL++

Post by rooly »

OpenAL++ is a cross-platform C++ wrapper for OpenAL. It's licensed via LGPL, and free to use, so you shouldn't have any worries.

Lets get one fact straight: There are 2 versions of OpenAL++ floating around. Use the latest, its what we'll be writing with.
(Note: the latest is not the version that shows up on a google search for openalpp tut.)

First things first, get your libraries, set up your project, and link Irrlicht and openalpp. The pure link command is “-lopenalpp”.

Here's our include:

Code: Select all

#include <irrlicht.h>

#include <alpp/alpp.h>
	//or
#include <openalpp/alpp.h>
	//depending on your folder structure
lets go ahead and bring in the namespaces too:

Code: Select all

//bring in the most common irrlicht namespaces
using namespace irr;
using namespace video;
using namespace scene;
using namespace core;

//and the openal++ namespace:
using namespace openalpp;
There. We've got all our common namespaces. Personally, I never 'using namespace' unless i'm inside a non-included source file, and rarely even then.

Now lets start with the main:

Code: Select all

int main()
{
	IrrlichtDevice* device = createDevice();	//use the default device driver
	ISceneManager* smgr = device->getSceneManager();	//get a scene manager
	IVideoDriver* driver = device->getVideoDriver();	//get a driver
Now that all the obvious stuff is set up, lets get to openal++
We need to setup a main sound environment:

Code: Select all

	AudioEnvironment* env = new AudioEnvironment();
	env->setGain(1.0);
This gives us access to using a listener. The listener, altho not dependant in code, is dependant on the environment for the main volume and any EAX plugins. Don't worry what EAX is, openal++ will explain that to you well enough.

Lets do a little more Irrlicht calls. we'll make a generic cube, and give it a fly straight animator to notice the 3d sound environment. We'll also add a static camera to view the scene;

Code: Select all

	ISceneNode* box = smgr->addCubeSceneNode();
	ISceneNodeAnimator* fly = smgr->createFlyStraightAnimator(vector3df(-15,0,10), vector3df(15,0,10), 10000, true);
	box->addAnimator(fly);
	fly->drop();
	
	ICameraSceneNode* cam = smgr->addCameraSceneNode();
	cam->setPosition(vector3df(0,10,-10));
	cam->setTarget(vector3df(0,0,10));
All of that is pretty self-evident if you know what you're reading. Our next step is to create our listener. For effect, lets put it at the camera's position.

Code: Select all

	Listener* listener = new Listener();
	vector3df cam_pos = cam->getPosition();
	vector3df cam_up = cam->getUpVector();
	vector3df cam_look = cam->getTarget();
	
	listener->setPosition(cam_pos.X, cam_pos.Y, cam_pos.Z);
	listener->setOrientation(cam_look.X, cam_look.Y, cam_look.Z, cam_up.X, cam_up.Y, cam_up.Z);
The Listener class is basically the exact equivalent of an irrlicht camera. You need a Listener to hear the 3d environment, and give it all the qualities of your main camera (or your character, or where ever you want the listener to be).

Now we can setup a Sound source. This is pretty much straight forward.

Code: Select all

	Source* sound = new Source("sound.wav");
	vector3df box_pos = box->getPosition();
	sound->setPosition(box_pos.X, box_pos.Y, box_pos.Z);
	sound->setLooping(true);
	sound->play();
Here's one part you need to be careful at. If you don't have a valid file, OpenAL++ will throw an exception and quit the program. Depending on your environment, you may need to fiddle with the exact path of your file. You can, of course, catch the thrown error and try to recover gracefully. This is done by putting your init lines into try/catch braces.

Now we need a few more bits of data, a timer, and a few float time variables to determine "deltaTime" (i'll call it dTime)

Code: Select all

	float dTime = 0.001, oldTime = 0, newTime = 0;
	ITimer Time = device->getTimer();
	
	vector3df velocity, box_pos_old = box->getPosition();
"velocity" you ask? "Why Would I need velocity?" Well its very simple. We want the velocity to affect the doppler shift. It probably won't be noticable at this level, but I'm showing you how anyway.

Now for our Main Loop. First we need to take care of modifying the velocity.

Code: Select all

	while(device->run())
	{
		box->updateAbsolutePosition();
		box_pos = box->getPosition();
		
		newTime = Time->getTime();
		dTime = (newTime - oldTime) / 1000;		//see note 1
		
		velocity = (box_pos - box_pos_old) / dTime;
		
		sound->setPosition(box_pos.X, box_pos.Y, box_pos.Z);		
		sound->setVelocity(velocity.X, velocity.Y, velocity.Z);	//see note 2
		
		driver->beginScene(true,true,SColor(255,0,0,255));	//blue background
		smgr->drawAll();
		driver->endScene();
		
		oldTime = Time->getTime();
		box_pos_old = box->getPosition();
	}
*NOTE1: the computer's clock is only accurate to milliseconds. So the smallest dTime we should get is 0.001. If you'r getting smaller, it's either a big error, or your dividing by zero and all hell is breaking loose.

*NOTE2: If you plan on having a moving listener, there's a "setVelocity" function there as well.

Now for cleanup. If your using the latest version of OpenAL++, you'll get horrible errors if you try to use 'not-pointers'. So we do this the fun way:

Code: Select all

	box->drop();
	cam->drop();
	
	listener->unref();
        sound->stop();
	sound->unref();
	
	evn->unref();
	
	device->closeDevice();
	device->drop();
	
	return 0;
}
All of this can be nicely wrapped into classes rather easily. The only translations required are for location and velocity. I suggest always using getAbsolutePosition() when modifying linked OpenAL++ types and Irrlicht types.

Remember, OpenAL++, just like OpenAL, and also like OpenGL, uses a left-handed coordinate system. It's up to you the user to determine what efforts are necessary to get it working perfectly. Usually you should only need to tweek simple things.

Gain is Volume. If you can't hear it, increase the gain. If its too loud, decrease. If you still are having trouble, modify the AudioEnvironment's Gain. Its the Master Volume in a sense. Sounds can be made ambient and not require a listener or positioning.

Lastly, OpenAL++ by default can load .ogg files, and play uncompressed and vorbis compressed .avi audio.

Code Happy!
Last edited by rooly on Fri Dec 21, 2007 6:30 pm, edited 1 time in total.
When banks compete, you win.
When ISPs compete, you win.
When electronics retailers compete, you win.
When governments compete...you get drafted.
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

This is awesome. Vote yes on prop. Stickthis.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

rooly: Just curious, I know this isn't the place to ask, but it appears that ALUT doesn't have a function named alutLoadWAV, and alutLoadWavFile is depreciated.

So I am curious what to do with OpenAL++ because it is using alutLoadWAV, but there is no such function defined in alut.h
TheQuestion = 2B || !2B
rooly
Posts: 224
Joined: Tue Oct 25, 2005 4:32 pm
Location: Louisiana, USA, backwater country
Contact:

Post by rooly »

this is an unfortunate side effect of the hardware sound accelleration industry's idiocy. OpenAL and OpenAL++ both have several version floating around, and no tutorials to explain any of it. This tut uses OpenAL++ v1.0, and the latest OpenAL.

Your OpenAL version may be older, but in the latest, it is at least deprecated but usuable. This setup would probably be best used on a linux machine, since your dependencies are easier to satisfy via the package manager
When banks compete, you win.
When ISPs compete, you win.
When electronics retailers compete, you win.
When governments compete...you get drafted.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Ah, I fixed the problem quite a while ago, but thanks rooly.
TheQuestion = 2B || !2B
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

thanks for the tutorial, as i'll be able to add sound to a simple demo i'm trying to make.

just to be sure, openalpp is this site: http://alpp.sourceforge.net/

i'll have to make three super-simple demos and then be able to make a demo similar to a controlled camera scene where the camera is guided to a sequence of sound dialogs, sort of like a briefing session, before the camera is set loose into the scene.

please let me know about any tools that will make it easy to do sound.
Image
Post Reply