5,317,180 members and growing! (22,273 online)
Email Password   helpLost your password?
Multimedia » Audio and Video » DirectMusic     Intermediate License: The GNU Lesser General Public License

Playing Midi files with DirectMusic

By Carlos Jiménez de Parga

A DirectX 8 class to perform Midi music playback.
VC6, C++, Windows, MFC, Visual Studio, VS6, Dev

Posted: 12 Nov 2001
Updated: 11 May 2003
Views: 165,097
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
21 votes for this Article.
Popularity: 5.82 Rating: 4.40 out of 5
0 votes, 0.0%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
3 votes, 27.3%
4
8 votes, 72.7%
5

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), segment files (.sgt) and PCM waveform files (.wav). 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 synthetizer.
  • FX (Reverb, Chorus...) if it is available in the software synthetizer.
  • 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 Intefaces 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:

Using CMidiMusic

In first sight 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:

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++;  // It is necessary

    }

     // Read the file and specify if it is a mid file or not 

    pMidi->LoadMidiFromFile("c:\\music\\song_004.mid",TRUE);
     // 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

Synthetizer

3D

Effects (Reverb,Chorus)

Segments(.sgt), Waves(.wav)

Microsoft Software

Yes

Only in not 3D mode

Only in 3D mode

Hardware

No

No

No

External

No

No

No

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.

History

  • 31 Jan 2002 - updated source files.
  • 12 May 2003 - updated source files

License

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

About the Author

Carlos Jiménez de Parga



Occupation: Software Developer
Location: Spain Spain

Other popular Audio and Video articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 76 (Total in Forum: 76) (Refresh)FirstPrevNext
Subject  Author Date 
QuestionMay I convert and redistribute your project?member_flix01_6:58 11 Jan '07  
AnswerRe: May I convert and redistribute your project?memberCarlos Jiménez de Parga7:37 11 Jan '07  
Question[WARNING] DirectMIDI on Windows Vista test - Information requestmemberCarlos Jiménez de Parga8:00 2 Jan '07  
Questionnewb needs tutorialsmemberlaserbeak431:27 3 May '06  
GeneralMusic timesussAnonymous3:38 26 Apr '05  
GeneralRe: Music timememberCarlos Jiménez de Parga6:40 26 Apr '05  
GeneralRe: Music timemembertongbj@hotmail.com3:01 29 Apr '05  
GeneralEditing the Midi filememberUhli0:41 24 Feb '05  
GeneralRe: Editing the Midi filememberCarlos Jiménez de Parga6:04 24 Feb '05  
GeneralTime position problem using MCImemberwanders8:55 1 Feb '05  
GeneralRe: Time position problem using MCImemberCarlos Jiménez de Parga9:41 1 Feb '05  
GeneralRe: Time position problem using MCImemberwanders11:36 1 Feb '05  
GeneralRe: Time position problem using MCImemberCarlos Jiménez de Parga23:01 1 Feb '05  
GeneralMIDI messages to multiple portsmemberEddieLotter9:41 24 Oct '04  
GeneralRe: MIDI messages to multiple portsmemberCarlos Jiménez de Parga23:48 25 Oct '04  
GeneralRe: MIDI messages to multiple portsmemberEddieLotter14:36 26 Oct '04  
GeneralCarlos, please contact mememberTitchener15:26 1 Sep '04  
Generalgetting the length in (milli)secondsmemberRüpel0:43 26 Aug '04  
GeneralRe: getting the length in (milli)secondsmemberCarlos Jiménez de Parga1:18 30 Aug '04  
GeneralRe: getting the length in (milli)secondsmembersolace1214:29 26 Nov '06  
GeneralRe: getting the length in (milli)seconds [modified]memberCarlos Jiménez de Parga5:13 26 Nov '06  
GeneralRe: getting the length in (milli)secondsmembersolace12116:56 3 Dec '06  
GeneralRe: getting the length in (milli)secondsmemberCarlos Jiménez de Parga1:04 4 Dec '06  
GeneralHelp me to show the lyricssussgenievn11:30 27 Jun '04  
GeneralRe: Help me to show the lyricsmemberCarlos Jiménez de Parga21:37 27 Jun '04  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 11 May 2003
Editor: Chris Maunder
Copyright 2001 by Carlos Jiménez de Parga
Everything else Copyright © CodeProject, 1999-2008
Web11 | Advertise on the Code Project