Important: |
---|
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
Playing a sound consists of the following steps:
Because streaming sound buffers usually play continually and are conceptually circular, DirectSound returns two write pointers when locking a sound buffer. For example, if you tried to lock 3,000 bytes beginning at the midpoint of a 4,000-byte buffer, the Lockmethod would return one pointer to the last 2,000 bytes of the buffer, and a second pointer to the first 1,000 bytes. The second pointer is NULL if the locked portion of the buffer does not wrap around.
Normally the buffer stops playing automatically when the end is reached. However, if the DSBPLAY_LOOPING flag was set in the dwFlagsparameter to the Playmethod, the buffer plays repeatedly until the application calls the IDirectSoundBuffer::Stopmethod.
Note When using a waveout driver, DirectSound will use waveOutGetPosition which returns a 32 bit value. This value will wrap in just under 7 hours, making the DirectSound subsystem unstable. If your application requires prolonged continous playback of audio with DirectSound, a DirectSound driver should be developed to avoid this problem.
For streaming sound buffers, your application is responsible for ensuring that each block of data is written to the buffer ahead of the current play position. (For more on the play position, see Current Play and Write Positions.) Applications should write at least 1 second ahead of the current play position to minimize the possibility of gaps in the audio output during playback.
The following C example writes data to a sound buffer, starting at the offset into the buffer passed in dwOffset:
BOOL AppWriteDataToBuffer( LPDIRECTSOUNDBUFFER lpDsb, // the DirectSound buffer DWORD dwOffset, // our own write cursor LPBYTE lpbSoundData, // start of our data DWORD dwSoundBytes) // size of block to copy { LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; HRESULT hr; // Obtain memory address of write block. This will be in two parts // if the block wraps around. hr = lpDsb->lpVtbl->Lock(lpDsb, dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); // If DSERR_BUFFERLOST is returned, restore and retry lock. if (DSERR_BUFFERLOST == hr) { lpDsb->lpVtbl->Restore(lpDsb); hr = lpDsb->lpVtbl->Lock(lpDsb, dwOffset, dwSoundBytes, &lpvPtr1, &dwAudio1, &lpvPtr2, &dwAudio2, 0); } if SUCCEEDED(hr) { // Write to pointers. CopyMemory(lpvPtr1, lpbSoundData, dwBytes1); if (NULL != lpvPtr2) { CopyMemory(lpvPtr2, lpbSoundData+dwBytes1, dwBytes2); } // Release the data back to DirectSound. hr = lpDsb->lpVtbl->Unlock(lpDsb, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if SUCCEEDED(hr) { // Success. return TRUE; } } // Lock, Unlock, or Restore failed. return FALSE; }
Last updated on Tuesday, May 18, 2004