CFugue
CFugue usage examples

Contents

C Examples

Playing the Notes

    #include "CFugueLib.h"
    void main()
    {               
        CFugue::PlayMusicString("C D E F G A B"); // Play the Music Notes on the default MIDI output port
    }

Playing them Carnatic style:

    #include "CFugueLib.h"
    void main()
    {      
        CFugue::PlayMusicString("K[MELA_DEFAULT] S R G M P D N"); // Play the Music Notes on the default MIDI output port
    }

Saving Music Notes to MIDI output file

    #include "CFugueLib.h"
    void main()
    {           
        CFugue::SaveAsMidiFile("Cq Dw Ex", "MidiOutput.midi"); // Save the Music Notes to Midi file directly, without playing
    }

Configuring the Play Options

The PlayMusicString() method plays the music notes on default MIDI output port with default MIDI timer resolution. However, if you would like to configure these options, use the PlayMusicStringWithOpts() method. It works similar to the PlayMusicString() method, but directs the output based on the input options.

    #include "CFugueLib.h"
    void main()
    {
        CFugue::PlayMusicStringWithOpts(_T("Cq Dw Ex"), // CFugue MusicString to be played
                                                MIDI_MAPPER, // MIDI Output port
                                                48); // MIDI Timer Resolution in MilliSeconds
     }

Accessing the Parser events

A MusicString need be parsed before it can be played or rendered as sheet output. While performing the parsing operation, parser generates Trace events and Error events to let the caller know of the status. Callers can handle these events and output the Trace and Error information to a log file or appropriate UI.

Use the PlayMusicStringCB() method to add listeners to the parser trace and error events. Once subscribed, the attached listeners will be invoked during the parse phase. A sample demonstrating the procedure is below.

    #include "CFugueLib.h"
    void __stdcall OnParseTrace(void* pUserData, const TCHAR* szTraceMsg)
    {
        OutputDebugString(_T("\n"));
        OutputDebugString(szTraceMsg);
    }
    void __stdcall OnParseError(void* pUserData, long lErrCode, const TCHAR* szErrorMsg, const TCHAR* szToken);
    {
        OutputDebugString(_T("\nError --> "));
        OutputDebugString(szErrMsg);
        if(szToken != NULL)
        {
            OutputDebugString(_T("\t Token: "));     
            OutputDebugString(szToken);
        }
    }
    void main()
    {
        CFugue::PlayMusicStringCB(_T("Cq Dw Ex"), // CFugue MusicString to be played
                                        OnParseTrace, // Parse Trace Event Handler
                                        OnParseError, // Prase Error Event Handler
                                        NULL);
     }

Use PlayMusicStringWithOptsCB() method to subscribe handlers and also configure the Play options. Modified snippet looks like below.

    void main()
    {
        CFugue::PlayMusicStringWithOptsCB(_T("Cq Dw Ex"), // CFugue MusicString to be played
                                                MIDI_MAPPER, // MIDI Output port
                                                48, // MIDI Timer Resolution in MilliSeconds
                                                OnParseTrace, // Parse Trace Event Handler
                                                OnParseError, // Prase Error Event Handler
                                                NULL);
     }

C++ Examples

Playing the Notes

    #include "CFugueLib.h"
    void main()
    {       
        // Create the Player Object
        CFugue::Player player; 
        // Play the Music Notes on the default MIDI output port
        player.Play("C D E F G A B"); 
    }

Playing them Carnatic style:

    #include "CFugueLib.h"
    void main()
    {
        // Create the Player Object
        CFugue::Player player; 
        // Play the Music Notes on the default MIDI output port
        player.Play("K[MELA_DEFAULT] S R G M P D N"); 
    }

Saving Music Notes to MIDI output file

    #include "CFugueLib.h"
    void main()
    {    
        // Create the Player Object 
        CFugue::Player player;
        // Save the Music Notes to Midi file directly, without playing
        player.SaveAsMidiFile("Cq Dw Ex", "MidiOutput.midi"); 
    }

Sometimes you might want to play the Notes first on the MIDI output and then save the played content to an output file. You can achieve this using the Player::SaveToMidiFile() method. You need to call this method after the call to Player::Play() or Player::PlayAsync().

    #include "CFugueLib.h"
    void main()
    {   
        // Create the Player Object  
        CFugue::Player player; 
        // Play few Music Notes on MIDI output port
        player.Play("ci di K[MELA_22] Pa M G R"); 
        // Now, save that played content to a MIDI output file
        player.SaveToMidiFile("Output.mid"); 
    }

Asynchronous Play

The Player::Play() method plays the music notes synchronously, i.e. the method will not return till all the music notes are played completely. However, if you would like to play the MusicString content asynchronously, you can use the Player::PlayAsync() method instead. It works similar to the Play() method, except that it returns immediately.

    #include "CFugueLib.h"
    void main()
    {
        // Create the Player object
        CFugue::Player player; 
        // Start Playing Asynchronously 
        if(player.PlayAsync("Cx Dh Ah.")) 
            while(player.IsPlaying()) // Wait while the play is in progress
                Sleep(1000);
        // Match every PlayAsync with a StopPlay
        player.StopPlay(); 
    }

At any time after the call to PlayAsync, the Player::IsPlaying() method can be used to know if the play is still in progress. Player::StopPlay() allows you to stop the play if it is still in progress. Calling StopPlay() after every PlayAsync() call is a good practice (no matter if play is in progress or not). A typical usage of these methods is demonstrated in the above code snippet.

Accessing the Parser events

A MusicString need be parsed before it can be played or rendered as sheet output. While performing the parsing operation, parser generates Trace events and Error events to let the caller know of the status. Callers can handle these events and output the Trace and Error information to a log file or appropriate UI.

Use the Player::Parser() method to access the parser object associated with the player and subscribe to its evTrace and evError events. Once subscribed, the attached handlers will be invoked during the parse phase whenever any of the Play or Save methods is invoked on the player. A sample demonstrating the procedure is below.

    #include "CFugueLib.h"
    void OnParseTrace(const CFugue::CParser*, 
                CFugue::CParser::TraceEventHandlerArgs* pEvArgs)
    {
        OutputDebugString(_T("\n"));
        OutputDebugString(pEvArgs->szTraceMsg);
    }
    void OnParseError(const CFugue::CParser*,
                CFugue::CParser::ErrorEventHandlerArgs* pEvArgs)
    {
        OutputDebugString(_T("\nError --> "));
        OutputDebugString(pEvArgs->szErrMsg);
        if(pEvArgs->szToken)
        {
            OutputDebugString(_T("\t Token: "));     
            OutputDebugString(pEvArgs->szToken);
        }
    }
    void main()
    {
        // Create the Player Object
        CFugue::Player player; 
        // Access the Player's Parser and Subscribe to its Trace and Error Events
        player.Parser().evTrace.Subscribe(&OnParseTrace); 
        player.Parser().evError.Subscribe(&OnParseError);
        // Parse the Notes and Save the content to a MIDI file
        player.SaveAsMidiFile(_T("Cq Dw Ex"), "MidiOutput.midi"); 
     }

P/Invoke usage

Playing the Notes

public static class CFugueLib
{
    [DllImport("CFugueDll.Dll")]
    public static extern bool PlayMusicString([MarshalAs(UnmanagedType.LPStr)] String szMusicNotes);
}
public static void Main()
{    
    CFugue::PlayMusicString("Cq Dw Ex");// Play the Music Notes on default MIDI Output Port
}

Saving Music Notes to MIDI output file

public static class CFugueLib
{
    [DllImport("CFugueDll.Dll")]
    public static extern bool SaveAsMidiFile([MarshalAs(UnmanagedType.LPStr)] String szMusicNotes, [MarshalAs(UnmanagedType.LPStr)] String szOutputFilePath);
}
public static void Main()
{    
    CFugue::SaveAsMidiFile("Cq Dw Ex", "MidiOutput.mid");// Save the Music Notes to a MIDI file
}

Accessing the Parser events

A MusicString need be parsed before it can be played or rendered as sheet output. While performing the parsing operation, parser generates Trace events and Error events to let the caller know of the status. Callers can handle these events and output the Trace and Error information to a log file or appropriate UI.

Use the PlayMusicStringCB() method to add listeners to the parser trace and error events. Once subscribed, the attached listeners will be invoked during the parse phase. A sample demonstrating the procedure is below.

    public static class CFugueLib
    {
        public delegate void ParserTraceDelegate(IntPtr userData, [MarshalAs(UnmanagedType.LPStr)] String szTraceMsg);
        public delegate void ParserErrorDelegate(IntPtr userData, int errCode,
                                                [MarshalAs(UnmanagedType.LPStr)] String szErrorMsg,
                                                [MarshalAs(UnmanagedType.LPStr)] String szToken);
        [DllImport("CFugueDll.Dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void PlayMusicStringCB([MarshalAs(UnmanagedType.LPStr)] String szMusicNotes, 
                                                [MarshalAs(UnmanagedType.FunctionPtr)] ParserTraceDelegate td,
                                                [MarshalAs(UnmanagedType.FunctionPtr)] ParserErrorDelegate ed,
                                                IntPtr userData);
    }
    public void OnParseTrace(IntPtr userData, [MarshalAs(UnmanagedType.LPStr)] String szTraceMsg)
    {
        // Do something with szTraceMsg ... 
    }
    public void OnParseError(IntPtr userData, int errCode, [MarshalAs(UnmanagedType.LPStr)] String szErrorMsg, [MarshalAs(UnmanagedType.LPStr)] String szToken)
    {
        // Do something with szErrorMsg and szToken ... 
    }
void main()
{
    CFugueLib.PlayMusicStringWithOptsCB("C D E", // CFugue MusicString to be played
                                        new CFugueLib.ParserTraceDelegate(OnParseTrace), // Parse Trace Event Handler
                                        new CFugueLib.ParserErrorDelegate(OnParseError), // Prase Error Event Handler
                                        IntPtr.Zero);
 }

Use PlayMusicStringWithOptsCB() method to subscribe handlers and also configure the Play options. Modified snippet looks like below.

void main()
{
    CFugueLib.PlayMusicStringWithOptsCB("C D E", // CFugue MusicString to be played
                                            MIDI_MAPPER, // MIDI Output port
                                            48, // MIDI Timer Resolution in MilliSeconds
                                            new CFugueLib.ParserTraceDelegate(OnParseTrace), // Parse Trace Event Handler
                                            new CFugueLib.ParserErrorDelegate(OnParseError), // Prase Error Event Handler
                                            IntPtr.Zero);
 }

CFugue, the C++ Music Programming Library © Copyright 2009 Cenacle Research India Private Limited Gopalakrishna Palem