Python对接Akai LPD8 mk2:可读取但无法发送MIDI指令
前言
我有一台Akai LPD8 mk2 MIDI设备,想用Python对接。目前有两个针对前代型号(mk1)的开源项目:
- zetof/LPD8
- DrLuke/python-lpd8
我对这些库做了少量修改后实现了读取功能(示例见脚注*),但无论怎么尝试都无法向设备发送指令——具体来说,没法用Python控制Pad的开关状态(Pad灯光颜色代表状态)。
问题详情
我用mido库写了最小测试示例,想读取Pad的状态变化消息,延迟后回发给设备:
from time import sleep import mido def get_ioport_name(search): # 见脚注** names = mido.get_ioport_names() names = set(n for n in names if search in n) assert len(names) == 1 return names.pop() def get_messages(port): return list(port.iter_pending()) name = get_ioport_name("LPD8") port = mido.open_ioport(name) # 见脚注*** # 清空消息队列 get_messages(port) # 暂停等待操作 input("按几个Pad,然后按回车继续...") msgs = get_messages(port) print(f"记录到这些消息:\n{msgs}\n") print("正在回发这些消息:") for m in msgs: print(m) port.send(m) sleep(1)
代码运行无报错,但Pad没有出现预期的颜色变化。我试过切换mido的不同后端(rtmidi、portmidi、pygame),也直接用过rtmidi库,结果都一样。
另外,我尝试把双向端口(ioport)改成单独的输入/输出端口对,问题依然存在:
port_in = mido.open_input(name) port_out = mido.open_output(name) # 清空消息队列 get_messages(port_in) # 暂停等待操作 input("按几个Pad,然后按回车继续...") msgs = get_messages(port_in) print(f"记录到这些消息:\n{msgs}\n") print("正在回发这些消息:") for m in msgs: print(m) port_out.send(m) sleep(1)
脚注
- 适配mk2的修改示例:
我修改了zetof/LPD8项目中lpd8.py第16行的常量:
NOTE_ON = 144+9 NOTE_OFF = 128+9 CTRL = 176 PGM_CHG = 192+9
** 端口名称:mido.get_ioport_names()返回结果:
['Midi Through:Midi Through Port-0 14:0', 'LPD8 mk2:LPD8 mk2 MIDI 1 20:0', 'Midi Through:Midi Through Port-0 14:0', 'LPD8 mk2:LPD8 mk2 MIDI 1 20:0']
去重后为:
{'LPD8 mk2:LPD8 mk2 MIDI 1 20:0', 'Midi Through:Midi Through Port-0 14:0'} `mido.get_input_names()`和`mido.get_output_names()`结果相同。 *** mido端口类型: mido提供三种端口类:
open_input() # 仅接收
open_output() # 仅发送
open_ioport() # 双向(我使用的类型)
请问我哪里操作有误? --- # 解决方法 ### 1. 换用Control Change消息控制灯光 你现在回发的是从Pad读取的Note On/Off消息,但LPD8 mk2的灯光不响应这类输入消息,它需要的是Control Change(CC)指令。试试发送下面的测试代码: ```python # 点亮第1个Pad(CC编号36,值127) msg = mido.Message('control_change', channel=9, control=36, value=127) port_out.send(msg) # 熄灭该Pad(值0) msg = mido.Message('control_change', channel=9, control=36, value=0) port_out.send(msg)
Pad对应的CC编号一般从36到43(对应Pad1到Pad8),可以逐个测试确认。
2. 确认MIDI通道是否正确
你修改的代码用了通道9,但LPD8 mk2的默认接收通道可能不是这个。可以试试切换到通道0(对应MIDI通道1)再测试:
msg = mido.Message('control_change', channel=0, control=36, value=127) port_out.send(msg)
3. 检查设备是否开启MIDI回控
有些控制器的灯光只响应自身硬件操作,不接受外部MIDI指令。你可以用MIDI监控工具手动发送CC消息,看设备有没有反应。如果工具也不行,就得进设备固件设置,确认是否开启了MIDI回控功能。
4. 遍历端口排查匹配问题
虽然你去重了端口名称,但系统里的输入输出端口可能有隐藏差异。可以遍历所有带LPD8的输出端口,逐个发送测试消息:
for out_name in mido.get_output_names(): if "LPD8" in out_name: try: port = mido.open_output(out_name) port.send(mido.Message('control_change', channel=9, control=36, value=127)) port.close() print(f"已向端口 {out_name} 发送测试消息") except Exception as e: print(f"端口 {out_name} 发送失败: {e}")
内容的提问来源于stack exchange,提问作者NichtJens

