Microsoft DirectX 8.1 (C++) |
Many sound cards maintain their own secondary buffers and handle 3-D 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 3-D 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—that is, the number of hardware buffers is limited by the hardware voices available. DirectSound allocates a hardware voice when a buffer is created and releases it only when the buffer is destroyed; the voice is not free even when the buffer is not playing. If an application creates many buffers, chances are that some of them will end up being in software—that is, they will be managed and mixed by the CPU rather than the sound card.
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 so that their resources can be allocated to new sounds.
To defer the allocation of resources for hardware mixing and 3-D 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 a buffer created with the DSBCAPS_LOCDEFER flag, 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 3-D 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 for some PCI 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. For more information, see Voice Management on ISA and PCI Cards.