MusIT

Class MidiKeyboard – Connect MIDI keyboard and device

The MidiKeyboard class is available with the Pro version to read or write MIDI events from a MIDI keyboard connected to your computer.

If you only need to read MIDI messages from your device, you may prefer to use the ready-made MidiInReader (also based on the MidiKeyboard class).

Setup

To connect an external MIDI device, Unity needs a plugin to provide core functions such as list, select, open devices, write or read MIDI messages.

Download MidiKeyboard_V1.2.1_Plugins.unitypackage.zip here

  • Unzip to get the Unity package file inside the downloaded file.
  • Import this package into your Unity editor (see the Unity documentation). You will get something like this in your project window:
This image has an empty alt attribute; its file name is MidiKeyboard-1.2.1.png
Plugins folder after import
  • Remove unused plugins. For example, if you have a newer Mac with a Silicon CPU, keep only the MacOSSilicon folder (optional).

Known limitations:

  • Tested with:
    • Windows 10 or higher, CPU 64 bits.
    • MacOS 10.1 or higher, CPU Intel/AMD CPU or Apple Silicon (M1, M2, ..).
  • Not available on Android and IOs.
  • Cannot handle sysex messages (maybe in the future, if needed!).

Class MidiKeyboard

The class MidiKeyboard is static. Cool, there is no need to allocate object. We like simple thing! This page could also help you for writing script for MPTK.

On top of that, the schema is classical and you will find all the details of the class MidiKeyboard in the API Reference like:

  • List connect devices (USB, MIDI port or internal).
  • Open a device for writing MIDI events.
  • Open all devices for reading.
  • Read or write MIDI events to the device.
  • Close the device.
  • Full integration with Maestro MPTK (MPTKEvent, MIDI Synth, Effect, …)

API Reference for the class MidiKeyboard

Demos

As usual with Maestro MPTK, demonstrations are available.

Just Read MIDI event

A very simple script for reading MIDI events from a MIDI device.
For testing:

  • Create a new scene in your Unity Editor (or use an existing one).
  • Add an empty gameObject (or use an existing one).
  • Copy / Paste this script in a C# file.
  • Add this script to your gameObject.
  • Connect your MIDI keyboard and run!
C#
using UnityEngine;
using System;
using MidiPlayerTK;

namespace DemoMPTK
{
    /// <summary>@brief
    /// Example of MVP implementation for reading MIDI event from a keyboard. 
    /// See here for detailed API doc:
    ///       https://mptkapi.paxstellar.com/da/d70/class_midi_player_t_k_1_1_midi_keyboard.html
    /// For testing:
    ///     - create a new scene
    ///     - add an empty gameObject
    ///     - add this script to the gameObject
    ///     - connect your MIDI keyboard and run!
    /// </summary>

    public class MidiKeyboardInput : MonoBehaviour
    {
        private void Start()
        {
            // Midi Keyboard need to be initialized at start
            MidiKeyboard.MPTK_Init();

            // Log version of the Midi plugins
            Debug.Log(MidiKeyboard.MPTK_Version());

            // Open or refresh all input MIDI devices able to send MIDI message
            MidiKeyboard.MPTK_OpenAllInp();
        }

        private void OnApplicationQuit()
        {
            // Mandatory to avoid Unity crash!
            MidiKeyboard.MPTK_CloseAllInp();
        }

        void Update()
        {
            int count = 0;
            try
            {
                MidiKeyboard.PluginError status = MidiKeyboard.MPTK_LastStatus;
                if (status != MidiKeyboard.PluginError.OK)
                    Debug.LogWarning($"MIDI Keyboard error, status: {status}");

                // Read message available in the queue
                // Limit the count of read messages to avoid locking Unity
                while (count < 100)
                {
                    count++;

                    // Read a MIDI event if available
                    MPTKEvent midievent = MidiKeyboard.MPTK_Read();

                    // No more Midi message
                    if (midievent == null)
                        break;

                    // ... and log 
                    Debug.Log($"[{DateTime.UtcNow.Millisecond:00000}] {midievent}");
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
    }
}

Read and Write with Unity User Interface

It’s a complete demonstration of the features you might need. Load the demonstration scene:

Load the demo scene
connect a MIDI keyboard like a synthesizer to your application
Scene TestMidiKeyboard is running

Thank to Giuseppe and his free asset ScreenLogger which was helpful to build this demo and test it on device.

Below is an excerpt from the demonstration script where the key methods of the MidiKeyboard class are emphasized.

Warning: Do not copy paste directly this code, it’s an extract of full C# file, it will not work!

This code is meant as a demonstration of how to implement the API and is tailored for the Unity scene “TestMidiKeyboard”. It could serves as an excellent foundation for your own project!

C#
private void Start(){
    // Midi Keyboard need to be initialized at start
    MidiKeyboard.MPTK_Init();

    // Log version of the Midi plugins
    Debug.Log(MidiKeyboard.MPTK_Version());

    // Open or close all Midi Input Devices
    ToggleRead.onValueChanged.AddListener((bool state) =>
    {
        if (state)
            MidiKeyboard.MPTK_OpenAllInp();
        else
            MidiKeyboard.MPTK_CloseAllInp();
        CheckStatus($"Open/close all input");
    });

    // Read or not system message (not sysex)
    ToggleMsgSystem.onValueChanged.AddListener((bool state) =>
    {
        MidiKeyboard.MPTK_ExcludeSystemMessage(state);
    });

    // Read preset value and send a midi message to change preset on the device 'index"
    InputPreset.OnEventValue.AddListener((int val) =>
    {
        int index = InputIndexDevice.Value;
        // send a patch change
        MPTKEvent midiEvent = new MPTKEvent()
        {
            Command = MPTKCommand.PatchChange,
            Value = InputPreset.Value,
            Channel = InputChannel.Value,
            Delay = 0,
        };
        MidiKeyboard.MPTK_PlayEvent(midiEvent, index);
        CheckStatus($"Play PatchChange {index}");
    });
}
// Open a device for output. 
public void OpenDevice() {
        index = InputIndexDevice.Value;
        MidiKeyboard.MPTK_OpenOut(index);
        CheckStatus($"Open Device {index}");
}
// Play ore note
public void PlayOneNote(int random) {
    MPTKEvent midiEvent;
    int index = InputIndexDevice.Value;
    // playing a NoteOn
    midiEvent = new MPTKEvent() {
        Command = MPTKCommand.NoteOn,
        Value = InputNote.Value + random,
        Channel = InputChannel.Value,
        Velocity = 0x64, // Sound can vary depending on the velocity
        Delay = 0,
    };
    MidiKeyboard.MPTK_PlayEvent(midiEvent, index);
    CheckStatus($"Play NoteOn {index}");

    // Send Notoff with a delay of 2 seconds
    midiEvent = new MPTKEvent() {
        Command = MPTKCommand.NoteOff,
        Value = InputNote.Value + random,
        Channel = InputChannel.Value,
        Velocity = 0,
        Delay = 2000,
    };
    MidiKeyboard.MPTK_PlayEvent(midiEvent, index);
    // When event is delayed, last status is sent when event is send, so after the delay!
}

// Read message from the keyboard
private void Update() {
    if (ToggleRead.isOn) {
        // Process the message queue by max 100 to avoid locking Unity
        while (count++ < 100) {
            // Parse the message.
            MPTKEvent midievent = MidiKeyboard.MPTK_Read();

            // No more Midi message
            if (midievent == null)
                break;
            Debug.Log($"[{DateTime.Now.Millisecond:00000}] {midievent}");
        }
    }
}

Have fun!

Get MPTK from the Unity store

If you like Midi Player Tool Kit, please leave a review on the Asset Store. It’s very appreciated!!!

Maestro MPTK on ChatGPT!

From different MPTK documentation sources DarkSky42 has created a custom LLM based on ChatGPT. You are now able to ask all the questions you want and get a good level of response, request code example, verify your source code …

Contact

If you have questions, please don’t hesitate to contact us via the dedicated Unity forum or our Discord  channel.

Reach the Discord archive by topic.

We are always happy to discuss your projects!

Add MIDI Music With 3 Clicks for Free

Sound Spatialisation, MPTK is ready for Virtual Reality [Pro]

Sound Spatialisation, MPTK is ready for Virtual Reality [free]

Midi Synth : Real Time Voice Effect Change

Euclidean Rhythm demo

The Deezer playlist that helped me create Maestro