【问题标题】:Can't communicate midi through USB (python)无法通过 USB 通信 midi (python)
【发布时间】:2020-04-26 08:41:19
【问题描述】:

我的目标:

我想在我的 Raspberry Pi Zero W 上编写一个脚本,每当我在 GPIO 板上进行特定连接时,它就会将 MIDI 发送到我的计算机。

问题:

硬件的东西已经处理好了,它可以识别独特的按钮按下。但它似乎不会向我的计算机发送任何数据。我尝试了多个 python 模块(如rtmidi-pythonpython-rtmidimido),但它们都没有像我希望的那样工作。

为了解决这个问题,我已将 Raspberry 设置为从电源端口供电,因此 USB 端口保持为空,当它启动时,我将电缆连接到我的 PC。我什至写了一个脚本,因为我找不到任何“设置协议”,所以它总是一遍又一遍地喊出相同的注释(包括注释掉)。在浏览各种表格时,我注意到所有表格都很旧。最新的是 GitHub 上的 rtmidi-python,但似乎没有任何设置。

很可能,我只是一直看错了方向,或者信号甚至没有通过 USB 电缆,或者它也不需要设置。如果是这样,你介意让我知道,或者告诉我如何正确地做到这一点。

更新

我把我的树莓变成了一个“MIDI 函数”(this is how)。我的电脑和 FL 工作室也能识别它。但是,当我尝试弹奏一个音符时,仍然没有任何动作。此端口探测脚本

import rtmidi_python as rtmidi

midi_out = rtmidi.MidiOut()
for port_name in midi_out.ports:
    print port_name

返回

Midi Through:0
f_midi:0

我无法确定它是说没有 MIDI 消息通过,还是我的 Raspberry 在端口 0 上通话

解决方案:

首先,您必须确保您的 Raspberry Pi 实际上被识别为(在这种情况下)MIDI gadget。然后,不要将PythonPython3 混淆,因为它们是不同的,并且pip3 install midopip install mido。此外,保持 SD 支架清洁并删除任何不必要的模块是一个很好的做法。如果您的系统变得非常混乱,并且即使使用pip listapt list(列出了所有已安装的模块)也无法跟踪,您可以随时重新开始。意思是擦干净你的 SD 卡,根据你所学到的经验,这一次应该会更容易。

此外,您显然应该查看给定的答案。

希望至少有其他人看到这一点,我能够帮助他们:)

谢谢

【问题讨论】:

  • 向我们展示您的代码。如果您不向我们展示您的尝试,我们将无法帮助您识别问题。您如何将 Pi Zero 配置为 USB 设备?您的主机是否在 USB 总线上看到它?你的代码是什么样的?
  • 因为我可能是一个初学者,所以在盯着 C++ 脚本一段时间后,我只是无耻地复制粘贴了设置/测试示例。链接到我访问过的页面:pypi.org/project/python-rtmidigithub.com/superquadratic/rtmidi-python 对于永远大喊大叫的脚本,我基本上只是在 NOTE_ON 和 NOTE_OFF 之间编写了一个无限的 while 循环。 (也刚刚注意到并纠正,我有一个零 W,如果这有什么不同的话)
  • 我们真的需要更多信息。您能否更新您的问题以显示(a)您如何将 Pi 配置为 USB MIDI 设备? (b) 你在树莓派上的 Python 代码是什么样的? (c) 您如何在主机上验证它是否正常工作?如果您可以在问题中提供该信息,我很乐意提供帮助。
  • 希望现在清楚一点。

标签: python raspberry-pi midi


【解决方案1】:

在这段代码中...

midi_out = rtmidi.MidiOut()
for port_name in midi_out.ports:
    print port_name

...您要求提供可用端口列表,rtmidi 正在为您提供该信息。有两个可用的 MIDI 端口:

Midi Through:0
f_midi:0

在这两个端口中,第二个 (f_midi:0) 是由 USB 小工具功能创建的端口。如果您在此端口上发送 MIDI 消息,它应该可以正常工作。例如,我在我的 Pi Zero 上复制了您的设置,并且能够使用以下代码将 MIDI 消息发送到我的桌面。我正在使用mido,它是rtmidi 的高级包装器(我更喜欢它,因为它使发送/接收 MIDI 消息变得更加容易):

>>> import mido
>>> mido.get_output_names()
['Midi Through:Midi Through Port-0 14:0', 'f_midi:f_midi 20:0']
>>> out = mido.open_output('f_midi:f_midi 20:0')
>>> out.send(mido.Message('control_change', channel=0, control=0, value=123))

在我的主机上,我看到 Pi Zero 显示为 MIDI 端口:

$ aseqdump -l
 Port    Client name                      Port name
  0:0    System                           Timer
  0:1    System                           Announce
 14:0    Midi Through                     Midi Through Port-0
 28:0    nanoKONTROL2                     nanoKONTROL2 MIDI 1
 36:0    Pi Zero Gadget                   Pi Zero Gadget MIDI 1

我看到了我发送的控制更改消息:

$ aseqdump --port 36:0
Waiting for data. Press Ctrl+C to end.
Source  Event                  Ch  Data
 36:0   Control change          0, controller 0, value 123

在回答您最后的评论时,您可以这样做:

import rtmidi
import sys

out = rtmidi.MidiOut()
for i, port in enumerate(out.get_ports()):
    if port.startswith('f_midi'):
        out.open_port(i)
        break
else:
  print('ERROR: failed to find a port')
  sys.exit(1)

out.send_message([176, 0, 123])

我正在使用 Python 3(我推荐它,因为 Python 2 到现在为止已经停产了),并且我正在使用 rtmidi 模块,如果您使用 apt install python3-rtmidi

使用我更喜欢的mido 模块,它看起来像:

import mido
import sys

for port in mido.get_output_names():
    if port.startswith('f_midi'):
        out = mido.open_output(port)
        break
else:
  print('ERROR: failed to find a port')
  sys.exit(1)

out.send(mido.Message('control_change', channel=0, control=0, value=123))

【讨论】:

  • 如果我在上面的示例中使用 python 或 python3,它会有所不同吗?因为使用 python 它什么都不做,而使用 python3,它实际上给了我一个错误。首先它告诉我,它说 smt 就像“预期的字节,找到了 str”,所以我重新安装了 rtmidi-python,但它仍然给我这个错误。或者我怎样才能找到带有脚本的“'f_midi:f_midi 20:0'”部分? (我不想每次开机都输入)
  • 很明显,我现在只是愚蠢,但这正是我寻求建议/帮助的原因。
  • 好吧,你可以像我在这里做的那样使用mido.get_output_names(),或者像你所做的那样使用rtmidi.MidiOut()返回的对象的ports属性。无论哪种情况,只需选择具有f_midi 的端口并使用那个端口。
  • 我在答案中添加了一个示例。
  • 哇。有用。我实际上可以看到我的消息正在发送。嗯,这不是一个惊喜吗?无论如何,非常感谢你帮助我,我真的很感激。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多