Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version

C# MIDI Toolkit

, 18 Apr 2007 MIT
A toolkit for creating MIDI applications with C#.
csharpmiditoolkitv4_demo.zip
CSharpMidiToolkitV4_demo
LSCollections.dll
MidiToolkitDemo
Properties
Settings.settings
MidiWatcher
Properties
Settings.settings
Multimedia.dll
Multimedia.Midi
Clocks
Device Classes
InputDevice Class
OutputDevice Classes
Messages
Message Builders
Multimedia.Midi.csproj.user
Processing
Sequencing
Midi File Player
Track Classes
UI
StateMachineToolkit.dll
csharpmiditoolkitv5_demo.zip
CSharpMidiToolkitV5_demo
MidiWatcher
Properties
Settings.settings
Sanford.Collections.dll
Sanford.Multimedia.dll
Sanford.Multimedia.Midi
Clocks
Device Classes
InputDevice Class
OutputDevice Classes
Messages
EventArgs
Message Builders
Processing
Sanford.Multimedia.Midi.csproj.user
Sequencing
Track Classes
UI
Sanford.Multimedia.Timers.dll
Sanford.Threading.dll
SequencerDemo
Properties
Settings.settings
miditoolkit_demo.zip
CSharpMidiToolkit
MidiToolkitDemo
App.ico
MidiToolkitDemo.csproj.user
Multimedia
Multimedia.csproj.user
Multimedia.Midi
Devices
Messages
Message Adaptors
MIDI File
Multimedia.MIDI.csproj.user
Sequencing
Synchronization
UI
miditoolkit_src.zip
MidiToolkit_src
Devices
Messages
MIDI File
Sequencing
TickGenerators
UI
/*
 * Created by: Leslie Sanford
 * 
 * Contact: jabberdabber@hotmail.com
 * 
 * Last modified: 05/08/2004
 */

using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Multimedia;

namespace Multimedia.Midi
{  
    /// <summary>
    /// Represents the method that will handle the event that occurs when an
    /// invalid short message is received.
    /// </summary>
    public delegate void InvalidShortMessageEventHandler(object sender, InvalidShortMsgEventArgs e);

    /// <summary>
    /// Represents Midi input device capabilities.
    /// </summary>
    public struct MidiInCaps
    {
        #region MidiInCaps Members

        /// <summary>
        /// Manufacturer identifier of the device driver for the Midi output 
        /// device. 
        /// </summary>
        public short mid; 

        /// <summary>
        /// Product identifier of the Midi output device. 
        /// </summary>
        public short pid; 

        /// <summary>
        /// Version number of the device driver for the Midi output device. The 
        /// high-order byte is the major version number, and the low-order byte 
        /// is the minor version number. 
        /// </summary>
        public int driverVersion;

        /// <summary>
        /// Product name.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
        public byte[] name;         

        /// <summary>
        /// Optional functionality supported by the device. 
        /// </summary>
        public int support; 

        #endregion
    }

	/// <summary>
	/// Represents Midi input devices.
	/// </summary>
	public class InputDevice : Component, IDevice, IMidiReceiver
	{
        #region InputDevice Members

        #region Delegates

        // Represents the method that handles messages from Windows.
        private delegate void MidiInProc(int handle, int msg, int instance,
            int param1, int param2); 
 
        #endregion

        #region Win32 Midi Input Functions and Constants
 
        [DllImport("winmm.dll")]
        private static extern int midiInOpen(ref int handle, int deviceId,
            MidiInProc proc, int instance, int flags);

        [DllImport("winmm.dll")]
        private static extern int midiInClose(int handle);

        [DllImport("winmm.dll")]
        private static extern int midiInStart(int handle);

        [DllImport("winmm.dll")]
        private static extern int midiInReset(int handle);

        [DllImport("winmm.dll")]
        private static extern int midiInPrepareHeader(int handle, 
            IntPtr header, int sizeOfmidiHeader);

        [DllImport("winmm.dll")]
        private static extern int midiInUnprepareHeader(int handle, 
            IntPtr header, int sizeOfmidiHeader);

        [DllImport("winmm.dll")]
        private static extern int midiInAddBuffer(int handle, 
            IntPtr header, int sizeOfmidiHeader);

        [DllImport("winmm.dll")]
        private static extern int midiInGetDevCaps(int handle, 
            ref MidiInCaps caps, int sizeOfmidiInCaps);

        [DllImport("winmm.dll")]
        private static extern int midiInGetNumDevs();

        [DllImport("winmm.dll")]
        private static extern int midiConnect(int inHandle, int outHandle, 
            int reserved);         

        [DllImport("winmm.dll")]
        private static extern int midiDisconnect(int inHandle, int outHandle, 
            int reserved); 

        private const int MMSYSERR_NOERROR = 0;
        private const int CALLBACK_FUNCTION = 0x30000; 
        private const int MIM_DATA = 0x3C3;
        private const int MIM_ERROR = 0x3C5;
        private const int MIM_LONGDATA = 0x3C4;
        private const int MHDR_DONE = 0x00000001;

        #endregion

        #region Constants

        // Number of system exclusive headers to use.
        private const int HeaderCount = 4;

        // System exclusive buffer size.
        private const int SysExBufferSize = 32000;

        #endregion

        #region Fields

        // Device handle.
        private int handle;

        // device Identifier.
        private int deviceId;

        // Indicates whether or not the device is open.
        private bool opened = false;

        // Indicates whether or not the device is recording.
        private bool recording = false;        

        // Represents the method that handles messages from Windows.
        private MidiInProc messageHandler;

        // Thread for managing messagess.
        private Thread messageManager;

        // Event used to signal when the device has received a message.
        private AutoResetEvent resetEvent = new AutoResetEvent(false);        

        // Queue for storing messages from Windows.
        private Queue messageQueue = new Queue();

        // Synchronized queue for messages.
        private Queue syncMsgQueue;

        // Midi headers for storing system exclusive messages.
        private MidiHeader[] headers = new MidiHeader[HeaderCount];

        // Pointers to headers. 
        private IntPtr[] ptrHeaders = new IntPtr[HeaderCount];       
        
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

        #endregion

        #region Construction

        /// <summary>
        /// Initializes a new instance of the InputDevice class.
        /// </summary>
        public InputDevice()
        {
            //
            // Required for Windows.Forms Class Composition Designer support
            //
            InitializeComponent();

            InitializeInputDevice();
        }

        /// <summary>
        /// Initializes an instance of the InputDevice class with the specified
        /// component container.
        /// </summary>
        /// <param name="container">
        /// The component container to add this instance of the InputDevice 
        /// class.
        /// </param>
		public InputDevice(IContainer container)
		{
			//
			// Required for Windows.Forms Class Composition Designer support
			//
			container.Add(this);
			InitializeComponent();

            InitializeInputDevice();
		}

        /// <summary>
        /// Initializes a new instance of the InputDevice class with the 
        /// specified device Id.
        /// </summary>
        /// <param name="deviceId">
        /// The device Id.
        /// </param>
        public InputDevice(int deviceId)
        {
            //
            // Required for Windows.Forms Class Composition Designer support
            //
            InitializeComponent();

            InitializeInputDevice();

            // Open device.
            Open(deviceId);
        }

        /// <summary>
        /// Initializes an instance of the InputDevice class with the specified
        /// component container and device Id.
        /// </summary>
        /// <param name="container">
        /// The component container to add this instance of the InputDevice 
        /// class.
        /// </param>
        /// <param name="deviceId">
        /// The device Id.
        /// </param>
        public InputDevice(IContainer container, int deviceId)
        {
            //
            // Required for Windows.Forms Class Composition Designer support
            //
            container.Add(this);
            InitializeComponent();

            InitializeInputDevice();

            // Open device.
            Open(deviceId);
        }

        #endregion        

        #region Component Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }
        #endregion

        #region Methods

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if(components != null)
                {
                    components.Dispose();
                }

                if(IsOpen())
                {
                    if(IsRecording())
                    {
                        Stop();
                    }

                    Close();
                }
            }
            base.Dispose( disposing );
        }        

        /// <summary>
        /// Connects to an output device for Midi thru operations.
        /// </summary>
        /// <param name="outDevice">
        /// The output device to connect to.
        /// </param>
        public void Connect(OutputDevice outDevice)
        {
            if(IsOpen() && outDevice.IsOpen())
            {
                midiConnect(handle, outDevice.DeviceHandle, 0);
            }
        }

        /// <summary>
        /// Disconnects from an output device to cease Midi thru operations.
        /// </summary>
        /// <param name="outDevice">
        /// The output device from which to disconnect.
        /// </param>
        public void Disconnect(OutputDevice outDevice)
        {
            if(IsOpen() && outDevice.IsOpen())
            {
                midiDisconnect(handle, outDevice.DeviceHandle, 0);
            }
        }

        /// <summary>
        /// Indicate whether or not the input device is open
        /// </summary>
        /// <returns>
        /// true if the device is open; otherwise, false.
        /// </returns>
        public bool IsOpen()
        {
            return opened;
        }   
     
        /// <summary>
        /// Indicates whether or not the device is recording.
        /// </summary>
        /// <returns>
        /// true if the device is recording; otherwise, false.
        /// </returns>
        public bool IsRecording()
        {
            return recording;
        }

        /// <summary>
        /// Gets the input device capabilities.
        /// </summary>
        /// <param name="deviceId">
        /// The device Identifier.
        /// </param>
        /// <exception cref="InputDeviceException">
        /// Thrown if an error occurred while retrieving the input device
        /// capabilities.
        /// </exception>
        /// <returns>
        /// The Midi intput device's capabilities.
        /// </returns>
        public static MidiInCaps GetCapabilities(int deviceId)
        {
            MidiInCaps caps = new MidiInCaps();

            ThrowOnError(midiInGetDevCaps(deviceId, ref caps, 
                Marshal.SizeOf(caps)));

            return caps;
        }

        /// <summary>
        /// Initializes input device.
        /// </summary>
        private void InitializeInputDevice()
        {
            // Create delegate for handling messages from Windows.
            messageHandler = new MidiInProc(OnMessage);            

            // Create synchronized queue for messages.
            syncMsgQueue = Queue.Synchronized(messageQueue);
        }

        /// <summary>
        /// Handles messages from Windows.
        /// </summary>
        private void OnMessage(int handle, int msg, int instance,
            int param1, int param2)
        { 
            // Only respond to messages if the device is in fact recording.
            if(IsRecording())
            {
                if(msg == MIM_DATA || msg == MIM_ERROR || msg == MIM_LONGDATA)
                {
                    syncMsgQueue.Enqueue(new Message(msg, param1, param2));
                    resetEvent.Set();            
                }
            }
        }

        /// <summary>
        /// Throw exception on error.
        /// </summary>
        /// <param name="errCode">
        /// The error code.
        /// </param>
        private static void ThrowOnError(int errCode)
        {
            // If an error occurred.
            if(errCode != MMSYSERR_NOERROR)
            {
                // Throw exception.
                throw new InputDeviceException(errCode);
            }
        }

        /// <summary>
        /// Thread method for managing Window messages.
        /// </summary>
        private void ManageMessages()
        {
            // While the device is recording.
            while(IsRecording())
            {
                // Wait for signal that a message has been received.
                resetEvent.WaitOne();

                // While the message queue is not empty.
                while(syncMsgQueue.Count > 0)
                {
                    // Get message from message queue.
                    Message msg = (Message)syncMsgQueue.Dequeue();

                    // Determine the type of message and act accordingly.
                    switch(msg.msg)
                    {
                        case MIM_DATA:
                            DispatchShortMessage(msg.param1, msg.param2);
                            break;

                        case MIM_ERROR:
                            DispatchInvalidShortMsg(msg.param1, msg.param2);
                            break;

                        case MIM_LONGDATA:
                            ManageSysExMessage(msg.param1, msg.param2);
                            break;

                        default:
                            break;
                    }                
                }
            }                
        }

        /// <summary>
        /// Determines the type of message received and triggers the correct
        /// event in response.
        /// </summary>
        /// <param name="message">
        /// The short Midi message received.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device 
        /// began recording.
        /// </param>
        private void DispatchShortMessage(int message, int timeStamp)
        {
            // Unpack status value.
            int status = ShortMessage.UnpackStatus(message);

            // If a channel message was received.
            if(ChannelMessage.IsChannelMessage(status))
            {
                // If anyone is listening for channel messages.
                if(ChannelMessageReceived != null)
                {
                    // Create channel message.
                    ChannelMessage msg = new ChannelMessage(message);

                    // Create channel message event argument.
                    ChannelMessageEventArgs e = 
                        new ChannelMessageEventArgs(msg, timeStamp);

                    // Trigger channel message received event.
                    ChannelMessageReceived(this, e);
                }
            }
            // Else if a system common message was received
            else if(SysCommonMessage.IsSysCommonMessage(status))
            {
                // If anyone is listening for system common messages
                if(SysCommonReceived != null)
                {
                    // Create system common message.
                    SysCommonMessage msg = new SysCommonMessage(message);

                    // Create system common event argument.
                    SysCommonEventArgs e = new SysCommonEventArgs(msg, timeStamp);

                    // Trigger system common received event.
                    SysCommonReceived(this, e);
                }
            }
            // Else if a system realtime message was received
            else if(SysRealtimeMessage.IsSysRealtimeMessage(status))
            {
                // If anyone is listening for system realtime messages
                if(SysRealtimeReceived != null)
                {
                    // Create system realtime message.
                    SysRealtimeMessage msg = new SysRealtimeMessage(message);

                    // Create system realtime event argument.
                    SysRealtimeEventArgs e = new SysRealtimeEventArgs(msg, timeStamp);

                    // Trigger system realtime received event.
                    SysRealtimeReceived(this, e);
                }
            }
        }

        /// <summary>
        /// Handles triggering the invalid short message received event.
        /// </summary>
        /// <param name="message">
        /// The invalid short message received.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device 
        /// began recording.
        /// </param>
        private void DispatchInvalidShortMsg(int message, int timeStamp)
        {
            if(InvalidShortMessageReceived != null)
            {
                InvalidShortMsgEventArgs e = 
                    new InvalidShortMsgEventArgs(message, timeStamp);

                InvalidShortMessageReceived(this, e);
            }
        }

        /// <summary>
        /// Manages system exclusive messages received by the input device.
        /// </summary>
        /// <param name="param1">
        /// Integer pointer to the header containing the received system
        /// exclusive message.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device 
        /// began recording.
        /// </param>
        private void ManageSysExMessage(int param1, int timeStamp)
        {
            // Get pointer to header.
            IntPtr ptrHeader = new IntPtr(param1);

            // If anyone is listening for system exclusive messages.
            if(SysExReceived != null)
            {
                // Imprint raw pointer on to structure.
                MidiHeader header = (MidiHeader)Marshal.PtrToStructure(ptrHeader, typeof(MidiHeader));
                
                // Dispatches system exclusive messages.
                DispatchSysExMessage(header, timeStamp);
            }
                
            // Unprepare header.
            ThrowOnError(midiInUnprepareHeader(handle, ptrHeader, 
                Marshal.SizeOf(typeof(MidiHeader))));                     

            // Prepare header to be used again.
            ThrowOnError(midiInPrepareHeader(handle, ptrHeader, 
                Marshal.SizeOf(typeof(MidiHeader)))); 
 
            // Add header back to buffer.
            ThrowOnError(midiInAddBuffer(handle, ptrHeader, 
                Marshal.SizeOf(typeof(MidiHeader))));
        }

        /// <summary>
        /// Handles triggering the system exclusive message received event.
        /// </summary>
        /// <param name="header">
        /// Midi header containing the system exclusive message.
        /// </param>
        /// <param name="timeStamp">
        /// Number of milliseconds that have passed since the input device 
        /// began recording.
        /// </param>
        private void DispatchSysExMessage(MidiHeader header, int timeStamp)
        {
            // Create array for holding system exclusive data.
            byte[] data = new byte[header.bytesRecorded - 1];

            // Get status byte.
            byte status = Marshal.ReadByte(header.data);
                
            // Copy system exclusive data into array (status byte is 
            // excluded).
            for(int i = 1; i < header.bytesRecorded; i++)
            {
                data[i - 1] = Marshal.ReadByte(header.data, i);
            }

            // Create message.
            SysExMessage msg = new SysExMessage((SysExType)status, data);

            // Raise event.
            SysExReceived(this, new SysExEventArgs(msg, timeStamp));
        }

        /// <summary>
        /// Create headers for system exclusive messages.
        /// </summary>
        private void CreateHeaders()
        {
            // Create headers.
            for(int i = 0; i < HeaderCount; i++)
            {
                // Initialize headers and allocate memory for system exclusive
                // data.
                headers[i].bufferLength = SysExBufferSize;
                headers[i].data = Marshal.AllocHGlobal(SysExBufferSize);

                // Allocate memory for pointers to headers. This is necessary 
                // to insure that garbage collection doesn't move the memory 
                // for the headers around while the input device is open.
                ptrHeaders[i] = 
                    Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MidiHeader)));
            }
        }

        /// <summary>
        /// Destroy headers.
        /// </summary>
        private void DestroyHeaders()
        {
            // Free memory for headers.
            for(int i = 0; i < HeaderCount; i++)
            {
                Marshal.FreeHGlobal(headers[i].data);
                Marshal.FreeHGlobal(ptrHeaders[i]);
            }
        }

        /// <summary>
        /// Unprepares headers.
        /// </summary>
        private void UnprepareHeaders()
        {
            // Unprepare each Midi header.
            for(int i = 0; i < HeaderCount; i++)
            {
                ThrowOnError(midiInUnprepareHeader(handle, ptrHeaders[i], 
                    Marshal.SizeOf(typeof(MidiHeader))));
            }
        }        

        #endregion

        #region Properties 
        
        /// <summary>
        /// Gets the number of intput devices present in the system.
        /// </summary>
        public static int DeviceCount
        {
            get
            {
                return midiInGetNumDevs();
            }
        }

        #endregion		

        #region Structs

        /// <summary>
        /// Represents a message sent by Windows to the input device.
        /// </summary>
        private struct Message
        {
            public int msg;
            public int param1;
            public int param2;

            public Message(int msg, int param1, int param2)
            {
                this.msg = msg;
                this.param1 = param1;
                this.param2 = param2;
            }
        }

        #endregion

        #endregion

        #region IDevice Members

        #region Methods

        /// <summary>
        /// Opens the InputDevice with the specified device Identifier.
        /// </summary>
        /// <param name="deviceId">
        /// The device Identifier.
        /// </param>
        /// <exception cref="InputDeviceException">
        /// Thrown if an error occurred while opening the input device.
        /// </exception>
        public void Open(int deviceId)
        {
            // If the device is already open.
            if(IsOpen())
            {
                // Close device before attempting to open it again.
                Close();
            }            

            // Open the device.
            ThrowOnError(midiInOpen(ref handle, deviceId, messageHandler, 0, 
                CALLBACK_FUNCTION));

            // Create headers for system exclusive messages.
            CreateHeaders();            

            // Indicate that the device is open.
            opened = true;

            // Keep track of device Identifier.
            this.deviceId = deviceId;
        }     
      
        /// <summary>
        /// Closes the InputDevice.
        /// </summary>
        /// <exception cref="InputDeviceException">
        /// Thrown if an error occurred while closing the input device.
        /// </exception>
        public void Close()
        {
            // If the device is open.
            if(IsOpen())
            {
                // If the device is recording.
                if(IsRecording())
                {
                    // Stop recording before closing the device.
                    Stop();
                }

                // Destroy headers for system exclusive messages.
                DestroyHeaders();                

                // Close the device.
                ThrowOnError(midiInClose(handle));

                // Indicate that the device is closed.
                opened = false;
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the device handle.
        /// </summary>
        public int DeviceHandle
        {
            get
            {
                return handle;
            }
        }     
   
        /// <summary>
        /// Gets the device Identifier.
        /// </summary>
        public int DeviceId
        {
            get 
            {
                return deviceId;
            }
        }

        #endregion

        #endregion

        #region IMidiReceiver

        #region Events

        /// <summary>
        /// Occurs when a channel message is received.
        /// </summary>
        public event ChannelMessageEventHandler ChannelMessageReceived;

        /// <summary>
        /// Occurs when a system common message is received.
        /// </summary>
        public event SysCommonEventHandler SysCommonReceived;

        /// <summary>
        /// Occurs when a system exclusive message is received.
        /// </summary>
        public event SysExEventHandler SysExReceived;

        /// <summary>
        /// Occurs when a system realtime message is received.
        /// </summary>
        public event SysRealtimeEventHandler SysRealtimeReceived;

        /// <summary>
        /// Occurs when an invalid short message is received.
        /// </summary>
        public event InvalidShortMessageEventHandler InvalidShortMessageReceived;

        #endregion

        #region Methods

        /// <summary>
        /// Starts recording Midi messages.
        /// </summary>
        /// <exception cref="InputDeviceException">
        /// Thrown if there was an error starting the input device.
        /// </exception>
        public void Start()
        {
            // If the device is open and it is not already recording.
            if(IsOpen() && !IsRecording())
            { 
                // Initializes headers for system exclusive messages.
                for(int i = 0; i < HeaderCount; i++)
                { 
                    // Reset flags.
                    headers[i].flags = 0;

                    // Imprint header structure onto raw memory.
                    Marshal.StructureToPtr(headers[i], ptrHeaders[i], false); 

                    // Prepare header.
                    ThrowOnError(midiInPrepareHeader(handle, ptrHeaders[i], 
                        Marshal.SizeOf(typeof(MidiHeader))));

                    // Add header to buffer.
                    ThrowOnError(midiInAddBuffer(handle, ptrHeaders[i], 
                        Marshal.SizeOf(typeof(MidiHeader))));                  
                }

                // Indicate that the device is recording.
                recording = true;

                // Create thread for managing messages.
                messageManager = new Thread(new ThreadStart(ManageMessages));

                // Start thread.
                messageManager.Start();

                // Wait for thread to become active.
                while(!messageManager.IsAlive)
                    continue;

                // Start recording.
                ThrowOnError(midiInStart(handle));
            }
        }

        /// <summary>
        /// Stop recording Midi messages.
        /// </summary>
        public void Stop()
        {
            // If the device is open.
            if(IsOpen())
            {
                // If the device is recording.
                if(IsRecording())
                {
                    // Indicate that the device is not recording.
                    recording = false;

                    // Clear out messages from message queue.
                    syncMsgQueue.Clear();

                    // Signal message thread to finish.
                    resetEvent.Set();

                    // Wait for message thread to finish.
                    messageManager.Join();

                    // Stop recording.
                    ThrowOnError(midiInReset(handle));  

                    // Unprepare headers.
                    UnprepareHeaders();
                }
            }
        }

        #endregion

        #endregion        
	}

    /// <summary>
    /// The exception that is thrown when a error occurs with the InputDevice
    /// class.
    /// </summary>
    public class InputDeviceException : ApplicationException
    {
        #region InputDeviceException Members

        #region Win32 Midi Input Error Function

        [DllImport("winmm.dll")]
        private static extern int midiInGetErrorText(int errCode, 
            StringBuilder errMsg, int sizeOfErrMsg);

        #endregion

        #region Fields

        // Error message.
        private StringBuilder errMsg = new StringBuilder(128);

        #endregion 

        #region Construction

        /// <summary>
        /// Initializes a new instance of the InputDeviceException class with
        /// the specified error code.
        /// </summary>
        /// <param name="errCode">
        /// The error code.
        /// </param>
        public InputDeviceException(int errCode)
        {
            // Get error message.
            midiInGetErrorText(errCode, errMsg, errMsg.Capacity);
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets a message that describes the current exception.
        /// </summary>
        public override string Message
        {
            get
            {
                return errMsg.ToString();
            }
        }

        #endregion

        #endregion
    }

    /// <summary>
    /// Provides data for the InvalidShortMsgEvent event.
    /// </summary>
    public class InvalidShortMsgEventArgs : EventArgs
    {
        #region InvalidShortMsgEventArgs Members

        #region Fields

        private int message;
        private int timeStamp;   
     
        #endregion

        #region Construction

        /// <summary>
        /// Initializes a new instance of the InvalidShortMsgEventArgs class 
        /// with the specified message and time stamp.
        /// </summary>
        /// <param name="message">
        /// The invalid short message as an integer. 
        /// </param>
        /// <param name="timeStamp">
        /// Time in milliseconds since the input device began recording.
        /// </param>
        public InvalidShortMsgEventArgs(int message, int timeStamp)
        {
            this.message = message;
            this.timeStamp = timeStamp;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Invalid short message as an integer.
        /// </summary>
        public int Message
        {
            get
            {
                return message;
            }
        }

        /// <summary>
        /// Time in milliseconds since the input device began recording.
        /// </summary>
        public int TimeStamp
        {
            get
            {
                return timeStamp;
            }
        }

        #endregion

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Leslie Sanford

United States United States
Aside from dabbling in BASIC on his old Atari 1040ST years ago, Leslie's programming experience didn't really begin until he discovered the Internet in the late 90s. There he found a treasure trove of information about two of his favorite interests: MIDI and sound synthesis.
 
After spending a good deal of time calculating formulas he found on the Internet for creating new sounds by hand, he decided that an easier way would be to program the computer to do the work for him. This led him to learn C. He discovered that beyond using programming as a tool for synthesizing sound, he loved programming in and of itself.
 
Eventually he taught himself C++ and C#, and along the way he immersed himself in the ideas of object oriented programming. Like many of us, he gotten bitten by the design patterns bug and a copy of GOF is never far from his hands.
 
Now his primary interest is in creating a complete MIDI toolkit using the C# language. He hopes to create something that will become an indispensable tool for those wanting to write MIDI applications for the .NET framework.
 
Besides programming, his other interests are photography and playing his Les Paul guitars.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 18 Apr 2007
Article Copyright 2004 by Leslie Sanford
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid