首页 > 编程问答 >Python mido 未检测到 Raspberry Pi 中的键盘输入

Python mido 未检测到 Raspberry Pi 中的键盘输入

时间:2024-08-05 04:40:54浏览次数:14  
标签:python raspberry-pi midi mido

我有一个简单的 python 代码,它通过连接到 PC 的 USB 从音乐键盘获取 MIDI 信号,然后将命令发送到 Arduino 板以写入其数字输出。这工作得很好,没有任何问题。 我尝试将相同的代码迁移到 Raspberry Pi,并进行一些特定于 Pi 的修改。我的代码如下:

import pygame
import mido
import rtmidi
import time
import RPi.GPIO as GPIO

pygame.init()
BLACK = [0,0,0]
WHITE = [255, 222, 111]
note_list = []
note_list_off = []
outport=mido.open_output()
inport=mido.open_input()
GPIO.setmode(GPIO.BCM)
done = False
GPIO.setup(4,GPIO.OUT)
print("START!")
while done == False:
    for msg in inport.iter_pending():
        try:
            n = msg.note
        except: 
            continue
        if msg.velocity>0 and msg.velocity != 64:
            print(msg.velocity)
            GPIO.output(4,True)
            time.sleep(1)
            GPIO.output(4,False)
        else:
            msg=mido.Message('note_off',note=n)
            outport.send(msg)

pygame.quit ()

添加RPi.GPIO是与Windows上运行的代码唯一的区别。如果我将代码移至该行上方

GPIO.output(4,True)
time.sleep(1)
GPIO.output(4,False)

Raspberry Pi 会写入我通过连接 LED 进行测试的正确端口。这里的问题是

print("START!")

之后的行永远不会被执行。我检查了 Pi 是否检测到键盘,这些是输出:

for msg in inport.iter_pending():

lsusb

amidi -l

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 07cf:6803 Casio Computer Co., Ltd CTK-3500 (MIDI keyboard)

aconnect -i

Dir Device    Name
IO  hw:3,0,0  CASIO USB-MIDI MIDI 1

Pi 可以很好地从键盘读取 MIDI,因为这是

client 0: 'System' [type=kernel]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 28: 'CASIO USB-MIDI' [type=kernel,card=3]
    0 'CASIO USB-MIDI MIDI 1'

aseqdump -p 28 在键盘上弹奏时的输出 我的 Python 版本是 3.11。 任何帮助深表感谢。

Waiting for data. Press Ctrl+C to end.
Source  Event                  Ch  Data
 28:0   Note on                 0, note 64, velocity 9
 28:0   Note on                 0, note 60, velocity 27
 28:0   Note on                 0, note 57, velocity 1
 28:0   Note off                0, note 57, velocity 64
 28:0   Note on                 0, note 60, velocity 30
 28:0   Note on                 0, note 57, velocity 23
 28:0   Note on                 0, note 55, velocity 31
 28:0   Note off                0, note 55, velocity 64
 28:0   Note off                0, note 60, velocity 64
 28:0   Note off                0, note 57, velocity 64
 28:0   Note on                 0, note 55, velocity 29
 28:0   Note off                0, note 55, velocity 64
 28:0   Note on                 0, note 57, velocity 35

My Python version is 3.11. Any help is much appreciated.


代码的问题在于 inport.iter_pending() 方法的阻塞性质。这种方法等待传入的 MIDI 消息,如果没有消息,它不会让代码的其余部分运行。这就是为什么你的代码在打印“开始!”之后似乎就停止了,因为它停滞在等待 MIDI 输入的循环中。

你可以通过使用非阻塞方法来读取 MIDI 输入,或者使用异步方法来处理 MIDI 输入,从而解决这个问题。下面介绍了这两种方法的示例:

1. 非阻塞方法:

你可以使用 inport.poll() 方法来检查是否有任何可用的 MIDI 消息,而不会阻塞代码的执行。如果有一个消息可用, inport.poll() 会返回该消息;否则,它会返回 None

下面是使用非阻塞方法修改后的代码:

import pygame
import mido
import time
import RPi.GPIO as GPIO

pygame.init()
BLACK = [0,0,0]
WHITE = [255, 222, 111]
note_list = []
note_list_off = []
outport=mido.open_output()
inport=mido.open_input()
GPIO.setmode(GPIO.BCM)
done = False
GPIO.setup(4,GPIO.OUT)
print("START!")
while not done:
    msg = inport.poll()  # 非阻塞方法检查消息
    if msg:
        try:
            n = msg.note
        except: 
            continue
        if msg.velocity > 0 and msg.velocity != 64:
            print(msg.velocity)
            GPIO.output(4,True)
            time.sleep(1)
            GPIO.output(4,False)
        else:
            msg=mido.Message('note_off',note=n)
            outport.send(msg)

pygame.quit()

2. 异步方法:

你也可以使用 Python 的 asyncio 库来异步处理 MIDI 输入。这将允许你的代码在等待 MIDI 输入的同时继续执行其他任务。

下面是使用 asyncio 库修改后的代码:

import pygame
import mido
import asyncio
import time
import RPi.GPIO as GPIO

pygame.init()
BLACK = [0,0,0]
WHITE = [255, 222, 111]
note_list = []
note_list_off = []
outport = mido.open_output()
inport = mido.open_input()
GPIO.setmode(GPIO.BCM)
done = False
GPIO.setup(4,GPIO.OUT)

async def process_midi():
    async for msg in inport:
        try:
            n = msg.note
        except: 
            continue
        if msg.velocity > 0 and msg.velocity != 64:
            print(msg.velocity)
            GPIO.output(4,True)
            await asyncio.sleep(1)
            GPIO.output(4,False)
        else:
            msg = mido.Message('note_off', note=n)
            outport.send(msg)

async def main():
    print("START!")
    await process_midi()

if __name__ == "__main__":
    asyncio.run(main())
    pygame.quit()

选择哪种方法取决于你的具体需求。如果你需要在等待 MIDI 输入的同时执行其他任务,那么异步方法是更好的选择。如果你的代码相对简单,并且不需要同时执行多个任务,那么非阻塞方法就足够了。

标签:python,raspberry-pi,midi,mido
From: 78616189

相关文章

  • Python 初学者,遇到简单数学问题
    我必须做一个数学练习,要求我以10^-5的幅度构建√3。使用扫描方法和Python。我是法国人,所以我不知道是否“扫描”是正确的词。在练习的前面,我得到了一些提示:√3是方程x^2-3=0的解,我需要达到x*的点y是负数所以我尝试了这个:x=1y=1+10......
  • python字典
    字典概念一种数据结构,用于储存键值对键:值=key:value键会有对应的值,键是用来查找值的(字→键,释义→值)字典名={}要在字典里放入多个键值对,就用"{}"把它们包住,键和值之间用":"表示对应,键值对之间用","分隔。用法如果我们要获取某个键的值,在字典名后面跟方括......
  • python+flask计算机毕业设计健康管理系统的设计与实现(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景近年来,随着人们生活水平的提高和健康意识的增强,健康管理已成为社会关注的焦点。传统的健康管理方式往往依赖于纸质记录和医生的口头建议,这......
  • python+flask计算机毕业设计实验室信息化管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在当今快速发展的科技时代,实验室作为科研与教学的核心场所,其管理效率和信息化水平直接影响到研究成果的质量和速度。传统的实验室管理方式......
  • python+flask计算机毕业设计中国诗词鉴赏网站(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景中国诗词作为中华文化的重要组成部分,承载着千年的历史与文化底蕴。从古至今,诗词一直是文人墨客表达情感、描绘景象的重要工具。然而,随着时......
  • python+flask计算机毕业设计装修公司管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景近年来,随着城市化进程的加速和人们生活水平的提高,装修行业迎来了前所未有的发展机遇。然而,传统装修公司管理方式存在诸多弊端,如信息不透明......
  • Python基础算法笔记
    整理自B站视频https://www.bilibili.com/video/BV1uA411N7c5递归1.汉诺塔问题#n个圆盘,从a经过b移动到cdefhanoi(n,a,b,c):ifn>0:#将n-1个圆盘从a经过c移动到bhanoi(n-1,a,c,b)#将最底层的圆盘从a移动到cprint("mov......
  • 24412-Python链接LDAP(Kerbores)认证的Impala
    24412-Python链接LDAP(Kerbores)认证的Impala必须安装pyImpala才行pipinstallimpylaPython3.x链接LDAP(Kerbores)认证的Impala代码fromimpala.dbapiimportconnectimpala_host="172.10.194.101"impala_port="25004"impala_user='huabingood_test&......
  • Python_DAG-有向无环图-igraph
    DAG-有向无环图-igraph安装pipinstallpython-igraphpipinstallpycairopiplist发现Python安装的有igraph包有两个:igraph、python-igraph有向图 有向图(Digraph)是图论中的一种图结构,其中的边(弧)具有方向性,表明从一个节点(顶点)到另一个节点的单向关系。与无向图不同,无向......
  • 【Python系列】深入理解 Python 中的 `nonlocal` 关键字
    ......