Main Site Links Resources Tutorials
News VB Gaming Code Downloads DirectX 7
Contact Webmaster VB Programming Product Reviews DirectX 8
  General Multimedia Articles DirectX 9
      Miscellaneous

DirectMusic: Playing MIDI files
By: Jack Hoxley
Written: June 2000
Download:
DM_Midi.Zip (8kb)


Thankfully; playing MIDI files are very easy and take very little control. In other words, once set up and playing you can pretty much leave them alone and they'll just keep on going. This is very useful when it comes to programming; as it means it is easier to write and as there is less interaction there are fewer places for errors.

There is one slight problem with DirectMusic in general - you'll need to have some musical skill (or know someone who has) and you'll need some software to write the music. There is little point in having music in your game if it is so poor your player always turns it off.

There is also one other thing to bare in mind. I always get asked three questions by people programming DirectMusic:

  1. Can DirectMusic play wave (.Wav) files? No.
  2. Can DirectMusic play mp3 Files? No.
  3. Can DirectMusic play CD-audio? No.

Remember that before asking someone! Although I have seen several third-party attempts to convert Mp3 to Wave file on the fly (so that DirectSound can play them) it's never been vary stable and it's been VERY slow - no good for games. You may well think that no CD-audio or Mp3 makes DirectMusic a bit useless; far from t he truth. DirectMusic supports MIDI and DLS files, both of which are very reasonable music formats. Because this tutorial is only about MIDI I'll explain it, DLS will be explained in it's own tutorial

MIDI
MIDI is basically a single track of music; almost like an Mp3 or a CD-audio track, when using DirectMusic, you create the buffers to hold the music, load the whole piece into the buffer and play it. It keeps on playing until either the sound has finished, or you tell it to stop. MIDI has often been associated with not being brilliant quality, and sounding very electronic/computer like; although this is true of some pieces of music, and especially on older sound cards, the new sound cards and/or drivers are capable of making very good quality music. MIDI is much easier to program than DLS, as it is fairly automated.

The code is very simple for MIDI. Although this will offer you no information, and no control of anything it will show you the very basics of DirectMusic.

Open up visual basic and create a standard EXE with a single form. Connect the project to DirectX through the reference library (you what?) and create 4 command buttons. name them, CmdStep1, CmdStep2, CmdStep3 and CmdStep4. You can think of imaginative captions as well; but something along the lines of: "init", "Load", "Play" and "stop".

Step1: Initialising
Initialisation must be done first, it involves linking up with the hardware, creating various objects and setting their properties:

'Declarations Section of a form:
Option Explicit

'''''''We need a root object:
Dim dx As New DirectX7
'A performance controls the music. It looks after
'sending data to the music port, setting options
'converting time sigs. etc...

Dim perf As DirectMusicPerformance
'A segment is where the actual data is stored;
'like a buffer or a surface in other DirectX objects

Dim seg As DirectMusicSegment
'This variable lets us know what the music is
'doing. At the simplest level this is "am I playing?"
'"am i stopped?" etc.......

Dim segstate As DirectMusicSegmentState
'A loader object is what parses the data from a file
'on the hard drive to the area in memory.

Dim loader As DirectMusicLoader


'This goes in the command button for step 1.
Private Sub cmdStep1_Click()
On Error GoTo LocalErrors

'Create our loader object. Used in cmdStep2
Set loader = dx.DirectMusicLoaderCreate()

'A performance is what organises the events
'think of it as a conductor - syncronising things
'setting things up; looking after the individual pieces
'of music.

'Create the performance

Set perf = dx.DirectMusicPerformanceCreate()
'initialise it
Call perf.Init(Nothing, 0)
'Set it's options - these options should be standard
'across most projects.

perf.SetPort -1, 80
Call perf.SetMasterAutoDownload(True)

'The 75 in the next statement can be any number between 0 (mute)
'and 100 (max). The formula just uses this number to create a
'volume DM can understand.

perf.SetMasterVolume (75 * 42 - 3000)

'Just some UI stuff to stop
'you doing things in the wrong order and screwing things
'up..... ;)

cmdStep1.Enabled = False
cmdStep2.Enabled = True

Exit Sub
LocalErrors:
End Sub

Step2: Loading Some data
Step two is fairly simple. But it wont work unless you have the Media components installed in windows. To save you from downloading an extra MIDI file here I choose to pick one that's likely to be on your computer. If you do not have the required Midi file, just edit the line of code that specifies the line of code.

Private Sub cmdStep2_Click()
'A variable to hold our file name...
Dim FILENAME As String

On Error GoTo LocalErrors

'We'll just hope that this file exists. It's only a tutorial
'after all ;-)

FILENAME = "c:\windows\media\passport.mid"

'Use the loader object to create us a music buffer

Set seg = loader.LoadSegment(FILENAME)

'Set the format of the segment to be a MIDI.

seg.SetStandardMidiFile

cmdStep2.Enabled = False
cmdStep3.Enabled = True
Exit Sub

LocalErrors:
MsgBox "There was an Error; music may not have been loaded correctly"
End Sub

Simple really!

Step3: Playing the Music
Playing the music in this case is extremely easy; but if you want to start doing clever things it may well get more complicated.

Private Sub cmdStep3_Click()
'This is all it takes to start playing.
'The last variable states where to start playing from; in this case "0", which means the
'beginning.

Set segstate = perf.PlaySegment(seg, 0, 0)
cmdStep3.Enabled = False
CmdStep4.Enabled = True
End Sub

Step4: Stopping the Music
Stopping the music is equally as easy:

Private Sub CmdStep4_Click()
Call perf.Stop(seg, segstate, 0, 0)
CmdStep4.Enabled = False
cmdStep3.Enabled = True
End Sub

Step5: Cleaning up
This is the only difficult part; and even then the only difficult part is remembering to do it! Although it isn't essential, it is advised to clean up after you, rather than dropping DirectX and Windows the job. Cleaning up in this instance means closing the performance, which in turn unhooks our application from the hardware.

Private Sub Form_Unload(Cancel As Integer)
If Not (perf Is Nothing) Then perf.CloseDown
End Sub

There; finished. You can now load and play your own MIDI files. A later tutorial will show you how to modify the music and get the information about the piece. Then the final tutorial will show you how to loop your music - once you understand that you'll have an easy music engine in your pocket.

You can download a working example from the top of this page, or from the downloads page.

DirectX 4 VB 2000 Jack Hoxley. All rights reserved.
Reproduction of this site and it's contents, in whole or in part, is prohibited,
except where explicitly stated otherwise.
Design by Mateo
Contact Webmaster