Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MIDI Output in Unity

I'm trying to build simple software to connect to a MIDI Output device on Windows in Unity and send MIDI data.

As to avoid re-inventing the wheel, I started with the use of the C# Midi Toolkit on CodeProject built with support for .NET 2.0.

The issue I'm having is that it works fine in the Unity editor but then fails in the standalone Windows build.

Here is the basic connection/play sound code:

    // Log devices
    int deviceCount = OutputDevice.DeviceCount;
    for (int i = 0; i < deviceCount; i++)
    {
        Debug.Log(string.Format("Detected MIDI Device with ID {0}:{1}", i, OutputDevice.GetDeviceCapabilities(i).name));
    }
    deviceID = 1;
    Debug.Log(string.Format("Connected to {0}", deviceID));
    // Connect to device
    device = new OutputDevice(deviceID);
    // Play Middle C
    device.Send(new ChannelMessage(ChannelCommand.NoteOn, 0, note, 127));

And in the standalone build I get the following exception:

OutputDeviceException: The specified device handle is invalid.

I looked through the source and noticed that the library is using Win32 handles to winmm.dll, I figured this might have something to do with it but not certain where to go from here.

Can anyone provide any insight in how to approach this? I'll probably look at alternatives built specifically for Unity but I'm interested in learning why something like this wouldn't work in the first place.

like image 651
Naxin Avatar asked Feb 28 '18 05:02

Naxin


People also ask

How do you use MIDI output?

Plug the MIDI cable labeled "In" into the keyboard MIDI port labeled "Out." This sends the output, or the music you are generating, through the MIDI cable and into your computer.

Can Unity play MIDI files?

With Maestro Midi Player Tool Kit, you can add to your Unity applications all the MIDI musics that you want: thank to the huge public collection of MIDI on the web .

What is a MIDI input output?

A MIDI OUT port allows a device to send MIDI data. And a MIDI IN port allows a device to take in MIDI data. There's also a third type of port on some MIDI devices called MIDI THRU. This port lets a device copy incoming MIDI data and send out a string of identical data.

What is MIDI Bridge?

MIDI Bridge for Windows (MidiBridge.exe) is a command line application to relay MIDI messages between Unity and MIDI devices.


1 Answers

I don't know if this kind of problem, but the x86 definition of midiOutOpen function that this old codeproject code uses (OutputDevice.cs) is

[DllImport("winmm.dll")]
 50          private static extern int midiOutOpen(ref int handle, int deviceID,
 51              MidiOutProc proc, int instance, int flags);

While on Pinvoke I can find this definition:

[DllImport("winmm.dll")]
        static extern uint midiOutOpen(out IntPtr lphMidiOut, uint uDeviceID, IntPtr dwCallback, IntPtr dwInstance, uint dwFlags);

Maybe it is a platform problem.

like image 89
anefeletos Avatar answered Oct 17 '22 07:10

anefeletos