« Return to Thread: Question about hardware channel allocation and sound buffers

Re: Question about hardware channel allocation and sound buffers

by slytron :: Rate this Message:

Reply to Author | View in Thread

Chris Robinson wrote:

> On Monday 10 November 2008 04:27:07 pm slytron wrote:
>  
>> I realize that most sound cards can only mix 32 or 64 sounds at a time.
>> The question is does a sound card hardware channel get allocated when a
>> buffer is loaded with alBufferData and attached with AL_BUFFER or is the
>> hardware channel only in use while the sound is playing?
>>    
>
> Generally the hardware channel is in use while a buffer is attached to a
> source. So setting a source with alSourcei(source,AL_BUFFER,0); will release
> the hardware channels. Note that this isn't gauranteed by the spec, but AFAIK
> all current hardware drivers behave this way.
>
> The one thing to watch out for though, is that an implementation may only
> generate enough sources for each one to play a mono sound (multichannel
> buffers may take up multiple hardware channels, too). What you'll probably
> have to do is hold a pool of sources, and pick from them as you need one. So,
> at your program's start, you could have:
>
> vector<ALuint> Sources;
> ...
> while(1) {
>     ALuint src;
>     alGenSources(1, &src);
>     if(alGetError() != AL_NO_ERROR)
>         break;
>     Sources.push_back(src);
> }
>
> Since they don't have attached buffers, they won't be taking up hardware
> channels yet. Then when you want to play a sound:
>
> void myObject::PlaySound(const string &name, bool looping
>                          /*, other parameters*/)
> {
>     // Get the buffer based on the given name. If it's the first time it's
>     // used, it can be loaded into an AL buffer then cached globally to be
>     // returned immediately on subsequent calls
>     ALuint buffer = GetBufferByName(name);
>     if(!buffer) // failed to load sound
>         return;
>
>     // Make sure there's a useable source and get it
>     if(Sources.size() == 0)
>     {
>         // if not, you'll have to kill a current sound based on distance,
>         // gain, and priority (find the sound with the lowest priority and is
>         // quietest based on distance and gain; if it has lesser priority, or
>         // equal priority but is quieter, than the sound trying to play, force
>         // it to stop)
>
>         // if there's still no sources (ie. no sounds could be killed), just
>         // skip
>         if(Sources.size() == 0)
>             return;
>     }
>     this->source = Sources.back();
>     Sources.pop_back();
>
>     ...set source properties...
>     alSourcei(this->source, AL_LOOPING, looping?AL_TURE:AL_FALSE);
>     alSourcei(this->source, AL_BUFFER, buffer);
>     if(alGetError() != AL_NO_ERROR)
>     {
>         // failed to setup the sound. return the source to the pool
>         Sources.push_back(this->source);
>         this->source = 0;
>         return;
>     }
>     alSourcePlay(this->source);
>     alGetError();
> }
>
> Then about 20 to 30 times a second, you'll want to update the sound. You can
> check then to make sure the sound is still playing.
>
> void myObject::UpdateSound()
> {
>     if(!this->source) // no sound to update
>         return;
>
>     ALint state;
>     alGetSourcei(this->source, AL_SOURCE_STATE, &state);
>     if(state == AL_STOPPED)
>     {
>         // source stopped playing. free the channel and return the source to
>         // the pool
>         alSourceRewind(this->source);
>         alSourcei(this->source, AL_BUFFER, 0);
>
>         Sources.push_back(this->source);
>         this->source = 0;
>         return;
>     }
>
>     ...update parameters...
> }
>
> This is similar to a method I used in a project, and is rather scalable. It
> works well even with limited sources (32) in high-sound-count environments
> (at least 80 trying to play). The higher-level logic will have to check if
> the object's supposed to be playing a looping sound and make sure it's still
> playing, periodically trying to restart it if its not.
> _______________________________________________
> Openal-devel mailing list
> Openal-devel@...
> http://opensource.creative.com/mailman/listinfo/openal-devel
>
>  
Thanks Chris,
Although I am currently only playing 2 sounds orbiting the listener as a
test it all seams to be working well thanks to your information.
With the info you just gave me I think I can implement a proper sound
management system. I thank all the developers of openal.
I spent a day looking into using the direct x sound and you would think
at version 10+ they would have a decent library but
I would bet it would of taken me 3 or 4 weeks instead of the 2 days with
openal. Plus even though the UI of my game and world editor is in
windows mfc the rest of it can be built in windows or linux. ( squirrel
scripting, irrlicht for graphics, openal for sound and newton game
dynamics for physics )
Thanks again
Brett
_______________________________________________
Openal-devel mailing list
Openal-devel@...
http://opensource.creative.com/mailman/listinfo/openal-devel

 « Return to Thread: Question about hardware channel allocation and sound buffers