Manipulating MIDI Segments
A number of interface functions (methods) are available to the IDirectMusicSegment interface that represents a loaded MIDI segment. You can look them up in the SDK if you're interested, but the two functions that should seem most important to you are the ones that play and stop a segment, right? Ironically, these are part of the IDirectMusicPerformance interface rather than the IDirectMusicSegment interface. This makes sense if you think about it: The performance object is like the ringmaster, and everything has to go through him. Like my girlfriend says, "Whatever."
Playing a MIDI Segment
Assuming that you've loaded a segment using the DMusic_Load_MIDI(), or done so manually, let dm_segment be the interface pointer to the segment. Then, to play it with the performance object, use IDirectMusicPerformance::PlaySegment(), prototyped here:
HRESULT PlaySegment(
IDirectMusicSegment* pSegment, // segment to play
DWORD dwFlags, // control flags
_int64 i64StartTime, // when to play
IDirectMusicSegmentState** ppSegmentState); // state holder
In general, set the control flags and start time to 0. The only parameters to worry about are the segment and segment state. Here's an example of playing dm_segment and storing the state in dm_segstate:
dm_perf->PlaySegment(dm_segment, 0, 0, &dm_segstate);
Here, dm_segstate is of the type IDirectMusicSegmentState and is used to track the segment playing. There is a copy of this in each array element of the dm_midi[], but if you do all this yourself, remember to send one yourself.
Stopping a MIDI Segment
To stop a segment during play, use the IDirectMusicPerformance::Stop() function shown here:
HRESULT Stop(
IDirectMusicSegment* pSegment, // segment to stop
IDirectMusicSegmentState* pSegmentState, // state
MUSIC_TIME mtTime, // when to stop
DWORD dwFlags); // control flags
Similar to Play(), you don't need to worry about most of the parameters, but just the segment itself. Here's an example of stopping dm_segment:
dm_perf->Stop(dm_segment, NULL, 0, 0);
If you want to stop all segments that are playing, make dm_segment NULL.
Checking the Status of a MIDI Segment
Many times you want to know if a song is done playing. To test this, use the IDirectMusicPerformance::IsPlaying() function. It simply takes the segment to test and returns S_OK if the segment is still playing. Here's an example:
if (dm_perf->IsPlaying(dm_segment,NULL) == S_OK)
{ /* still playing */ }
else
{ /* not playing */ }
Releasing a MIDI Segment
When you're done with a segment, you have to release the resources. The first step is to unload the DLS instrument data with a call to IDirectMusicSegment::SetParam() and then release the interface pointer itself with Release(). Here's how:
// unload the instrument data
dm_segment->SetParam(GUID_Unload, -1, 0, 0,(void*)dm_perf);
// Release the segment and set to null
dm_segment->Release();
dm_segment = NULL; // for good measure
Shutting Down DirectMusic
When you're all done with DirectMusic, you have to close down and release the performance object, release the loader, and release all the segments (see the preceding code). Finally, you must close down COM unless it's done elsewhere. Here's an example of the process:
// If there is any music playing, stop it. This is
// not really necessary, because the music will stop when
// the instruments are unloaded or the performance is
// closed down.
if (dm_perf)
dm_perf->Stop(NULL, NULL, 0, 0 );
// *** delete all the midis if they already haven't been
// CloseDown and Release the performance object.
if (dm_perf)
{
dm_perf->CloseDown();
dm_perf->Release();
} // end if
// Release the loader object.
if (dm_loader)
dm_loader->Release();
// Release COM
CoUninitialize();
A Little DirectMusic Example
As an example of using DirectMusic without DirectSound or any other DirectX component, I have created a program called DEMO10_4.CPP|EXE on the CD. It basically loads a single MIDI file and then plays it. Take a look at it and experiment. When you're done, come back and see how easy all this is with the latest installment of the library, T3DLIB3.CPP|H.
|