Microsoft DirectX 9.0 SDK Update (Summer 2004) |
Play Audio Sample
The Play Audio sample shows how to load a segment and play it on an audiopath, how to use DirectMusic notifications, and how to change global performance parameters.
Path
Source: (SDK root)\Samples\C++\DirectMusic\PlayAudio
Executable: (SDK root)\Samples\C++\DirectMusic\Bin
User's Guide
Play the default segment, or load another WAV, MIDI, or DirectMusic segment file by clicking Open File. Adjust the tempo and volume by using the sliders. The tempo cannot be adjusted for WAV files.
Programming Notes
The OnInitDialog function does the following:
- Creates an event, g_hDMusicMessageEvent. This will be used by DirectMusic to signal the application whenever a DirectMusic notification comes in.
- Creates an object of class CMusicManager called g_pMusicManager.
- Initializes the CMusicManager object. This does the following:
- Creates IDirectMusicLoader8 by using CoCreateInstance.
- Creates IDirectMusicPerformance8 by using CoCreateInstance.
- Calls IDirectMusicPerformance8::InitAudio to initialize the performance and create a standard audiopath.
- Calls IDirectMusicPerformance8::AddNotificationType,requesting notifications of type GUID_NOTIFICATION_SEGMENT. DirectMusic will notify the application of all segment events so it can ascertain when the segment has ended.
- Calls IDirectMusicPerformance8::SetNotificationHandle, passing in the event whose handle is in g_hDMusicMessageEvent. This tells DirectMusic to signal this event when a notification is available.
The WinMain function performs the following tasks:
- Creates the window by using CreateDialog.
- In the messasge loop, calls MsgWaitForMultipleObjects, passing in g_hDMusicMessageEvent. This will tell us when g_hDMusicMessageEvent is signaled. DirectMusic signals this event whenever a DirectMusic notification has come in.
- If WAIT_OBJECT_0 is returned, calls ProcessDirectMusicMessages.
- If WAIT_OBJECT_0 + 1 is returned, Windows messages are available. The function does standard message processing by using PeekMessage.
When Open File is clicked, the OnOpenSoundFile function performs the following tasks:
- Gets the file name.
- Releases any previously created segment.
- Calls CMusicManager::CollectGarbage in Dmutil.cpp. This calls IDirectMusicLoader8::CollectGarbage, which ensures that unused objects are released. See Garbage Collection.
- Calls CMusicManager::SetSearchDirectory. This calls IDirectMusicLoader8::SetSearchDirectory, passing in GUID_DirectMusicAllTypes and a directory. This tells DirectMusic where to look for files referenced by segments.
- Calls CMusicManager::CreateSegmentFromFile to create a CMusicSegment called g_pMusicSegment. This entails the following steps:
- Call IDirectMusicLoader8::LoadObjectFromFile to load the IDirectMusicSegment8 into pSegment.
- Create a CMusicSegment, passing in pSegment.
- If the file is a pure MIDI file, call IDirectMusicSegment8::SetParam, passing in GUID_StandardMIDIFile. This ensures that the file is played correctly.
- Call IDirectMusicSegment8::Download, which downloads the segment's bands to the synthesizer. Some applications might want to wait before downloading, because the more instruments are downloaded, the more memory is required.
When Play is clicked, the OnPlayAudio function does the following:
- If the sound is to be looped, calls CMusicSegment::SetRepeats, passing in DMUS_SEG_REPEAT_INFINITE. Otherwise repeats are set to zero.
- Call CMusicSegment::Play, which calls IDirectMusicPerformance8::PlaySegmentEx.
When a notification is signaled, the ProcessDirectMusicMessages function looks for a message indicating that a segment has stopped. It performs the following tasks:
- Calls IDirectMusicPerformance8::GetNotificationPMsg in a loop to process each available message. The loop tests for S_OK, because S_FALSE is returned when no more messages are available.
- If the dwNotificationOption of the DMUS_NOTIFICATION_PMSG structure is DMUS_NOTIFICATION_SEGEND, calls QueryInterface on the punkUser member to obtain the IDirectMusicSegmentState8 interface of the segment instance that ended. The segment itself is obtained by using IDirectMusicSegmentState8::GetSegment. This method returns IDirectMusicSegment, and QueryInterface must be used to obtain IDirectMusicSegment8. The application then compares this pointer to the global primary segment pointer, to ensure that it was indeed the primary segment that stopped. Segments authored in DirectMusic Producer can trigger other segments, so we can't be sure that only the primary segment was playing.
- Cleans up all the interfaces.
See Also
© 2004 Microsoft Corporation. All rights reserved.