# OpenAL

This topic is 4426 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Couldn't find a better forum for this... I'm learning OpenAL. I've got the Programmers' Guide, which looks useful, but I'm after some other things like good tutorials. I've got experience with DirectSound so I'm expecting this all to be quite easy. Here are a couple of things I'm curious about comparing the two:
• In DSound you have your sound buffers, which you play. However for long sounds it's common to stream the data into a short buffer to save memory. Does OpenAL have functionality to inform you when a buffer is nearly played etc to let you do this? Is this streaming approach still valid in AL?
• Say I want to loop a sound X times. Is there any clever way to do this, or must I write code to look at the sample length, the start-time and the current time and figure out when to stop? Similarly to fade a sound in/out.
• Any general comments on Dsound Vs OpenAL are also welcome.

##### Share on other sites
To stream sounds in OpenAL you queue several buffers on a source. You can check if any buffers have finished playing, and if they have you can fill them with new data and queue them on the front again.

I'm not sure how you'd loop a certain number of times. Perhaps you could queue the same thing over and over.

##### Share on other sites
Oh I was thinking you'd use queing for telling it to "play sound A, then sound B".
But if I have two short buffers filled with the first 2 parts of a long sound effect, then once the first buffer has stopped playing I re-fill it with the 3rd part of the sound and then re-queue this buffer?

But you'd have to use a timer, or a poll in a low-priority thread, to check if a sound has finished? No way to get a notification?

##### Share on other sites
Streaming is pretty simple in OpenAL. Basically, you fill 2 or more (usually 3) buffers with sound, as you would in DS. Then these buffers are queued onto a source using alSourceQueueBuffers.

There is no real notification as such, and you definatly do not need to use a timer. To check if a buffer has finished playing on the source, you can use

int numProcessed;alGetSourcei(alSource, AL_BUFFERS_PROCESSED, &numProcessed);

All this does is return how many of the queued buffers have finished playing. If you do this check every frame, you can then have a simple for loop to re-queue how ever many buffers are needed.

So you really just do the following

Create 3 buffers and 1 sourceFill Buffer 1Fill Buffer 2Fill Buffer 3Queue Buffers On SourcePlay Sourcewhile (Not End Of Sample){  Check how many have been processed by now  Loop For (number of processed buffers)  {    Unqueue 1 buffer (this will obviously take the first one)    Re-fill the buffer with the next part of the sample    Re-queue the buffer on the source  }}

Obviously you need to check when the sample data has come to an end, but that shouldn't be to hard, depending on the data you are streaming.

Now this doesn't do what you requested, mainly that it tells you when a buffer has finished, rather than if it has nearly finished, but I don't see why that would be a problem.

Regarding looping a sample X number of times. This isn't to difficult as long as you use a few tricks.

If you are looping a sample that only requires one buffer, the instead of calling alSourcePlay, just queue the one buffer. The when alGetSourcei(alSource, AL_BUFFERS_PROCESSED, &numProcessed) sets numProcessed to 1, you know its time to re-add the buffer, and dec the loop count. If the loop count is 0, don't queue it again.

Just a quick note regarding queueing. In my example above, I used alSourceQueueBuffers to just queue one buffer, rather than alSourcePlay. This seems to be the accepted way of playing a buffer regardless of streaming, as it gives you more information on the playing of buffers and their current state.

Hope that helps
Spree

##### Share on other sites
The buffers used could be a global resource - so for any source we just grab some unused buffers off a 'pile', or create new ones if required? Although with AL having a source as a separate object to a buffer, is there any overhead with creating the maximum number of in-game sources at start-up - obviously you don't want to create loads of un-needed buffers?

Can you queue the same buffer twice or must you wait for it to finish the first loop before queueing again? And if you want multiple instances of the same sound playing at the same time on different sources, do you need one buffer for each (like in DirectSound) or can it share a single buffer?

Thanks again.

##### Share on other sites
Quote:
 Original post by d000hgThe buffers used could be a global resource - so for any source we just grab some unused buffers off a 'pile', or create new ones if required?

Thats totally up to you, and depends on your implementation. To make life easier, I generate a buffer (or multiple buffers) per sound, so I know I will always have a buffer to use, and I don't have to deal with various checks and safety features.

Quote:
 Original post by d000hgAlthough with AL having a source as a separate object to a buffer, is there any overhead with creating the maximum number of in-game sources at start-up

Other than memory no, generating the max number of sources is generally the done thing - and is what I do to a point. There are usually not that many anyway, though I always have a limit (since my current sound card can support 1024 sources!). 64 is usually plenty.

Quote:
 Original post by d000hgCan you queue the same buffer twice or must you wait for it to finish the first loop before queueing again?

Not something I have tried, though I don't know what you expect to gain from this. If the buffer has not yet finished, that means it is still reading the sound data. So queuing it again with new sound would corrupt the current playback.

Not sure if you can load data into a buffer that is currently queued - might be something that would be worth looking into, though I don't see the benifits.

Quote:
 Original post by d000hgAnd if you want multiple instances of the same sound playing at the same time on different sources, do you need one buffer for each (like in DirectSound) or can it share a single buffer?

A single buffer can be played on as many sources as you want. Once the buffer is created, all the source does is read the sound data directly. So you can have one buffer and multiple sources playing the sample sample without worry - I'm very surprised DS cannot do this!

Spree