Home > Articles

  • Print
  • + Share This
This chapter is from the book

The DirectMusic API Rapper

Did you get my joke with the title? The DirectMusic API is even simpler than the DirectSound API. I have created functions to initialize DirectMusic, create all the COM objects for you, and enable you to focus on loading and playing MIDI files. Here's the basic functionality list:

  • Initialize and shut down DirectMusic with single calls

  • Load MIDI files off disk

  • Play a MIDI file

  • Stop a MIDI that is currently playing

  • Test the play status of a MIDI segment

  • Automatically connect to DirectSound if DirectSound has previously been initialized

  • Delete MIDI segments from memory

Let's take a look at each function one by one.

NOTE

Unless otherwise stated, all functions return TRUE (1) if successful, and FALSE (0) if not.

Function Prototype:

int DMusic_Init(void);

Purpose:

Dmusic_Init() initializes DirectMusic and creates all necessary COM objects. You make this call before any other calls to the DirectMusic library. In addition, if you want to use DirectSound, make sure to initialize DirectSound before calling DMusic_Init(). Here's an example of using the function:

Example:

if (!DMusic_Init())
 { /* error */ }

Function Prototype:

int DMusic_Shutdown(void);

Purpose:

DMusic_Shutdown() shuts down the entire DirectMusic engine. It releases all COM objects, in addition to unloading all loaded MIDI segments. Call this function at the end of your application, but before the call to shutdown DirectSound—if you have DirectSound support. Here's an example:

Example:

if (!DMusic_Shutdown())
 { /* error */ }

// now shutdown DirectSound...

Function Prototype:

int DMusic_Load_MIDI(char *filename);

Purpose:

DMusic_Load_MIDI() loads a MIDI segment into memory and allocates a record in the midi_ids[] array. The function returns the ID of the loaded MIDI segment, or –1 if not successful. The returned ID is used as a reference for all other calls. Here's an example of loading a couple of MIDI files:

Example:

// load files
int explode_id = DMusic_Load_MIDI("explosion.mid");
int weapon_id = DMusic_Load_MIDI("laser.mid");

// test files
if (explode_id == -1 || weapon_id == -1)
 { /* there was a problem */ }

Function Prototype:

int DMusic_Delete_MIDI(int id);

Purpose:

DMusic_Delete_MIDI() deletes a previously loaded MIDI segment from the system. Simply supply the ID to delete. Here's an example of deleting the previously loaded MIDI files in the preceding example:

Example:

if (!DMusic_Delete_MIDI(explode_id) ||
 !DMusic_Delete_MIDI(weapon_id) )
{ /* error */ }

Function Prototype:

int DMusic_Delete_All_MIDI(void);

Purpose:

DMusic_Delete_All_MIDI() simply deletes all MIDI segments from the system in one call. Here's an example:

Example:

// delete both of our segments
if (!DMusic_Delete_All_MIDI())
 { /* error */ }

Function Prototype:

int DMusic_Play(int id);

Purpose:

DMusic_Play() plays a MIDI segment from the beginning. Simply supply the ID of the segment you want to play. Here's an example:

Example:

// load file
int explode_id = DMusic_Load_MIDI("explosion.mid");

// play it
if (!DMusic_Play(explode_id))
 { /* error */ }

Function Prototype:

int DMusic_Stop(int id);

Purpose:

DMusic_Stop() stops a currently playing segment. If the segment is already stopped, the function has no effect. Here's an example:

Example:

// stop the laser blast
if (!DMusic_Stop(weapon_id))
 { /* error */ }

Function Prototype:

int DMusic_Status_MIDI(int id);

Purpose:

DMusic_Status() tests the status of any MIDI segment based on its ID. The status codes are as follows:

#define MIDI_NULL  0 // this midi object is not loaded
#define MIDI_LOADED 1 // this midi object is loaded
#define MIDI_PLAYING 2 // this midi object is loaded and playing
#define MIDI_STOPPED 3 // this midi object is loaded, but stopped

Here's an example of changing state based on a MIDI segment completing:

Example:

// main game loop
while(1)
  {
  if (DMusic_Status(explode_id) == MIDI_STOPPED)
  game_state = GAME_MUSIC_OVER;

  } // end while

That's it for the DirectSound and DirectMusic APIs. As I said, later in the chapter you will see demo examples of both, but for now, let's continue with putting together the final T3D Game Console and bring our virtual computer interface all together in one glorious ...Whoooaaa! I'm getting a little carried away here. I'm mean, let's finish up.

The T3DLIB Library at a Glance

At this point, we have three main .CPP|H modules that make up the T3D library:

  • T3DLIB1.CPP|H—DirectDraw plus graphics algorithms

  • T3DLIB2.CPP|H—DirectInput

  • T3DLIB3.CPP|H—DirectSound & DirectMusic

Keep this in mind when compiling programs. If you want to compile a demo program, call it DEMOX_Y.CPP, and then look at its .H includes. If you see it include any of the preceding related .H library modules, you'll obviously need to include the .CPP files, too.

To compile any of the programs, make sure to include both the library source files, as well as all the DirectX .LIB files—and please, for the sake of God, set your compiler to Win32 .EXE as the target!

  • + Share This
  • 🔖 Save To Your Account