A quick search through the forums didn't come up with this, so i'd like to post a suggestion: the ability to load a file without using a slot on the soundcard yet. I tried to do this myself, but the loading + creating seems tightly coupled (since both happen in the sound implementations), and my knowledge of OpenAl isn't good enough yet.
It would be usefull if the SoundManager would have a 'LoadSound' method, which would in turn call a SoundFactory::loadSoundImpl() method or something. So that you can pre-populate its mBufferMap without 'eating' soundcard slots yet. If you have any hints, please let me know so i can have another look myself.
On the same subject (no offence intended) it looks like the mBufferMap never gets smaller during a game session, does it? Since destroying sounds doesn't delete the buffers. That might be a second suggestion: to add a parameter to the DestroySound method(s) which tells whether its source (the buffer) may also be removed.
That's it for today
I am working on a change now so that Sounds won't use up sources on the audio hardware. You will be able to create infinitely many sources and play them all at once and OgreAL will make some intelligent (hopefully
) decisions as to which to play and which to put off.
I modeled the buffer map off of Ogre's meshes that it keeps around so that loading more Entities from the same mesh file all point to the same instance. And all sounds that are loaded form the same file point to a single buffer in memory so any given sound file is only every loaded once.
Thanks for the quick response.
About playing many sounds simultaneously: can you give some insights about what your plans are with this?
Currently i'm writing a class on top of OgreAL which replaces soundcard slots based on a sounds' priority, when all slots are occupied. This high-level algoritm uses the SoundManager's MaxSounds() method for 'scaling'. This works pretty well, except for the coupling between loading & creation that is.
If you are working on something like this yourself, an idea might be to (optionally) accept a callback function which will determine whether a sound is more important than another. This mechanism could work like 'sort' methods. So you'd get:
string& MyClass::GetMostImportantSound(string& handle1, string& handle2)
// Determine based on distance, loudness, or whatever.
Where your Play method will optionally call the given method when all soundcard slots are busy.
Please note that i use the sound names, because i guess that most user algorithms, such as my own, will keep a handle as it's keys.
About the buffers: of course, i understand the performance reason. It's just that -always in theory
- you can run out of system memory when keeping unused buffers.
I am allowing the user to set a priority (low, medium, high) and then sorting the sounds based on priority and within each priority group I am sorting them by distance from the listener. So, for example, when you create a Sound it won't get a source. When you tell it to play it will request a source from the SoundManager. If the SoundManager has sources left in its "SourcePool" it will give it one of those, if it doesn't then it sorts the sounds that currently have sources. If there are any that have stopped and not released their sources, then the SoundManager will take its source and give it to the new Sound. If there are no sounds that have stopped it compares the priority of the most likely to be stopped against the current Sounds priority. If the current sound has a higher priority it steals the source from the one that it currently playing. If they have the same priority then they get compared by their distance from the listener. This is all done using two sort algorithms that are written to plug into std::sort(), I am thinking of adding a way to let the user supply their own algorithm, though this one seems to work pretty well so far.
Our current setup only takes the distance as a measure of priority but it might be handy indeed to add an actual priority argument.
Will it also be possible to give a sort of 'infinite' priority for slots you don't want to sacrafice? Like background music or gui sounds? Or will they 'survive' because of the distance check (which will probably be 0 for such sounds)?
The default priority is going to be medium which I think makes sense, so this will allow you to create sounds that you care less about and others that shouldn't be given up. So if you create your background music at high priority and the rest of your sounds at medium (the default) then the background music should never be given up. You make a good point about the listener relative sounds, though, I am not sure it's looking at those correctly! I'll have to look into that!
yeah using the high priority for certain sounds looks like a valid way to overcome that problem.
For customising/tweaking you might want to make the number of priorities configurable, for example through the soundManager's constructor. So the user has fine-grained control. Maybe this value needs to be limited (let's say 5 or 8 ), otherwise your algoritm might become too expensive.