使用 Python 发送 MIDI 消息(在 Ubuntu 上)

Posted

技术标签:

【中文标题】使用 Python 发送 MIDI 消息(在 Ubuntu 上)【英文标题】:Sending MIDI messages using Python (on Ubuntu) 【发布时间】:2014-12-31 11:42:39 【问题描述】:

我正在尝试使用 Python 向合成器发送基本的 MIDI 消息。

我知道 PC-Synthesizer 链接可以正常工作,因为当 MIDI 输出设置为“DigitalKBD 20:0”端口时,可以将 Rosegarden 应用程序配置为在设备上播放 MIDI 文件。

我发现了这个 Python 库 (MIDO) 并安装了它。好消息是外部 MIDI 设备已被识别并在端口列表中可用。不幸的是,简单的音符测试不会在设备上触发任何声音。这是我尝试过的代码:

使用 PortMidi(这是 MIDO 的默认设置):

>>> import mido
>>> output = mido.open_output('DigitalKBD MIDI 1')
>>> output.send(mido.Message('note_on', note=60, velocity=64))

使用 RtMidi:

>>> import mido
>>> rtmidi = mido.Backend('mido.backends.rtmidi')
>>> output = rtmidi.open_output('DigitalKBD 20:0')
>>> output.send(mido.Message('note_on', note=60, velocity=64))

在这两种情况下,合成器都没有声音。

请问,我能否获得有关如何修复代码(或设置)以使仪器正确接收和解释消息的建议?

【问题讨论】:

运行aseqdump,玩到那个端口,检查是否有任何东西到达。 mido 可能在不同的 MIDI 通道上发送。验证合成器正在监听哪个 MIDI 通道并尝试在 mido.Message channel 字段上相应地进行显式设置。 这可能不是您的问题的论坛,因为它不是特定于 python 语言的问题。这是 API、安装、库兼容性或环境问题。您是否查看过该库的文档? 音量和时长如何? mido.get_output_names() 是否将您的设备名称列为可用输出?尝试使用该函数返回的确切字符串。 【参考方案1】:

好的,我让 MIDI 输入/输出正常工作,方法是创建一个小脚本来回显键盘上播放的任何内容,但有一定的延迟:

import mido
import time
from collections import deque

print mido.get_output_names() # To list the output ports
print mido.get_input_names() # To list the input ports

inport = mido.open_input('DigitalKBD MIDI 1')
outport = mido.open_output('DigitalKBD MIDI 1')

msglog = deque()
echo_delay = 2

while True:
    while inport.pending():
        msg = inport.receive()
        if msg.type != "clock":
            print msg
            msglog.append("msg": msg, "due": time.time() + echo_delay)
    while len(msglog) > 0 and msglog[0]["due"] <= time.time():
        outport.send(msglog.popleft()["msg"])

这个脚本运行得很好,所以我有机会仔细回过头来看看为什么我的初始测试不成功。事实证明,要接收输出消息,还必须打开输入端口。不知道原因,但这是最简单的代码:

import mido
inport = mido.open_input('DigitalKBD MIDI 1')
outport = mido.open_output('DigitalKBD MIDI 1')
outport.send(mido.Message('note_on', note=72))

另外,如果python在运行上述代码后立即退出,可能是MIDO没有发送消息,所以不会播放声音。给它一些时间来结束。

【讨论】:

OSError: 未知端口 'DigitalKBD MIDI 1' @OzanKurt 使用上面的代码打印输出和输入名称(需要对 Python 3 进行轻微的语法更新),以查看检测到的输入/输出端口。【参考方案2】:

您需要在将消息发送到输出后立即为您的呼叫添加睡眠。

我在1s的信息之后添加了一个简单的睡眠,并且音调播放得很好

【讨论】:

在使用 rtmidi 时,我不得不做类似的事情。除了使用睡眠之外,您还可以使用循环,就像上面的键盘回显示例一样。在我的情况下,我只是一个按键监听器

以上是关于使用 Python 发送 MIDI 消息(在 Ubuntu 上)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Arduino 发送 MIDI SysEx 消息?

如何在 c 中正确发送 midi 弯音消息?

使用 QT 通过 USB 发送 midi 消息

发送和接收 Java Midi Sysex 消息

在 C# 中将 MIDI 消息发送到 DAW

C# / nAudio - 向控制器发送 MIDI 消息