2

我在 Unity3D 标准版中工作。对于那些不知道的人,它是一个支持 C#/.NET 脚本的 3D 游戏引擎(因此它可以访问 .NET 2.0 API)。

我创建了自己的合成器。(目前它正在响应由 MIDI 音序器咀嚼 MIDI 文件生成的 note-ON 事件。)

现在我希望从 MIDI 键盘捕捉 note-ON 事件。

我打算至少将我的应用程序部署到 iOS,希望其他操作系统也能效仿。所以目标场景是:

  • 有人在 iPhone 上运行我的应用程序,他们有一个 MIDI 键盘连接到他们的 Windows 机器
  • 有人在 android 平板电脑上运行我的应用程序,他们有一个 MIDI 键盘连接到他们的 Linux 机器
  • 有人在 OS X 上运行我的应用程序,他们有一个连接到 OS X 的 MIDI 键盘

最后一个是我所处的情况,所以如果有人有一个不扩展的解决方案,我仍然对它非常感兴趣——这至少可以让我一起获得一个功能原型。

存在一种资产MIDI Unified,它将与 MIDI 设备连接。但是,它需要 PRO 版本。这是因为 PRO 版本允许使用原生插件。

我相信应该可以在不使用本机插件的情况下将 MIDI 导入 Unity,而是通过网络连接。

(请注意,我不是在说 Internet 连接、以太网连接、TCP/IP、UDP、HTTP,因为我不完全确定正确的术语是什么。)

似乎有用于通过网络发送 MIDI 信号的实用程序:ipMIDI将为 Windows 和 OS X 执行此操作。在 Linux 中可能会执行此操作。

OSX 有一个“音频 MIDI 设置”实用程序,有人告诉我它允许将 MIDI 信号从设备引导到本地主机。(也许这就是为什么 OS X 的 ipMIDI 是免费的?)

编辑:我刚刚发现 Audio MIDI 设置实现了RTP MIDI,这似乎是通过网络传输 MIDI 的最佳标准(它可以处理有损网络)。

所以我很确定任务变成了:如何在 C#/.NET 中实现 RTP MIDI?

但也许有一些更简单(但功能较弱)的解决方案,例如,一些解决方案仅适用于 OSX 上的 localhost 并接收来自 localhost 的 Note-ON MIDI 消息。

如果我能够为我的第一代应用程序获得一个基本解决方案,然后在我有能力的时候用一个强大的组件替换它,我会非常高兴。

所以这就是我所得到的,任何人都可以整理这个并推动它前进吗?

π

编辑:http ://u3d.as/content/sta-blockhead/websocket-sharp-for-unity/4X4这有帮助吗?

4

2 回答 2

0

我过去做过类似的事情。你可以做的是:

在您的计算机上安装 Midi 环回设备(驱动程序)。其中有很多,例如:http ://www.tobias-erichsen.de/software/loopmidi.html

然后设计一个简单的应用程序,它监听来自 Loopback 设备的虚拟 MIDI 端口,并将从虚拟 MIDI 端口接收到的任何内容转换为通过 TCP/IP 连接发送的数据包。TCP/IP 连接将在您的 Unity 脚本或其他支持 TCP/IP 并能够播放 MIDI 的东西上终止。协议非常简单,只有 3 个字节 - Note On、Note Number、Volume。(通常音量 0 表示音符关闭)。这就是你如何实现这一点。

希望这可以帮助...

于 2013-11-02T11:23:35.293 回答
0

Python 真的很棒!

每当发生 MIDI 音符开/关时,此脚本都会发送一个 UDP 数据包。我可以在 Unity3D 中捕获 UDP 数据包。

#!/usr/bin/python

# https://github.com/superquadratic/rtmidi-python/
import rtmidi_python as rtmidi

import time

import socket

def callback( data, time_stamp ):
    event, note, vel = data

    if event == 144: # note on/off
        endpoint = ( "127.0.0.1", 6500 )

        MESSAGE = "%d, %f" % ( note, float(vel) / 127.0 )

        print MESSAGE

        udp_socket = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )

        udp_socket.sendto( 
            MESSAGE, 
            endpoint
            )

def main( ):
    midi_in = rtmidi.MidiIn( )

    midi_in.callback = callback

    midi_in.open_port( 0 )

    # do something else here (but don't quit)
    while True: 
        time.sleep( 0.001 )

if __name__ == '__main__': 
    main()
于 2014-02-21T11:45:57.007 回答