Well, running out of voices - even though it’s a condition that can
result in very audible artifacts - is not a serious error.
There are basically three ways of handling this situation:
1. Allocate more resources, to increase the number of
simultaneous voices.
+ You'll never run out of voices.
- You risk running out of CPU power!
- Very hard to do reliably on a normal OS,
since memory allocation is higly non-
deterministic. (ie may cause drop-outs)
2. Drop new sounds until playing voices are finished.
(Seems to be the default action with SDL_mixer.)
+ Easy to implement.
+ No clicking or popping.
+ No CPU time issues. (Fixed voice pool.)
+ No system dependant real time issues.
- New and important sounds may be blocked by
barely audible tails of old sounds.
3. Steal voices. (What nearly all synths do when they
run out of voices.)
+ New and important sounds will be played.
+ No CPU time issues. (Fixed voice pool.)
+ No system dependant real time issues.
- Tricky to implement without introducing
clicks or pops, still without delaying
new sounds audibly.
- Figuring out which channel/voice to steal
is rarely as trivial as it may sound.
Unless it’s already supported, I think it would be possible to implement
3) on top of SDL_Mixer, but a good implementation would probably have
to be a part of SDL_Mixer. (It’s better and easier to this kind of stuff
in the real time context of the engine, than “from the outside”.)
Either way, the best solution is usually not to run out of channels at
all.
Especially when it comes to sound effects, the major problem with
"runaway explosions" and the like seems to be the total output level. Too
many explosions playing at a time will drive the mixer into clipping, or
as in Kobo Deluxe, make the output compressor/limiter “pump”. Neither
sounds particularly good.
Early versions of Kobo Deluxe (as well as many, many other games) “solve"
this by locking each sound effect to a specific voice. That is, there can
be only one instance of each sound effect playing at a time. If a sound
effect is triggered while playing, it just aborts and restarts. No
"buildup” effect - but obviously, the result isn’t all that "massive"
either…
Using a random factor for the retrig/don’t retrig helps reducing that
BzzzzzzzzOOM! effect when large (usually tiled) monsters or buildings
explode, but it’s still far from perfect. Besides, it can also cause
audible clicking, unless the mixer engine deals with that.
In the current version of Kobo Deluxe I’m using a polyphonic soft synth.
Explosions always allocate new voices, and they’re played at slightly
varying pitch. Pan and volume is used for “2D positional” sound. Phatt
sound and no clicking - but the game logic causes other problems.
The biggest one is keeping exploding bases from flooding the audio
engine. Exploding bases are in fact handled by invisible "enemies"
crawling around the base, multiplying when they hit branches. The net
result is that there’s no easy way of controlling the number of enemies
simultaneously and repeatedly firing off explosion sounds. Likewise when
the player shoots nodes at a high rate, having pipes exploding
independently all over the place. Seems like these "exploding pipe"
enemies will need to cooperate better when it comes to the sound effects.
//David Olofson — Programmer, Reologica Instruments AB
.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |
-------------------------------------> http://olofson.net -'On Sunday 19 May 2002 18:22, Johannes Prix wrote:
Hi!
I use Mix_PlayChannel to play sounds in my game and it works GREAT!
Yet sometimes it occurs that collision-sounds occur in large numbers
and very rapid succession and then my Mix_PlayChannel(-1,
Loaded_WAV_Files[Tune] , 0) - Command returns -1. Of course this is
something I have to catch and that won’t be too difficult. I guess the
error might be due to no sound channels left or something. However in
this case Mix_GetError() returns an empty string? Why is this? Is
this normal? Thanks again for any help or suggestions, Johannes.