winapidirectsound

How to check if IDirectSoundBuffer is really playing? (buffer underrun detection)


I want to detect buffer underrun situation in direct sound environment.

I use two sound buffers (primary and secondary). Sometimes (when server gives data) I call lock method of IDirectSoundBuffer interface for posting data to secondary sound buffer. If data from server do not have time to come, the sound buffer starts play again from start of the buffer (and repeat it until I send new data to buffer). Maybe it's flag DSBPLAY_LOOPING, but as I read (and test it), primary buffer cannot be created without this flag (there was error at Play method).

I try to get status of playing, but GetStatus method always returns the same status, even there is no new data and player repeat old data.

So, how can I detect buffer underrun situation (when there is no new data for playing and all old data is played)?

Thanks in advance.


Solution

  • IDirectSoundBuffer8::GetCurrentPosition is really the only way you can determine where it is playing from, but it's also only reliable on Windows Vista or later systems that report DSBCAPS_TRUEPLAYPOSITION.

    A few things to note:

    TL;DR: Don't use DirectSound in new applications. It is only still supported at all for old software & games.

    So, what is a developer supposed to use if not DirectSound?

    (1) Windows Core Audio (WASAPI) is a good option if you can provide the sound data at a known data rate and format. If you need any real-time mixing or source-rate conversion, you have to do it yourself -or- you can use one of the many existing 3rd party audio libraries to do it that also send the final result to WASAPI. See Microsoft docs.

    (2) XAudio version 2 is a good choice if you want to do real-time mixing, source-rate conversion, and software-based DSP effects. It is included in the operating system as of Windows 8, but to support Windows 7 you have to use some legacy distribution and SDKs. See Microoft docs and this blog.

    Both WASPI and XAudio use a 'audio packet' model instead of a looping buffer for data submission. As long as a packet is pending processing, you won't have under-run.