Using MIDI with NAudio

This is a quick and small program in C# to get started with MIDI programming using NAudio. There are other libraries for .NET which can be used for MIDI programming but NAudio has the reputation of being a very stable and updated library, so I have gone along with it.

This program only does two things:

  • Enumerate MIDI devices
  • Track MIDI IN messages from a MIDI keyboard.

Given below is the output when no MIDI keyboard is attached. The Microsoft GS WaveTable Synth is a default MIDI output device which comes as part of Windows 10. We are looking for an MIDI input device which can be queried for MIDI messages. In this case , there is none:

Next we attach a MIDI keyboard and we assume that the first device found in the list of MIDI IN devices is our target device. Here I have attached an Impact ix61 MIDI Controller keyboard and it shows its MIDI device names in the list.

Now we create a MIDI Input device object in NAudio and start tracking its events. As each event is received, it is dumped on the Console. Here I am pressing keys on the MIDI keyboard.

The source code is given below. Create a Windows .NET Console project and use Nuget to add a reference to NAudio.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NAudio.Midi;

namespace MidiTest
{
    class Program
    {
        static int mInDeviceIndex = -1;
        static int mOutDeviceIndex = -1;
        static MidiIn mMidiIn = null;
        static Boolean mReady = false;


        static void Main(string[] args)
        {
            listDevices();
            if (mReady)
            {
                handleMidiMessages();
                Console.ReadLine();

                mMidiIn.Stop();
                mMidiIn.Dispose();
            }
        }

        public static void listDevices()
        {
            Console.WriteLine("MIDI In Devices");
            Console.WriteLine("===============");
            for (int device = 0; device < MidiIn.NumberOfDevices; device++)
            {
                mReady = true; //  some midi in device exists
                Console.WriteLine(MidiIn.DeviceInfo(device).ProductName);
            }
            mInDeviceIndex = 0;
            Console.WriteLine("\n\n\nMIDI Out Devices");
            Console.WriteLine("=====================");
            for (int device = 0; device < MidiOut.NumberOfDevices; device++)
            {
                Console.WriteLine(MidiOut.DeviceInfo(device).ProductName);
            }
            mOutDeviceIndex = 1;
        }

        public static void handleMidiMessages()
        {
            mMidiIn = new MidiIn(mInDeviceIndex);
            mMidiIn.MessageReceived += midiIn_MessageReceived;
            mMidiIn.ErrorReceived += midiIn_ErrorReceived;
            mMidiIn.Start();


        }

        static void midiIn_ErrorReceived(object sender, MidiInMessageEventArgs e)
        {
            Console.WriteLine(String.Format("Time {0} Message 0x{1:X8} Event {2}",
                e.Timestamp, e.RawMessage, e.MidiEvent));
        }

        static void midiIn_MessageReceived(object sender, MidiInMessageEventArgs e)
        {
            Console.WriteLine(String.Format("Time {0} Message 0x{1:X8} Event {2}",
                e.Timestamp, e.RawMessage, e.MidiEvent));
        }
    }
}

Be the first to comment

Leave a Reply

Your email address will not be published.


*