   OpenAL Design
  I'm wondering whether you guys can help with a sound manager for my game. I’m using openAL and am a little confused with how to design my buffers / sources / listeners.Thoughts:- There will be 12 players at one time. - Most common sound a player will make will be stepping- Which may require (at max) a couple of step sounds every second for each player.- (I thought of looping 1 sound per player but this will probably not sink with the animation)- So for this, I thought of using a source for each player. (this is not very scaleable when if I exend to 100 players).- What should I do when the player makes another sound (eg chop)- Should I use another source?- Or attach multiple buffers the existing source (please explain how this can be done). alSourcei(, AL_BUFFER, ) seems to only handle 1 buffer and I do not understand how to manage the alSourceiv versionMore Questions:- What if I have 50 to 100 sounds. 50 to 100 buffers sounds like too much to load. And 80% of sounds will be rare. Should they be kept on disk and loaded when played and then unloaded? Or can they be played/streamed from disk.- Should I only attach buffers to sources when the buffer is played on that source. Should I then unattach that buffer from the source (not sure how to do this).- I thought of a method that used 1 source (with 1 buffer attached) when a sound is played. Therefore if a player makes 2 sounds, 2 sources would be used for those sounds. So at the moment I have the following design ideas:Design1 (source pool):- Play a sound. - An available source is searched for. - Buffer for sound is attached- Source position updated on each frame- Source made available to the source pool when sound completeDesign2 (source per object):- Each player has a source- When player make a sound (eg step, chop), the buffer is attached to the source and played- When sound complete, the buffer is unattached- Source may have multiple buffersEDIT: i prefer Design1 because it will be scaleable when i need more objects in the scene. it will also provide a simple interface. ie PlaySound(soundindex, position, velocity)The downside to Design1 is that I will need to init a source for each frequent step sound. I however guess this will not be much overhead.   
  I believe you are going to need a source pool, as many OpenAL implementations have a max source number.  If you are curious, I have what I consider to be a decent sound system for my current project.  I wish I had a decent page that described it all together, as I don't have a lot of time to go in depth here at the moment.  You can see the source online here.  The files you will want to look at are:SoundSystem .h/.cpp - Sound system, where you go to have it play sounds, etc.  It also manages a queue of sources.  If you try to play a sound that doesn't have a source, it allocates a source to it.  If there are no free sources, it kills the oldest sound and uses it's source.OpenALSource .h/.cpp - Wrapper around an AL source, just to make it easier to handleISound .h/.cpp - Base sound type, holds an OpenALSourceSoundResource .h/.cpp - Part of a generalized resource management system that loads sounds, textures, models, etc. on demand.  It also ensures that there is only one copy of each sound in memory at a time.  That way no matter how many times you play "explosion.ogg" in the game, it'll only have one copy in memory.  The resources are reference counted, so they get deleted when nothing uses them anymore.  The sound resource loads an ogg file from disk into an OpenAL buffer.SoundEffect .h/.cpp - Derived from ISound to play ogg files.  Eventually, I plan to have a SoundStream that streams a file off the disk but haven't gotten around to it yet.These are less important, but just for completeness here are the rest of the resource management files:SoundFactory .h/.cpp - This is a factory that takes a resource name (for sounds it's something like "explosion.ogg") and returns a SoundResource object.  Again, this is part of the whole resource management system.  So I'm not sure how carefully you care to look at this.IResourceFactory .h - Base resource factory classIResource .h - Base resource classResourceManager .h/.cpp - Class to actually do all the management of all the resource types.I'm not sure how useful that'll be, but hopefully it'll help you some.  Let me know if you have questions or comments.  I'll try to post something more of a description of what is going on when I'm not at work...   ;  Thanks Mr Grinch.  I have to brew up some coffees and check out your system.I've tried to keep my library less involved (mainly because I don't have time to maintain it).  But here is an overview of the wrapper I have made:- load wav files into buffers. all files are loaded into memory. - in the future i may create a pool for the buffers. the wave files will need to be read on a seperate thread so that the game thread is not delayed. might treat the pool as a cache. ie 'uncache' the least used wave.- load 16 sources (of course this can be configured)- playsound() searches for a source that is not used- source is released when the sound is complete (ie interface can not take ownership of a source)- interface is given a handle to the source with 1 function: stopsound. ie they may stop a looping sound.- future: soundmanager may stop a sound when sound pool full to make room for the new sound. the handle to the old sound is disabled so that any stop requests are ignored.- the implementation would be more simple if i created a source for each played sound and deleted the source when play complete. this would remove all pooling code. however im not sure what the overhead is. **if it was just memory allocation/deallocation, then overhead would be OK (since it would be marginal to what my app does).;  Yeah, you could probably just ignore the resource management and it would be easier.  It is nice to be able to say "get me a sound object for explosion.ogg" and not have to worry about whether it's already loaded or not, though.  Anyway, here are a few more thoughts:Quote:Original post by kneeride- Or attach multiple buffers the existing source (please explain how this can be done). alSourcei(, AL_BUFFER, ) seems to only handle 1 buffer and I do not understand how to manage the alSourceiv versionAs far as I know, you can't have a single source play multiple buffers.  If you want a player to play a step sound and a chop sound, you will need a source for each one.Quote:- in the future i may create a pool for the buffers. the wave files will need to be read on a seperate thread so that the game thread is not delayed. might treat the pool as a cache. ie 'uncache' the least used wave.As I see it buffer pooling/management is less important then source management.  Buffer management is just like managing textures or models or whatever.  Having several copies of the same thing loaded into memory is ok, you just waste some memory.  If you can avoid it, you probably should, but it's not the end of the world if you don't.  Having too many sources is a more serious problem because (if I remember correctly from my testing) it may cause crashes or at least OpenAL errors.  You can probably tell from my code that I don't handle OpenAL errors as well as I should...Quote:- the implementation would be more simple if i created a source for each played sound and deleted the source when play complete. this would remove all pooling code. however im not sure what the overhead is. **if it was just memory allocation/deallocation, then overhead would be OK (since it would be marginal to what my app does).I would avoid creating/deleting sources when it's not necessary.  According to this message from the OpenAL mailing list, creating and deleting sources can be expensive.  I would just create your set of sources at startup and delete them when you shutdown.Quote:- load 16 sources (of course this can be configured)- playsound() searches for a source that is not used- source is released when the sound is complete (ie interface can not take ownership of a source)- interface is given a handle to the source with 1 function: stopsound. ie they may stop a looping sound.- future: soundmanager may stop a sound when sound pool full to make room for the new sound. the handle to the old sound is disabled so that any stop requests are ignored.This sounds very much like what I do.  I'm not sure I would release the source whenever sound is complete.  Aside from possible difficulties figuring out when a source is really complete, it seems like you will be releasing and reacquiring sources way more than is really necessary.  I'm not sure how expensive that is, but it's work thinking about.  In your footsteps example, let's say a footstep happens every second.  Then you would have this happening "acquire source, play sound, release source, (wait a fraction of a second until the next step) acquire source, play sound, release source, (wait) acquire source, play sound, release source, etc.".  It could just be "acquire, play, (wait) play, (wait) play, ... release".I'd say just leave the source assigned to that sound/buffer until it is either deleted (and the source is released back to your pool) or another sound starts up that has a higher priority and takes the source.  That's what I do, and I think the code to do that is fairly well contained in the SoundSystem and SoundEffect (and I guess ISound, since SoundEffect inherits from that).  It seems like having more sounds than sources is something that is going to happen eventually, so you might as well plan for it.One other bit of advice: I have a "locking" mechanism that allows you to say this sound should not ever loose it's source, but I'm not quite happy about that.  I think a better approach would be to have several different sound priorities.  For example, you could have "dialog, music, sound effects, ambient noise".  That way, if a new ambient sound like a cricket or something started up, it wouldn't cut off your critical-to-the-plot dialog.  Other things I've read have recommended that you also factor in the distance from the player, so a sound that is across the map from the player would be more likely to be replaced than one right next to the player.  I think both of those are worth considering, although it makes figuring out which sound should loose it's source more complicated.  Just a thought...Let me know what you decide and how it goes.   ;  Good points Mr Grinch. You have some very interesting comments.- OK don't load/unload sources. This was just a thought. I actually load 16 sources and the start and unload at the end.- OK, can't have multiple buffers attached to a source. (1 source required for each sound)- I already handle unique wav files. I have 20 sounds. They all get loaded into a buffer. No repleat wavs (this is actually up to the config file).- I am however concerned when my game will have 100 unique sounds. Loading them all into memory could be expensive. So i may need load common wav files and cache uncommon ones. Maybe load them in on a different thread when needed. But I'm not worry just yet. This will not be needed for the first prototype.- I agree with the sound priorities based on distance and maybe other priorities. ie When 10 people chop, no one will be interested in the walk sounds (or even notice them missing).- Gee, I hope I dont have issues detectign the AL_STOPPED. That is how I am freeing the source back to the pool for the next sound- Interesting thoughts on keeping the source open for frequent sounds on the same buffer (ie steps). Probably a good idea because the steps will be CPU intensive if 10 - 20 people walking.- So i might have 3 types of sounds1. Play sound, that's it, dont care what happens to it2. Play a loop sound. Send a handle back to the interface so they may stop the sound (eg when a missle reaches its target)3. Play frequent sound. ie walk. source given owner ship to interface. interface may call repeat PlaySound on the same source/bufferAn optimisation idea:- Play the requiresource/step/step/step/etc../releasesource for actors on screen- Actors off screen or far way, just play a looping walk sound (ie dont need to be synced with the animation).   