|
DirectMusic:
Playing MIDI files
By: Jack Hoxley
Written: June 2000
Difficulty: Easy
Description: How to play simple MIDI files through DirectX
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 attemps
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 fromt 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 basicically 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.
|