Dynamic Voice Management

Many sound cards maintain their own secondary buffers and handle 3D effects and mixing for them. These hardware buffers, as they are called, usually reside in system memory rather than on the card itself, but because they are mixed by the device, they make far smaller demands on the system processor than do software buffers. It is therefore most efficient to have as many buffers as possible allocated to hardware, especially 3D buffers.

By default, DirectSound allocates buffers to hardware whenever it can. However, it can create only as many hardware buffers as the device can play at one time. In other words, the number of hardware buffers is limited by the availability of hardware voices. DirectSound allocates a hardware voice when a buffer is created and releases it only when the buffer is destroyed. If an application creates many buffers, some of them will likely end up in software, which means that they will be managed and mixed by the CPU rather than the sound card.

Note    The DirectSound voice manager allocates hardware mixing resources, not memory. On a PCI card, the buffer occupies the same memory before and after it is allocated, regardless of whether it is allocated to the hardware mixer or the software mixer.

Dynamic voice management helps you overcome the limited availability of hardware resources by deferring voice allocation until buffers are played, and by enabling DirectSound to stop lower-priority sounds prematurely and release their resources so that these resources can be allocated to new sounds.

To defer the allocation of resources for hardware mixing and 3D effects to the moment when the buffer is played, specify the DSBCAPS_LOCDEFER flag in the DSBUFFERDESC structure passed to IDirectSound8::CreateSoundBuffer. When you call IDirectSoundBuffer8::Play or IDirectSoundBuffer8::AcquireResources on such a buffer, DirectSound places the buffer in hardware if possible, and in software otherwise.

When calling Play, you can attempt to free a hardware voice for the buffer by passing one of the flags in the following table, or one of the first two flags in combination with the third. DirectSound then searches for a playing buffer that is suitable for termination as specified by the flags.

Flag Criterion
DSBPLAY_TERMINATEBY_TIME Select the buffer that has been playing longer than any other candidate buffers.
DSBPLAY_TERMINATEBY_DISTANCE Select the 3D candidate buffer farthest from the listener.
DSBPLAY_TERMINATEBY_PRIORITY Select the buffer that has the lowest priority of candidate buffers, as set in the call to Play. If this is combined with one of the other two flags, the other flag is used only to resolve ties.

If it finds a suitable buffer, DirectSound stops it and allocates the voice it was using to the newly played buffer. If no buffer is suitable for termination, the newly played buffer is played in software, unless the DSBPLAY_LOCHARDWARE flag was specified, in which case the call to Play fails.

For more information on how deferred buffers are dealt with when played, see IDirectSoundBuffer8::Play.

Note    Do not use the DSBCAPS_STATIC flag in combination with DSBCAPS_LOCDEFER when creating buffers. DSBCAPS_STATIC buffers are placed in on-card memory when this is available, as is the case on some older cards. If you create such a buffer with the DSBCAPS_LOCDEFER flag, the buffer memory is not copied to the sound card until the buffer is played for the first time, which can result in unacceptable delays.