Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
135
Library/dxx8/samples/Multimedia/DirectMusic/PlayAudio/readme.txt
Normal file
135
Library/dxx8/samples/Multimedia/DirectMusic/PlayAudio/readme.txt
Normal file
@@ -0,0 +1,135 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sample Name: PlayAudio Sample
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// GM/GS<47> Sound Set Copyright <20>1996, Roland Corporation U.S.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
Description
|
||||
===========
|
||||
The PlayAudio 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: DXSDK\Samples\Multimedia\DirectMusic\PlayAudio
|
||||
|
||||
Executable: DXSDK\Samples\Multimedia\DirectMusic\Bin
|
||||
|
||||
User's Guide
|
||||
============
|
||||
Play the default segment, or load another wave, MIDI, or DirectMusic
|
||||
Producer segment file by clicking Segment File. Adjust the tempo and
|
||||
volume by using the sliders
|
||||
|
||||
Programming Notes
|
||||
=================
|
||||
This and other DirectMusic samples uses the DirectMusic sample
|
||||
framework, CMusicManager and CMusicSegment to help encapsulate some of
|
||||
the common functionality of DirectMusic. The framework is contained
|
||||
in dmutil.cpp.
|
||||
|
||||
This is how the sample works:
|
||||
|
||||
* Upon WM_INITDIALOG. See OnInitDialog()
|
||||
1. Create a Win32 event, g_hDMusicMessageEvent. This will be
|
||||
used by DirectMusic to signal the app whenever a DirectMusic
|
||||
notification comes in.
|
||||
2. Create a help class CMusicManager called g_pMusicManager.
|
||||
3. Initialize the CMusicManager class. This does the following.
|
||||
See CMusicManager::Initialize() in dmutil.cpp
|
||||
- Creates a IDirectMusicLoader8 using CoCreateInstance
|
||||
- Creates a IDirectMusicPerformance8 using CoCreateInstance
|
||||
- Calls IDirectMusicPerformance8::InitAudio to init DirectMusic
|
||||
using a standard audio path.
|
||||
4. Call IDirectMusicPerformance8::AddNotificationType() passing in
|
||||
GUID_NOTIFICATION_SEGMENT. This will make DirectMusic tell us about any
|
||||
segment notifications that come in. This is needed to by this
|
||||
sample to know when the segment has ended. However DirectMusic
|
||||
games may not care when the segment has ended.
|
||||
5. Call IDirectMusicPerformance8::SetNotificationHandle() passing
|
||||
in the Win32 event, g_hDMusicMessageEvent. This tells DirectMusic
|
||||
to signal this event when a notification is available.
|
||||
|
||||
* Setting up the app message loop. See WinMain()
|
||||
1. Create the dialog using CreateDialog().
|
||||
2. In a loop call MsgWaitForMultipleObjects() passing in
|
||||
g_hDMusicMessageEvent. This will tell us when g_hDMusicMessageEvent
|
||||
is signaled. Above we have told DirectMusic to signal this event
|
||||
whenever a DirectMusic notification has come in.
|
||||
3. If WAIT_OBJECT_0 is returned, then call ProcessDirectMusicMessages(),
|
||||
See below for details.
|
||||
4. If WAIT_OBJECT_0 + 1 is returned, then Windows msgs are available, so
|
||||
do standard msg processing using PeekMessage().
|
||||
|
||||
* When "Open File" is clicked. See OnOpenSoundFile()
|
||||
1. Get the file name from using GetOpenFileName().
|
||||
2. Release the any old g_pMusicSegment.
|
||||
3. Call CMusicManager::CollectGarbage(). See dmutil.cpp.
|
||||
This calls IDirectMusicLoader8::CollectGarbage which
|
||||
collects any garbage from any old segment that was present.
|
||||
This is done because some sophisticated segments, in particular
|
||||
ones that include segment trigger tracks or script tracks, may
|
||||
have a cyclic reference. For example, a segment trigger that
|
||||
references another segment that references the first segment, also
|
||||
via a segment trigger track.
|
||||
4. Call CMusicManager::SetSearchDirectory(). See dmutil.cpp
|
||||
This calls IDirectMusicLoader8::SetSearchDirectory()
|
||||
passing in the GUID_DirectMusicAllTypes and a directory.
|
||||
This will tell DirectMusic where to look for files that
|
||||
are referenced inside of segments.
|
||||
5. Call CMusicManager::CreateSegmentFromFile() to create a
|
||||
CMusicSegment called g_pMusicSegment from the file.
|
||||
See dmutil.cpp. This does the following:
|
||||
- Calls IDirectMusicLoader8::LoadObjectFromFile() to
|
||||
load the IDirectMusicSegment8 into pSegment.
|
||||
- Creates CMusicSegment passing in pSegment.
|
||||
- If the file is a pure MIDI file then it calls
|
||||
IDirectMusicSegment8::SetParam passing in
|
||||
GUID_StandardMIDIFile to DirectMusic this. This makes
|
||||
sure that patch changes are handled correctly.
|
||||
- If requested, it calls IDirectMusicSegment8::Download()
|
||||
this will download the segment's bands to the synthesizer.
|
||||
Some apps may want to wait before calling this to because
|
||||
the download allocates memory for the instruments. The
|
||||
more instruments currently downloaded, the more memory
|
||||
is in use by the synthesizer.
|
||||
|
||||
* When "Play" is clicked. See OnPlayAudio()
|
||||
1. If the UI says the sound should be looped, then call
|
||||
CMusicSegment::SetRepeats passing in DMUS_SEG_REPEAT_INFINITE,
|
||||
otherwise call CMusicSegment::SetRepeats passing in 0.
|
||||
2. Call CMusicSegment::Play() which calls
|
||||
IDirectMusicPerformance8::PlaySegmentEx(). See dmutil.cpp.
|
||||
|
||||
* Upon a DirectMusic notification. See ProcessDirectMusicMessages().
|
||||
This sample wants to know if the primary segment has stopped playing
|
||||
so it can updated the UI so tell the user that they can play
|
||||
the sound again. This is rather complex, but typically apps
|
||||
will not need this functionality. Here is what has to be done:
|
||||
|
||||
1. Call IDirectMusicPerformance8::GetNotificationPMsg() in a loop
|
||||
to process each PMsg that has occurred.
|
||||
2. Switch off the pPMsg->dwNotificationOption. This sample
|
||||
only handles it if its a DMUS_NOTIFICATION_SEGEND. This tells
|
||||
us that segment has ended.
|
||||
3. Call QueryInterface on the pPMsg->punkUser, quering for a
|
||||
IDirectMusicSegmentState8.
|
||||
4. Using the IDirectMusicSegmentState8, call GetSegment to
|
||||
get a IDirectMusicSegment* of the segment it refers to.
|
||||
This call may fail is the segment may have gone away before this
|
||||
notification was handled.
|
||||
5. Call QueryInterface IDirectMusicSegment to get a IDirectMusicSegment8
|
||||
6. Compare this pointer to the IDirectMusicSegment8 pointer
|
||||
in g_pMusicSegment, to see if this was the primary segment.
|
||||
This may not always be the case since segments can have segments enbedded
|
||||
inside of them, we only want handle when the primary segment has
|
||||
stopped playing. If it has, then update the UI
|
||||
7. Cleanup all the interfaces.
|
||||
|
||||
Reference in New Issue
Block a user