Tricks of the Windows Game Programming Gurus:Sounding Off with DirectSound and DirectMusic

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### The DirectMusic API Rapper—Get It?

The DirectMusic API is even simpler than the DirectSound API. I have created functions to initialize DirectMusic and created all the COM objects for you to allow you to focus on loading and playing MIDI files. Here’s the basic functionality list:

  • Initializing and shutting down DirectMusic with single calls.
  • Loading MIDI files from disk.
  • Playing a MIDI file.
  • Stopping a MIDI that is currently playing.
  • Testing the play status of a MIDI segment.
  • Automatically connecting to DirectSound if it’s already initialized.
  • Deleting 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:

    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 shut down DirectSound (if you have DirectSound support). Here’s an 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 unsuccessful. The returned ID is used as a reference for all other calls. Here’s an example of loading a couple MIDI files:

    // 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:

    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:

    // 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:

    // 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:

    // 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

    #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:

    // main game loop

    while(1)

         {

         if (DMusic_Status(explode_id) == MIDI_STOPPED)

            game_state = GAME_MUSIC_OVER;

         } // end while

For a demo of using the library, check out `DEMO10_5.CPP|EXE` and `DEMO10_6.CPP|EXE`. The first program is a demo of DirectMusic using the new library, which allows you to pick a MIDI file from a menu and instantly play it. The second demo is a mixed-mode application that uses both DirectSound and DirectMusic at the same time. The important detail of the second demo is that DirectSound must be initialized first. The sound library detects this and then connects to DirectSound. Otherwise, the sound library would create its own DirectSound object.

> Warning: Both `DEMO10_5.CPP` and `DEMO10_6.CPP` use external cursor, icon, and menu resources contained in `DEMO10_5.RC` and `DEMO10_6.RC`, respectively. So make sure to include these files in the projects when you’re trying to compile. And you need to include `T3DLIB3.CPP|H` to compile, but you knew that!

### Summary

This chapter has covered a lot of ground. You learned a bit about the nature of sound and music, how synthesis works, and how to record sound. Then you learned about DirectSound and DirectMusic, created a library, and saw a lot of demos. I would have loved to have gone into DirectSound3D, not to mention more advanced DirectMusic, but that’s up to you. Now you know everything you need to make a game, and that’s the mission for the next chapter!

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.