//----------------------------------------------------------------------------- // // Sample Name: StreamData Sample // // Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- Description =========== The StreamData sample shows how to stream a wave file through a DirectSound secondary buffer. It is similar to the PlaySound sample, but adds support for streaming. Path ==== Source: DXSDK\Samples\Multimedia\DSound\StreamData Executable: DXSDK\Samples\Multimedia\DSound\Bin User's Guide ============ Load a wave file by clicking Sound File. Select Loop Sound if you want it to play repeatedly. Click Play. Programming Notes ================= For details on how to setup a non-streaming DirectSound buffer, see the PlaySound sample. The basic tasks to stream data from a wav file to a DirectSound buffer are as follows: * Set up DirectSound: 1. Call DirectSoundCreate to create a IDirectSound object 2. Call IDirectSound::SetCooperativeLevel to set the cooperative level. 3. Set the primary buffer format. This sample calls DSUtil_SetPrimaryBufferFormat() to do just this. * Create a DirectSound buffer and set up the notifications: 1. Read the wav file to get the wav file size, and the wav format in the format a WAVEFORMATEX structure. 2. Choose a DirectSound buffer size. This is the amount of data that DirectSound stores at once. You re-fill this buffer as sound plays from this buffer. This is best for large sounds files that are not possible to load all at once. For this sample, the buffer size is ~3 seconds of data. 3. Create a DirectSound buffer using the buffer size, and the wav file's format. Also pass in DSBCAPS_CTRLPOSITIONNOTIFY flag. This allows the buffer to send notification events to tell us whenever sound has finished playing. However, using this flags limits the buffer to software only, since hardware can not signal position notifications. 4. Set up the notifications on the buffer by calling IDirectSoundBuffer::SetNotificationPositions. See InitDSoundNotification() for an example of how this is done. When DirectSound plays past a notification position it signals an Win32 event. When this event is signaled, it is safe to fill that segment of data in the buffer with a new piece of sound. * Play the DirectSound buffer: 1. Call IDirectSoundBuffer::Restore on the buffer if the buffer was lost. 2. Next, fill the DirectSound buffer will the maximum amount of sound data. Since all the sound can not fit into this buffer will be filled with new sound data as this sound plays. 3. Call IDirectSoundBuffer::Play with the DSBPLAY_LOOPING flag set to start the buffer playing. The looping flag needs to be set since the buffer will need to continue playing after the end of the buffer is reached since typically more sound needs to be played. * Check to see if a notification is signaled: 1. Typically in the message pump check to see if the event was signaled. The event tells us that a segment of data has been played so this piece need to be filled. MsgWaitForMultipleObjects() works well as the message pump for this purpose. 2. If the event has been signaled, then lock the section of the buffer than has just been played and fill it with the next segment of wav data. See HandleNotification() for how this works. * When the entire sound has played: When handling the event notification, keep track of how much data has been put in the buffer. When the entire wav file has been put into the buffer, and after DirectSound has played it all it is necessary to manually stop the buffer since the buffer will continuously loop otherwise. * Free DirectSound: Simply call Release() on all the DirectSound objects that were created.