Reputation: 496
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.
Upvotes: 6
Views: 2847
Reputation: 2144
You can take a look at how it's implemented in DryWetMIDI, for example: Output device.
Usage:
using Melanchall.DryWetMidi.Devices;
using Melanchall.DryWetMidi.Core;
// ...
using (var outputDevice = OutputDevice.GetByName("Output device")) // or GetById(1)
{
outputDevice.SendEvent(new NoteOnEvent());
}
Upvotes: 0
Reputation: 712
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.
Upvotes: 1