RE: [GD-General] Writing an audio mixer
Brought to you by:
vexxed72
From: Tom H. <to...@3d...> - 2002-03-19 00:28:19
|
At 04:00 PM 3/18/2002, Brian Hook wrote: >One other thing that hasn't been mentioned is latency. With a threaded >audio mixer you can get pretty low latencies since you know you'll be >serviced at fairly regular intervals. With a synchronous mixer, you >have to trade off robustness (underflows) for response time. For a >puzzle game this probably isn't that big a deal, but it's something to >be aware of. Setting up a one second buffer gives you a lot of lee way >on servicing the stream, but you've now established a pretty big ass >delay in your audio stream. Lets assume that my frame rate should never drop below 20fps. This means my sound buffer must be at least 50ms if I'm going to service it once per frame (two 50ms buffers for double buffering). This also means that I have a 50ms latency for kicking off new sound effects. If the frame rate drops below 20fps then I'm going to have ugly problems (skipping on MacOS, repeating on Win32). I think you can stretch this out to 70, 80, etc ms ... though I'm not sure where exactly it starts to feel disconnected from the action. The other option is to go with a threaded system. However, for systems without threads, or systems like MacOS where you only have cooperative threads (icky kaka) you end up right back at the once per frame thing or dealing with doing your buffer filling in response to interrupts. Basically, if you can get away with saying the frame rate will never drop below some number (which is strictly a sound effect latency problem), then you can deal with updating the sound buffers once per frame. If you can't, then you either need to sprinkle multiple sound updates through the code or go to a threaded / interrupt based system. ------ I think if I was to set up a mixer, I would push the issue of how to service the hardware down to the system level. I would stack up play commands from the game side and generate the mixed results in response to a function call: GetMixedData(int iBytes, void* pBuffer); which would give you the next iBytes worth of mixed sound data into pBuffer. This function would need to be interrupt and thread safe. Then you just call this function from where ever you update the sound hardware for that system. The mixing code is all cross-plat and you only have to write up a page or two of code for stuffing a system buffer with audio (just like Ogg Vorbis). The buffer sizes are all system dependant, and can even be varied at run time if you like. Tom |