Objectives
Based on a recommendation from a Discord member of the Maestro , I explored the Unity package midi-plugin-for-mobile-and-desktop.
My aim is to create an integration between this plugin and Maestro. The objective is to easier Maestro’s MIDI synthesizer functionality with this plugin, while also facilitating Bluetooth and RTP MIDI keyboard connectivity for Maestro on mobile devices and websites, features often requested by Maestro’s users!
Limitation
- This post is not intended to serve as a substitute for the comprehensive documentation of either package. For in-depth information, please refer to the midi-plugin-for-mobile-and-desktop PDF or visit the links for both the MIDI plugin and Maestro documentation.
- It may take some time to fully understand these packages. If you have questions regarding the MIDI plugins or Maestro MPTK, please reach out to the respective publisher for efficiency.
Setup
Import the Unity packages Maestro and midi-plugin into your project. Next, include the following namespaces in all C# scripts that require either Maestro or the midi-plugin:
using MidiPlayerTK;
using jp.kshoji.midisystem;
using jp.kshoji.unity.midi;
It’s advisable to create an assembly for your project as a good practice. In this situation, you will need to include these Assembly Definition References (though not all may be necessary based on your specific tasks and operating system):
MIDI Integration
Initialize midi-plugin
For the midi-plugin initialization, I let you read the documentation:
- Published Unity asset: MIDI Plugin for Mobile devices
- MIDI over Bluetooth LE library for Android
- Additionally, the PDF included with the Unity package is an excellent resource and is likely more current.
Bellow a short example how to prepare your class for receiving MIDI events:
public class TestMidi : MonoBehaviour, IMidiAllEventsHandler, IMidiDeviceEventHandler
{
private void Awake()
{
#if !UNITY_IOS && !UNITY_WEBGL
netInterfaces = NetworkInterface.GetAllNetworkInterfaces();
#endif
MidiManager.Instance.RegisterEventHandleObject(gameObject);
MidiManager.Instance.InitializeMidi(() =>
{
#if DEVELOPMENT_BUILD
#if (UNITY_ANDROID || UNITY_IOS || UNITY_WEBGL) && !UNITY_EDITOR
MidiManager.Instance.StartScanBluetoothMidiDevices(0);
#endif
#endif
});
}
}
Initialize MPTK MidiStreamPlayer
For Maestro MPTK, add a MidiStreamPlayer to your project and a reference in your script:
- Prefab MidiStreamPlayer
- Set your midiStreamPlayer within your script:
using MidiPlayerTK;
...
// MPTK component able to play a stream of midi events.
// Need to be public to be visible in the inspector
// The reference can be set with the inspector or in your script.
public MidiStreamPlayer midiStreamPlayer;
public class TestMidi : MonoBehaviour, IMidiAllEventsHandler, IMidiDeviceEventHandler
{
void Start()
{
Debug.Log("Start: dynamically load MidiStreamPlayer prefab from the hierarchy.");
// Search a MidiStreamPlayer in the scene and initialize your variable.
midiStreamPlayer = FindFirstObjectByType<MidiStreamPlayer>();
if (midiStreamPlayer == null)
Debug.LogWarning("Can't find a MidiStreamPlayer Prefab in the current scene.");
}
}
Receiving MIDI event from devices
These functions will be triggered when an event is available. The MIDI event will be played with MPTK with the selected soundfont:
public class TestMidi : MonoBehaviour, IMidiAllEventsHandler, IMidiDeviceEventHandler
{
...
public void OnMidiNoteOn(string deviceId, int group, int channel, int note, int velocity)
{
// With no filter on the MIDI device selected, all MIDI devices found
// will trugger this function.
MPTKEvent midiStreamEvent = new MPTKEvent()
{
Command = MPTKCommand.NoteOn,
Value = note,
Channel = channel,
Velocity = velocity,
Duration = -1 // play until note off is received
};
midiStreamPlayer.MPTK_PlayEvent(midiStreamEvent);
}
public void OnMidiNoteOff(string deviceId, int group, int channel, int note, int velocity)
{
// With no filter on the MIDI device selected, all MIDI devices found
// will trugger this function.
MPTKEvent midiStreamEvent = new MPTKEvent()
{
Command = MPTKCommand.NoteOff,
Value = note,
Channel = channel,
Velocity = velocity,
};
midiStreamPlayer.MPTK_PlayEvent(midiStreamEvent);
}
// Warning, all other midi event handler must be implemented either
// you will get compilation error like:
// does not implement interface member IMidixxxxEventHandler.OnMidixxxx(...)
// See MidiSampleScene.cs in the midi-plugin demo.
...
}
Sending MIDI event to devices
*** to be continued ***