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
Listing 9-10: Playing MIDI music
    procedure TfrmMidiExample.FormCreate(Sender: TObject);

    begin

      {determine if there are any devices capable of outputting MIDI music}

      if midiOutGetNumDevs<1 then

      begin

        ShowMessage(‘There are no devices attached to the system capable of’ +

                    ‘outputting MIDI music.’);

        Application.Terminate;

      end;

    end;

    procedure TfrmMidiExample.FormClose(Sender: TObject;

      var Action: TCloseAction);

    begin

      {make sure that the MIDI device is closed before exiting the program}

      MCISendCommand(MCIDeviceID, MCI_CLOSE, 0, 0);

    end;

    procedure TfrmMidiExample.btnPlayClick(Sender: TObject);

    var

      OpenParms: TMCI_Open_Parms;

      PlayParms: TMCI_Play_Parms;

      StatusParms: TMCI_Status_Parms;

      SetParms: TMCI_Set_Parms;

    begin

      {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;

      {set the time format to milliseconds}

      SetParms.dwTimeFormat := MCI_FORMAT_MILLISECONDS;

      MCISendCommand(MCIDeviceID, MCI_SET, MCI_WAIT or MCI_SET_TIME_FORMAT,

                     LongInt(@SetParms));

      {retrieve the length of the song}

      StatusParms.dwItem := MCI_STATUS_LENGTH;

      MCISendCommand(MCIDeviceID, MCI_STATUS, MCI_WAIT or MCI_STATUS_ITEM,

                     LongInt(@StatusParms));

      {display this length in terms of minutes and seconds}

      Label1.Caption := ‘Format(%d:%.2d’, [StatusParms.dwReturn div 1000 div 60,

                               Trunc(Frac(StatusParms.dwReturn/1000/60)*60)]);

      {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));

      {enable the playback position polling timer}

      tmrPosition.Enabled := TRUE;

    end;

       .

       .

       .

    procedure TfrmMidiExample.tmrPositionTimer(Sender: TObject);

    var

      StatusParms: TMCI_Status_Parms;

    begin

      {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));

      {indicate this position in terms of minutes and seconds}

      Label2.Caption := ‘Format(%d:%.2d’, [StatusParms.dwReturn div 1000 div 60,

                               Trunc(Frac(StatusParms.dwReturn/1000/60)*60)]);

    end;
#### CD Audio MIDI offers the advantage of providing large musical scores with minimal space requirements. However, unless the user has a dedicated MIDI sound card (unlikely unless they are a musician), musical sound quality will always be less than perfect. Many games are circumventing this limitation by playing their musical scores directly off of the CD on which the game is distributed. This offers the highest possible sound quality, although the amount of music available to the game will be limited by the number of scores and their length, as CD audio requires much more storage space than MIDI files. The method by which data and music is stored on the CD varies. In a mixed-mode CD, all executable data must be placed in what a regular CD player would recognize as the first track. Multisession CDs do not have this requirement.
| Caution: While the application is accessing data from the CD, it cannot play a musical track, and vice versa.
The music data itself is stored on the CD in a format known as Red Book Audio. This format provides for stereo music at the highest quality, and is the format used by the professional music industry to record music onto conventional audio CDs. An interesting side effect to this arrangement is that a CD game taking advantage of Red Book Audio music can be placed into a conventional CD player and played as if it were any regular music CD. The data track will be nothing but white noise, but the musical tracks can be replayed as desired.
| Red Book Audio: The digital format used to store professional music on conventional audio CDs.
It is important to note that the end user’s machine must be set up correctly before it can play CD audio music. This involves installing a small wire that runs directly from the CD to the audio output hardware. While most new machines have this installed automatically, it may not always be available. Also, as an added benefit, this direct connection between the hardware results in true multitasking when playing CD audio. The audio signals are sent directly to the sound output hardware, bypassing the CPU completely. Thus, playing CD audio involves almost no CPU utilization, resulting in almost no performance penalties. Like MIDI music playback, several steps must be followed in order to initialize and commence the playback of a CD audio track. CD audio playback is implemented by performing these tasks: • Open the CD device • Check for the existence of the CD • Set the time format • Retrieve the number of tracks and their length • Commence playback • Stop playback • Close the device Open the CD Device If the music for a game is stored on a CD along with the executable code, the target machine must contain a CD-ROM drive in order to use the application. Thus, we do not need to check for the existence of a CD-ROM drive. However, it is good practice to test for the existence of a CD in the drive before attempting to play a track from it. This will be discussed in a moment. Like MIDI, we must first open the CD device. However, unlike MIDI, we do not need to specify a file. Again, we will need a variable of the type TMCI_Open_Parms, but this time its lpstrDeviceType member must be set to the string ‘cdaudio’. For example:
      {open the cd audio playback device}

      OpenParms.lpstrDeviceType := ‘cdaudio’;

      MCISendCommand(0, MCI_OPEN, MCI_OPEN_TYPE or MCI_WAIT, Longint(@OpenParms));

      {save a handle to the cd audio device}

      MCIDeviceID := OpenParms.wDeviceID;
Check for the Existence of the CD Once the CD audio device is opened, we can poll it to determine if a CD is actually inserted. To accomplish this, we need a variable of the type TMCI_Status_Parms. The dwItem member of this data structure must be set to MCI_STATUS_MEDIA_PRESENT to indicate that we wish to test for the presence of a CD in the drive. We then call the MCISendCommand function, passing MCI_STATUS in its second parameter. For example:
      {determine if a CD is present in the drive}

      StatusParms.dwItem := MCI_STATUS_MEDIA_PRESENT ;

      MCISendCommand(MCIDeviceID, MCI_STATUS, MCI_WAIT or MCI_STATUS_ITEM,

                     LongInt(@StatusParms));
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.