Search Tips Advanced Search |
| Delphi Graphics and Game Programming Exposed with DirectX 7.0 by John Ayres Wordware Publishing, Inc. ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous | Table of Contents | Next
The first member of this structure can be set to the handle of a window which will receive the MM_MCINOTIFY message (if so desired) when the function completes. The second member will be set to the MCI device identifier when the function returns, and should be stored for later use. The third parameter is set to the name of the device; for MIDI file playback, this should be set to ‘sequencer.’ The fourth parameter is set to the name of the MIDI file, which is opened and prepared for playback when this function returns. The final member contains a device alias and for our purposes can be ignored. For our purposes, we can also ignore the dwCallback member. Thus, to open the MIDI device and a MIDI file, we must initialize lpstrDeviceType to ‘sequencer,’ set lpstrElementName to the filename of our MIDI file, and pass the structure to the MCISendCommand function, specifying MCI_OPEN as our command message. For example:
      {open the MIDI output device, loading the Canyon MIDI song}

      OpenParms.lpstrDeviceType  := ‘sequencer’;

      OpenParms.lpstrElementName := ‘C:\Windows\Media\Canyon.mid’;

      MCISendCommand(0, MCI_OPEN, MCI_OPEN_TYPE or MCI_OPEN_ELEMENT or MCI_WAIT,

                     LongInt(@OpenParms));

      {save a handle to the device}

      MCIDeviceID := OpenParms.wDeviceID;
When this command returns, the wDeviceID member of TMCI_Open_Parms will contain a device identifier for the opened MIDI sequencer. The application should store this value, as it will be used in all subsequent MCISendCommand function calls. Set the Time Format The MCI subsystem needs to know the time format for playback of various media so it will not come out garbled or trashed. MIDI music is timed by the millisecond, so we must inform MCI to set the time format for playback to milliseconds. This is accomplished by initializing a variable of type TMCI_Set_Parms. The TMCI_Set_Parms structure is defined as:
    TMCI_Set_Parms = record

      dwCallback: DWORD;                  // a window handle

      dwTimeFormat: DWORD;                // the time format

      dwAudio: DWORD;                     // audio output channel

    end;
The first member of this structure can be set to the handle of a window which will receive the MM_MCINOTIFY message (if so desired) when the function completes. The second parameter is a flag that indicates the time format. The final member indicates the audio output channel. For our purposes, we are only interested in the dwTimeFormat member, which should be set to MCI_FORMAT_MILLISECONDS to indicate a millisecond time format. This initialized structure is then sent to the MCISendCommand function with a command message of MCI_SET. We must also pass in the device ID that we recorded from the previous call to indicate the device whose time format is being set. For example:
      {set the time format to milliseconds}

      SetParms.dwTimeFormat := MCI_FORMAT_MILLISECONDS;

      MCISendCommand(MCIDeviceID, MCI_SET, MCI_WAIT or MCI_SET_TIME_FORMAT,

                     LongInt(@SetParms));
Commence Playback The final step simply informs the multimedia system that we wish to play the file. This requires a variable of the type TMCI_Play_Parms. The TMCI_Play_Parms data structure is defined as:
    TMCI_Play_Parms = record

      dwCallback: DWORD;                  // a window handle

      dwFrom: DWORD;                      // play start position

      dwTo: DWORD;                        // play end position

    end;
The first member of this structure can be set to the handle of a window which will receive the MM_MCINOTIFY message (if so desired) when the function completes. The second member indicates the position at which to start playback, and the final member indicates the position at which to end playback. This data structure allows the application to specify the exact position from which to begin playback and an exact position at which to end the playback. Even though the MCISendCommand function requires a variable of this type, there is no need to initialize any of the members to simply play the MIDI file; it will play it from start to finish by default. The MCI_PLAY command message instructs Windows to begin playback. For example:
      {commence song playback, indicating that we wish to receive an MM_MCINOTIFY

       message when the playback has completed}

      PlayParms.dwCallback := Handle;

      MCISendCommand(MCIDeviceID, MCI_PLAY, MCI_NOTIFY, LongInt(@PlayParms));
Notice that we set the dwCallback member to the handle of our main window, and indicated that we wished to be notified when the function finishes. If we had used the MCI_WAIT flag, our application would hang until the MIDI file had finished playing. Obviously, this is not acceptable, so we indicated that we would instead like to receive the MM_MCINOTIFY message when the music stops. In our example below, we use this to implement a looping feature. Retrieve Playback Status While certainly not a required step, most applications at some point may need to know the current position of playback. This could be used to change the music according to the context, waiting for playback to reach a specific point so the music can be changed at an appropriate time. We can retrieve the current playback status by using a variable of type TMCI_Status_Parms. TMCI_Status_Parms is defined as:
    TMCI_Status_Parms = record

      dwCallback: DWORD;                    // a window handle

      dwReturn: DWORD;                      // the status value

      dwItem: DWORD;                        // the status item

      dwTrack: DWORD;                       // length

    end;
The first member of this structure can be set to the handle of a window which will receive the MM_MCINOTIFY message (if so desired) when the function completes. The second member contains the status value when the function returns. The third member contains a flag indicating the item whose status is to be retrieved. For our purposes, this can be set to MCI_STATUS_POSITION to indicate we wish to retrieve the status of the playback position. The final member indicates the length or number of tracks. The MCI_STATUS command message indicates we wish to retrieve the device’s status. For example:
      {retrieve the current position of the song playback}

      StatusParms.dwItem := MCI_STATUS_POSITION;

      MCISendCommand(MCIDeviceID, MCI_STATUS, MCI_WAIT or MCI_STATUS_ITEM,

                     LongInt(@StatusParms));
Close the Device When the application terminates or MIDI music playback is no longer required, the MCI device must be closed and released by calling the MCISendCommand with a command message of MCI_CLOSE. The MCI device ID must be passed in to the first parameter, but the last two parameters are unused and should be set to zero. The following example implements the discussed steps in order to play back a MIDI music file.
Previous | Table of Contents | Next

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 whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.