Sign in to follow this  
scarypajamas

OpenAL sources and buffers

Recommended Posts

I'm trying to play sounds in OpenAL and I can get at least 2-3 sounds playing but then my app quits. I'm not quite sure I understand sources and buffers correctly, so if someone could confirm my knowledge, that would be great. Buffers are what store the sounds, such as ALuint Buffer[10] could be used to store 10 sounds. Sources are where my sounds play from. Also, when I attach a sound, via a buffer, to a source, is that source "stuck" with that sound? I can't attach another sound over that source and the old one will go away (or be overwritten)? I'm trying to make a 2d game and so I don't need any fancy 3d sound, I really only need 2 sources, 1 for music and the other for trinket noises like picking up items. I have code below but after I play about 2-3 sounds it quits the app. I'm wondering if my Source doesn't like having another buffer trying to be binded over it? Does anyone have any ideas? Do I have to delete the source and make a new one before I bind the buffer to it?
#define NUM_BUFFERS 13
#define NUM_SOURCES 3
#define LOOPING 1
#define STATIC 2

ALuint Buffer[NUM_BUFFERS];

ALuint Sources[NUM_SOURCES];

void PlaySound(ALint type, ALboolean looping)  //'type' is just the sound # in my Buffer[#] array to index.
{
	if( looping == AL_TRUE )
	{
		alSourcei (Sources[LOOPING], AL_BUFFER,   Buffer[type] );
		alSourcef (Sources[LOOPING], AL_PITCH,    1.0          );
		alSourcef (Sources[LOOPING], AL_GAIN,     1.0          );
		alSourcefv(Sources[LOOPING], AL_POSITION, SourcePos    );
		alSourcefv(Sources[LOOPING], AL_VELOCITY, SourceVel    );
		alSourcei (Sources[LOOPING], AL_LOOPING,  AL_TRUE      );
		alSourcePlay(Sources[LOOPING]);
	}
	else if( looping == AL_FALSE )
	{
		alSourcei (Sources[STATIC], AL_BUFFER,   Buffer[type] );
		alSourcef (Sources[STATIC], AL_PITCH,    1.0          );
		alSourcef (Sources[STATIC], AL_GAIN,     1.0          );
		alSourcefv(Sources[STATIC], AL_POSITION, SourcePos    );
		alSourcefv(Sources[STATIC], AL_VELOCITY, SourceVel    );
		alSourcei (Sources[STATIC], AL_LOOPING,  AL_FALSE     );
		alSourcePlay(Sources[STATIC]);
	}
}





Share this post


Link to post
Share on other sites
Quote:
Where's your loading routine?



LoadSound("sound.wav",1);

ALboolean LoadSound( ALbyte* file, ALint bufNum )
{
//variables to load into.
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
ALboolean loop;

//create sound sources
alGenSources(NUM_SOURCES, &Sources[LOOPING]);
alGenSources(NUM_SOURCES, &Sources[STATIC]);

//load wav data into a buffer.
alGenBuffers(NUM_BUFFERS, &Buffer[bufNum]);
if (alGetError() != AL_NO_ERROR)
return AL_FALSE;

alutLoadWAVFile(file, &format, &data, &size, &freq, &loop);
alBufferData(Buffer[bufNum],format,data,size,freq);
alutUnloadWAV(format, data, size, freq);

//do another error check and return.
if (alGetError() == AL_NO_ERROR)
return AL_TRUE;

return AL_FALSE;
}

Share this post


Link to post
Share on other sites
What does alutLoadWAVFile() return? I'm going to assume it might not actually be loading the files, and when you're passing some random pointer to Open AL to buffer, it's causing a few issues, because aside from that, it looks ok...

Also, here's a few things to help with your coding...


//you can generate all of the sources you'll need using this:
alGenSources(NUM_SOURCES,Sources);
//same with the buffers
alGenBuffers(NUM_BUFFERS,Buffer);

//you don't need to compare booleans with true or false
if (looping){
//looping
}else{
//not looping
}

Share this post


Link to post
Share on other sites
Quote:
When I attach a sound, via a buffer, to a source, is that source "stuck" with that sound? I can't attach another sound over that source and the old one will go away (or be overwritten)?


I'm quoting myself, but is this statement true?

Why might I only be able to play 2 static (non-looping sounds) before it unexpectedly quits?

[Edited by - scarypajamas on July 29, 2008 10:58:26 AM]

Share this post


Link to post
Share on other sites
OK, seems I missed something last night (that happens when you're tired). I think I see what the problem is now. Try using alSourceQueueBuffers() instead of setting the buffer directly, play the sound, and then alSourceUnqueueBuffers() once it's finished playing the sound, or, if you don't mind the sounds being cut a little short to keep the new sounds coming, you can stop it first, then unqueue it (it wont unqueue unless it's been stopped first). That will definately solve the 'getting stuck' problem, and hopefully, it will solve the crashing problem too.

Share this post


Link to post
Share on other sites
I've investigated alSourceQueueBuffers() but even with a half-hour of googling, I'm still a little sketchy on the implementation. I've re-written my PlaySound() function but now I'm not getting any sounds. Could someone check to see whats wrong. BTW, I haven't touched my LoadSound code at all so the above snippet is still the same.



void PlaySound(ALint type, ALboolean looping)
{
if( looping )
{
alSourceQueueBuffers(Sources[LOOPING], NUM_BUFFERS, &Buffer[type] );
alSourcei (Sources[LOOPING], AL_BUFFER, Buffer[type] );
alSourcef (Sources[LOOPING], AL_PITCH, 1.0 );
alSourcef (Sources[LOOPING], AL_GAIN, 1.0 );
alSourcefv(Sources[LOOPING], AL_POSITION, SourcePos );
alSourcefv(Sources[LOOPING], AL_VELOCITY, SourceVel );
alSourcei (Sources[LOOPING], AL_LOOPING, AL_TRUE );
alSourcePlay(Sources[LOOPING]);
}
else
{
alSourceQueueBuffers(Sources[STATIC], NUM_BUFFERS, &Buffer[type] );
alSourcei (Sources[STATIC], AL_BUFFER, Buffer[type] );
alSourcef (Sources[STATIC], AL_PITCH, 1.0 );
alSourcef (Sources[STATIC], AL_GAIN, 1.0 );
alSourcefv(Sources[STATIC], AL_POSITION, SourcePos );
alSourcefv(Sources[STATIC], AL_VELOCITY, SourceVel );
alSourcei (Sources[STATIC], AL_LOOPING, AL_FALSE );
alSourcePlay(Sources[STATIC]);
alSourceUnqueueBuffers(Sources[STATIC], NUM_BUFFERS, &Buffer[type] );
}
}





Also, what could be wrong with my other implementation below. What it does is delete the old source (to "cleanse" the old source of the buffer) and create a new one for a new sound.



void PlaySound(ALint type, ALboolean looping)
{
if( looping )
{
alDeleteSources(NUM_SOURCES, &Sources[LOOPING]);
alGenSources(NUM_SOURCES, &Sources[LOOPING]);
alSourcei (Sources[LOOPING], AL_BUFFER, Buffer[type] );
alSourcef (Sources[LOOPING], AL_PITCH, 1.0 );
alSourcef (Sources[LOOPING], AL_GAIN, 1.0 );
alSourcefv(Sources[LOOPING], AL_POSITION, SourcePos );
alSourcefv(Sources[LOOPING], AL_VELOCITY, SourceVel );
alSourcei (Sources[LOOPING], AL_LOOPING, AL_TRUE );
alSourcePlay(Sources[LOOPING]);
}
else
{
alDeleteSources(NUM_SOURCES, &Sources[STATIC]);
alGenSources(NUM_SOURCES, &Sources[STATIC]);
alSourcei (Sources[STATIC], AL_BUFFER, Buffer[type] );
alSourcef (Sources[STATIC], AL_PITCH, 1.0 );
alSourcef (Sources[STATIC], AL_GAIN, 1.0 );
alSourcefv(Sources[STATIC], AL_POSITION, SourcePos );
alSourcefv(Sources[STATIC], AL_VELOCITY, SourceVel );
alSourcei (Sources[STATIC], AL_LOOPING, AL_FALSE );
alSourcePlay(Sources[STATIC]);
}
}





I can get a sound from the buffer to the source, but then it seems the source is stuck with it, I thought deleting the source and crating a new one, such as the in the above implementation, would solve the problem. But instead, I get a runtime error. Any more suggestions would be helpful.

Is there anyway to "cleanse" the Source?

Share this post


Link to post
Share on other sites
You're still setting the buffer directly. As for deleting the source and recreating it, that's far more wasteful than you need it to be. You can ditch the giant if/else statement too, since you're basically setting up the sources the exact same way...


//define the source you plan on dealing with first with a simple if/else statement
ALuint source = looping ? Sources[LOOPING] : Sources[STATIC];

/*
When you want to stop the current sound and play another one,
you first need to stop the source
*/

alSourceStop(source);

//Now you need to find out which buffer is currently bound to the source
ALuint buffer;
alGetSourcei(source,AL_BUFFER,(ALint*)&buffer);

//And remove it...
alSourceUnqueueBuffers(source,1,&buffer);

//Now you're ready to queue another sound and play it, but first...
//REMOVE THIS LINE COMPLETELY:
alSourcei (source, AL_BUFFER, Buffer[type] );

/*
Finally, after you've set all of the other variables, since you've got
no need for your giant if/else statement, you can substitute AL_FALSE
and AL_TRUE when defining the looping value with the actual variable
*/

alSourcei (Sources[LOOPING], AL_LOOPING, looping);



One question though: if you're only going to be playing 2 sounds at most, why allocate an extra source? Wouldn't it be easier to just make the buffer and source indexes start from 0?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this