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:
- Can DirectMusic play wave
(.Wav) files? No.
- Can DirectMusic play mp3 Files?
No.
- 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.
|