Unity 中的 MIDI 输出

Posted

技术标签:

【中文标题】Unity 中的 MIDI 输出【英文标题】:MIDI Output in Unity 【发布时间】:2018-08-07 22:27:41 【问题描述】:

我正在尝试构建简单的软件以在 Unity 中连接到 Windows 上的 MIDI 输出设备并发送 MIDI 数据。

为了避免重新发明***,我首先在支持 .NET 2.0 的 CodeProject 上使用 C# Midi Toolkit。

我遇到的问题是它在 Unity 编辑器中运行良好,但随后 在独立 Windows 构建中失败

这是基本的连接/播放声音代码:

    // 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));

在独立构建中我得到以下异常:

OutputDeviceException: 指定的设备句柄无效。

我查看了源代码并注意到该库正在使用 Win32 处理 winmm.dll,我认为这可能与它有关,但不确定从这里去哪里。

谁能提供有关如何解决此问题的任何见解?我可能会看看专门为 Unity 构建的替代方案,但我有兴趣了解为什么这样的东西一开始就行不通。

【问题讨论】:

你为什么用deviceID = 1 看起来例子用的是0 0 是 Microsoft GS Wavetable Synth,我正在尝试连接到设备 ID 为 1 的单独环回 MIDI 接口。使用您看到的日志记录代码确认独立和编辑器中的情况在顶部 哪个语句失败? OutputDevice 的构造函数,这是我正在使用的库也尝试连接到提供的设备 ID 的地方 你试过使用NAudio吗? 【参考方案1】:

不知道是不是这种问题,但是这个老codeproject代码使用的midiOutOpen函数的x86定义(OutputDevice.cs)是

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

在 Pinvoke 上我可以找到这个定义:

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

可能是平台问题。

【讨论】:

非常有趣,所以您是在暗示旧代码项目示例可能是为具有不同 winmm.dll 的旧 Windows 构建的?我在 Windows 10 上对此进行了测试。 这是带有 IntPtr 的新 x64 / x86 实现。【参考方案2】:

你可以看看DryWetMIDI是如何实现的,例如:Output device。

用法:

using Melanchall.DryWetMidi.Devices;
using Melanchall.DryWetMidi.Core;

// ...

using (var outputDevice = OutputDevice.GetByName("Output device")) // or GetById(1)

    outputDevice.SendEvent(new NoteOnEvent());

【讨论】:

以上是关于Unity 中的 MIDI 输出的主要内容,如果未能解决你的问题,请参考以下文章

Unity3d 中集成的 android MIDI 驱动程序没有声音

Java 中用于播放的硬件 MIDI 输出?

如何使用 Python 中的长笛乐器从音符制作 MIDI 文件(music21 库)

.NET 中的精确计时

从 Java 中的 Midi 文件中读取 Midi 消息 [重复]

.Net 中的 Midi 实现