Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / MFC

Playing Midi Files with DirectMusic

Rate me:
Please Sign up or sign in to vote.
4.83/5 (17 votes)
30 Dec 2010LGPL34 min read 375.3K   6.4K   64   77
A DirectX 8 class to perform Midi music playback
Image 1

Introduction

This article focuses on the use of CMidiMusic which allows an easy access to DirectX DirectMusic API. This class allows loading and playing general midi sequence files(.mid). The class is designed to perform midi playback in one segment and offers additional features like using any midi port installed in your system, 3D sound environment, sound effects, etc.

Direct Audio Specifications

The DirectX 8.0 Audio part offers improved integration between DirectSound and DirectMusic, including a great set of new features. Some of these are listed hereafter:

  • The last version of Direct Audio allows using hardware acceleration for sound synthesis.
  • With the new AudioPath model, the sound of a port does not go directly to a directsound buffer, instead, it goes to an audiopath which controls data flow from a performance to the final output. The audiopath allows controlling the 3D position of each sound and adding other effects.
  • The segments are modified independently and you can apply effects like pan, volume, individually.
  • It allows using DLS2 (Downloadable sound level 2 standard) which provides a great sound quality and unlimited use of instruments with the software synthesizer.
  • FX (Reverb, Chorus...) if it is available in the software synthesizer.
  • It overcomes the 16 midi channels limit, allowing the use of as many midi channels as the software is able to handle.
  • The playback can be controlled accurately in run time by selecting different sets of musical variations and changes in the chords progress.
  • 3D Positioning.

Main Interfaces of DirectMusic

  • IDirectMusic8: This interface allows managing buffers and ports. There should only exist one instance of this interface per application.
  • IDirectMusicPerformance8: This is the most important interface in playback management. It is used to add and remove ports, play segments, notify event reception, control music parameters and obtain timing information.
  • IDirectMusicPort8: This interface provides access to DirectMusicPorts objects like MPU-401 or the software synthesizer.
  • IDirectMusicSegment8: This interface represents a segment, musical piece made up of multiple tracks. It can contain a midi file, a wave, a segment.
  • IDirectMusicLoader8: Its main function is to find and load the different objects. These objects are to be stored in a segment.
  • IDirectMusicSegmentState8: The (playback) engine creates a SegmentState object which allows analyzing the state of the segment currently playing.
  • IDirectMusicAudioPath8: The IDirectMusicAudioPath8 interface represents the stages of data flow from the data file to the primary buffer.

DirectMusic Architecture

Once a resource has been loaded in a segment, the performance dispatches the messages defined by a tool of an application, such tools are grouped in toolgraphs which process specific segment messages. A tool can modify a message and pass it on, delete it, or send a new message.

Finally, the messages are delivered to the output tool, which converts the data to MIDI format before passing it to the synthesizer. Channel-specific MIDI messages are directed to the appropriate channel group on the synthesizer. The synthesizer creates sound waves and streams them to a device called a sink, which manages the distribution of data through buses to DirectSound buffers.

There are three kinds of buffers:

  • Sink-in buffers are DirectSound secondary buffers into which the sink streams data. Here are applied many effects like 3D, pan, volume, etc...The resulting waveform is passed either directly to the primary buffer or to one or more mix-in buffers.
  • Mix-in buffers receive data from other buffers, apply effects, and mix the resulting wave forms. These buffers can be used to apply global effects.
  • The primary buffer performs the final mixing on all data and passes it to the rendering device.

The following diagram shows the flow of data from files to the speakers:

Image 2

Using CMidiMusic

In first sight, it is necessary to add in Visual C++ IDE this library: Go to Project -> Settings -> Object Library Modules and add dxguid.lib of DirectX8 SDK.

After this, it will be necessary to include in the project the header "dmusic.h" and "dmusic.cpp" file and finally instance an object of CMidiMusic class type as shown below:

C#
void CPlayerDlg::OnButton_Start()     
{
    DWORD dwcount; // Counter variable to enumerate the midi ports 
    INFOPORT Info; // INFOPORT structure to store port information 
    BOOL bSelected;

    CMidiMusic *pMidi;     // Pointer to CMidiMusic object type
    pMidi=new CMidiMusic;     // Allocate it      
    pMidi->Initialize(FALSE);// Initialize without 3D positioning
    
    dwcount=0;
    bSelected=FALSE;
    
     // Port enumeration  phase 
     // It is necessary to supply a port counter 
    while (pMidi->PortEnumeration(dwcount,&Info)==S_OK)
    {
        // Ensure it is an output hardware device
        if (Info.dwClass==DMUS_PC_OUTPUTCLASS) 
        {
            if (!((Info.dwFlags & DMUS_PC_SOFTWARESYNTH) || bSelected))
            {
                // Select the enumerated port 
                pMidi->SelectPort(&Info);
                bSelected=TRUE;
            }
        }
    
    dwcount++;      
   }

     // Read the MIDI file 
    pMidi->LoadMidiFromFile("c:\\music\\song_004.mid");
     // Play the file
    pMidi->Play();
    AfxMessageBox("Playing...");
     // Stop it
    pMidi->Stop();

    //Important!: Delete the pointer to the object in order to call the 
    //destructor 
    //which call the DirectMusic releases interfaces
    delete pMidi;
}

CMidiMusic Capabilities

Synthesizer3D Effects (Reverb,Chorus)
Microsoft SoftwareYesOnly in not 3D mode
HardwareNoNo
ExternalNoNo

More Information

For more information about the CMidiMusic class, read the attached file readme.txt included in the sources. You will be able to find more information in the online help of http://www.microsoft.com/directx and DirectX 8 SDK technical documentation.

Overview of the Demo Project

As you can see, this is not WinAmp, wish it was. ;) Nevertheless, all of CMidiMusic class features are made available.

Image 3

History

  • 31 Jan 2002 - Updated source files
  • 12 May 2003 - Updated source files
  • 28 Dec 2010 - Updated article and source files

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer
Spain Spain
I obtained my PhD degree in Computer Graphics at the National Distance Education University (UNED) in October 2019. I also hold a Ms. degree in Software Engineering and Computer Systems and a Bs. degree in Computer Science from the National Distance Education University (UNED).
I have been employed as a C++ software developer in several companies since year 2000.
I currently work as a Tutor-Professor of Symbolic Logic, Discrete Math and Java Object-Oriented Programming at UNED-Cartagena (Spain) since 2015.

Comments and Discussions

 
GeneralRe: How to save part of midi data into new midi file? Pin
vachel18-Feb-04 21:57
vachel18-Feb-04 21:57 
GeneralRe: How to save part of midi data into new midi file? Pin
glushkin3-Mar-12 1:34
glushkin3-Mar-12 1:34 
QuestionWhy not have sound after pressing Play? Pin
vachel11-Feb-04 22:23
vachel11-Feb-04 22:23 
AnswerRe: Why not have sound after pressing Play? Pin
Carlos Jiménez de Parga12-Feb-04 4:10
Carlos Jiménez de Parga12-Feb-04 4:10 
GeneralRe: Why not have sound after pressing Play? Pin
Anonymous18-Feb-04 17:26
Anonymous18-Feb-04 17:26 
GeneralRe: Why not have sound after pressing Play? Pin
vachel18-Feb-04 17:29
vachel18-Feb-04 17:29 
GeneralSending SysEx in DirectMusic Pin
HPlate6-Feb-04 3:58
HPlate6-Feb-04 3:58 
GeneralRe: Sending SysEx in DirectMusic Pin
HPlate7-Feb-04 3:58
HPlate7-Feb-04 3:58 
GeneralRe: Sending SysEx in DirectMusic Pin
Carlos Jiménez de Parga7-Feb-04 22:23
Carlos Jiménez de Parga7-Feb-04 22:23 
Hi Heiko

I saw your web site about your MIDI file library and it looks very
interesting!

Concerning your question about SysEx sending, I must point out that I tried to send a MIDI file containing a SysEx track with the MidiPlayer demo application and it worked right. I used a 70KB .mid file containing
instrument definitions with my Korg X5 and it didn't get any problem.
I don't know if you are attempting to send files of .syx type or any other binary format. What I can say is that DirectMusic, in particular the DirectMusicLoader8::GetObjectFromFile, only handles with MIDI, WAV, DLS or SGT file formats. Therefore, if you need to send SysEx data in a playing sequence the best solution is to embed it into a MIDI file.

Regards
GeneralRe: Sending SysEx in DirectMusic Pin
HPlate8-Feb-04 8:56
HPlate8-Feb-04 8:56 
Generalresource-script newbie help Pin
mr. Alex13-Jan-04 10:46
mr. Alex13-Jan-04 10:46 
GeneralRe: resource-script newbie help Pin
Carlos Jiménez de Parga13-Jan-04 20:46
Carlos Jiménez de Parga13-Jan-04 20:46 
GeneralRe: resource-script newbie help Pin
mr. Alex14-Jan-04 6:02
mr. Alex14-Jan-04 6:02 
Generalwhy not load?.....help me... Pin
Mr. Simson12-Nov-03 1:34
sussMr. Simson12-Nov-03 1:34 
GeneralRe: why not load?.....help me... Pin
Carlos Jiménez de Parga15-Nov-03 4:53
Carlos Jiménez de Parga15-Nov-03 4:53 
GeneralAdd a midi mixer Pin
Tomba313-Jul-03 23:20
Tomba313-Jul-03 23:20 
GeneralRe: Add a midi mixer Pin
Carlos Jiménez de Parga15-Jul-03 6:01
Carlos Jiménez de Parga15-Jul-03 6:01 
GeneralRe: Add a midi mixer Pin
Tomba320-Jul-03 1:42
Tomba320-Jul-03 1:42 
GeneralRe: Add a midi mixer Pin
Carlos Jiménez de Parga21-Jul-03 23:24
Carlos Jiménez de Parga21-Jul-03 23:24 
GeneralRe: Add a midi mixer Pin
Tomba324-Jul-03 0:14
Tomba324-Jul-03 0:14 
GeneralRe: Add a midi mixer Pin
Carlos Jiménez de Parga24-Jul-03 23:14
Carlos Jiménez de Parga24-Jul-03 23:14 
GeneralRe: Add a midi mixer Pin
Tomba329-Jul-03 0:16
Tomba329-Jul-03 0:16 
GeneralRe: Add a midi mixer Pin
Carlos Jiménez de Parga29-Jul-03 4:32
Carlos Jiménez de Parga29-Jul-03 4:32 
QuestionHow to analyze an midi file? Pin
ICE_WIZARD23-Jun-03 5:18
ICE_WIZARD23-Jun-03 5:18 
GeneralI have one question: about pause a wave file Pin
bullzeye10-Apr-03 0:53
bullzeye10-Apr-03 0:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.