| 
 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. 
                                       |