Platform SDK: DirectX |
A secondary buffer that contains an entire self-contained sound is called a static buffer. Although it is possible to reuse the same buffer for different sounds, typically data is written to a static buffer only once.
Note A static buffer is not necessarily created by setting the DSBCAPS_STATIC flag in the buffer description. This flag requests allocation of memory on the sound card, which is often not available. A static buffer can exist in system memory and can be created with either the DSBCAPS_LOCHARDWARE or DSBCAPS_LOCSOFTWARE flag.
Loading data into a static buffer is a three-step process.
These steps are shown in the following example, where lpdsbStatic is an IDirectSoundBuffer interface pointer and pbData is the address of the data source.
LPVOID lpvWrite; DWORD dwLength; if (DS_OK == lpdsbStatic->Lock( 0, // Offset at which to start lock. 0, // Size of lock; ignored because of flag. &lpvWrite, // Gets address of first part of lock. &dwLength, // Gets size of first part of lock. NULL, // Address of wraparound not needed. NULL, // Size of wraparound not needed. DSBLOCK_ENTIREBUFFER)) // Flag { memcpy(lpvWrite, pbData, dwLength); lpdsbStatic->Unlock( lpvWrite, // Address of lock start. dwLength, // Size of lock. NULL, // No wraparound portion. 0); // No wraparound size. }
To play the buffer, call IDirectSoundBuffer::Play, as in the following example.
lpdsbStatic->SetCurrentPosition(0); HRESULT hr = lpdsbStatic->Play( 0, // Unused. 0, // Priority for voice management. 0); // Flags.
Because the DSBPLAY_LOOPING flag is not set in the example, the buffer automatically stops when it reaches the end. You can also stop it prematurely by using IDirectSoundBuffer::Stop. When you stop a buffer prematurely, the current read position remains where it is. Hence the call to IDirectSoundBuffer::SetCurrentPosition in the example, which ensures that the buffer starts from the beginning.
A static buffer can be created and filled with data by using a single method call, either DirectSound.CreateSoundBufferFromFile or DirectSound.CreateSoundBufferFromResource.
The following sample code creates a static buffer from the wave identified as "bounce" in the resource file. Assume that m_ds is a DirectSound object.
Dim dsbd As DSBUFFERDESC Dim dsbResource As DirectSoundBuffer Dim waveFormat As WAVEFORMATEX dsbd.lFlags = DSBCAPS_CTRLVOLUME Set dsbResource = m_ds.CreateSoundBufferFromResource( _ "", "bounce", dsbd, waveFormat)
The resource file has been compiled into the executable file, so no module name needs to be provided. Nor does the value of the lBufferBytes member of the DSBUFFERDESC type need to be set, because the method determines the size of the buffer from the size of the data. The WAVEFORMATEX type receives information about the wave format from the header stored in the file or resource.
To play the buffer, call DirectSoundBuffer.Play, as in the following example.
dsbResource.SetCurrentPosition 0 dsbResource.Play 0
Because the DSBPLAY_LOOPING flag is not set in the example, the buffer automatically stops when it reaches the end. You can also stop it prematurely by using DirectSoundBuffer.Stop. When you stop a buffer prematurely, the current read position remains where it is. Hence the call to DirectSoundBuffer.SetCurrentPosition in the example, which ensures that the buffer starts from the beginning.
You can also create a static buffer by using DirectSound.CreateSoundBuffer and then fill it with data from another location in memory by using the DirectSoundBuffer.WriteBuffer method.
For more information on writing to secondary buffers, see Using Streaming Buffers.