|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Question about hardware channel allocation and sound buffersI am building a rpg. I currently have over 300 sounds but normally fewer than 10 will actually be playing at any given time.
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? My plan is to buffer the sound when it is first played but not delete with alDeleteBuffers unless the creature is destroyed. My other option is to load the buffers when the sound is about to played and destroy it when the sound has finished but this seems ineffectient ( I am not currently worried about memory consumption.. only performance and avoiding loading from file each time ). In other words in the extreme case there could be 100s of sounds loaded at the same time but only a few playing at any given time. Is it ok to leave the buffers loaded or do I need to reload them each time a sound is required to avoid using up all the hardware sound channels? BTW Thanks for the previous help:) Brett |
|
|
Re: Question about hardware channel allocation and sound buffersOn 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 |
|
|
Re: Question about hardware channel allocation and sound buffersChris 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 > > 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 |
|
|
Re: Question about hardware channel allocation and sound buffersOn Monday 10 November 2008 09:34:21 pm Brett Jones wrote:
> With the info you just gave me I think I can implement a proper sound > management system. I thank all the developers of openal. Not a problem. :) > I spent a day looking into using the direct x sound and you would think > at version 10+ they would have a decent library DirectSound has been rather stagnant since DirectX 8. Doesn't help that Windows Vista effectively killed it (there is no accelerated DirectSound in Vista, without something like ALchemy that can wrap it around a hardware OpenAL driver). _______________________________________________ Openal-devel mailing list Openal-devel@... http://opensource.creative.com/mailman/listinfo/openal-devel |
| Free embeddable forum powered by Nabble | Forum Help |