我引用了Pygame文档和这段代码来尝试让MIDI输入正常工作。MIDI接口(Avid 11 in )从我的MIDI控制器接收MIDI数据,就在我的音频软件(Pro Tools)中。然而,使用Pygame,我似乎根本看不懂任何信息。
源代码
import pygame
from pygame.locals import *
from pygame import midi
class MidiInput():
    def __init__(self):
        # variables
        self.elevenRackInID = 2
        # init methods
        pygame.init()
        pygame.midi.init()
        self.midiInput = pygame.midi.Input(self.elevenRackInID, 100)
    def run(self):
        # print(pygame.midi.Input(3, 100))
        # for i in range(10):
            # print(pygame.midi.get_device_info(i), i)
        self.read = self.midiInput.read(100)
        # self.convert = pygame.midi.midis2events(self.read, self.elevenRackInID)
        print(self.read)
test = MidiInput()
while True:
   test.run()唯一打印到控制台的东西是空方括号:
[]其他信息
我刚刚又检查了一遍:输入ID是正确的,实际上是一个输入。
"self.midiInput.poll()“返回False。因此,根据Pygame文档,没有数据输入。
您可以在下面看到数据、投票和设备信息:
data: [] || poll: False || device info: (b'MMSystem', b'Eleven Rack', 1, 0, 1)我所有MIDI设备的列表(包含索引):
(b'MMSystem', b'Microsoft MIDI Mapper', 0, 1, 0) 0
(b'MMSystem', b'External', 1, 0, 0) 1
(b'MMSystem', b'Eleven Rack', 1, 0, 1) 2
(b'MMSystem', b'Maschine Mikro MK2 In', 1, 0, 0) 3
(b'MMSystem', b'Microsoft GS Wavetable Synth', 0, 1, 0) 4
(b'MMSystem', b'External', 0, 1, 0) 5
(b'MMSystem', b'Eleven Rack', 0, 1, 0) 6
(b'MMSystem', b'Maschine Mikro MK2 Out', 0, 1, 0) 7任何帮助或建议都是非常感谢的!
发布于 2020-11-20 16:04:48
我在另一个论坛上得到了答案。事实证明,有一个示例文件显示了如何使代码工作。因此,如果其他人在这个问题上绊倒了,下面是示例代码的有用部分:
import sys
import os
import pygame as pg
import pygame.midi
def print_device_info():
    pygame.midi.init()
    _print_device_info()
    pygame.midi.quit()
def _print_device_info():
    for i in range(pygame.midi.get_count()):
        r = pygame.midi.get_device_info(i)
        (interf, name, input, output, opened) = r
        in_out = ""
        if input:
            in_out = "(input)"
        if output:
            in_out = "(output)"
        print(
            "%2i: interface :%s:, name :%s:, opened :%s:  %s"
            % (i, interf, name, opened, in_out)
        )
def input_main(device_id=None):
    pg.init()
    pg.fastevent.init()
    event_get = pg.fastevent.get
    event_post = pg.fastevent.post
    pygame.midi.init()
    _print_device_info()
    if device_id is None:
        input_id = pygame.midi.get_default_input_id()
    else:
        input_id = device_id
    print("using input_id :%s:" % input_id)
    i = pygame.midi.Input(input_id)
    pg.display.set_mode((1, 1))
    going = True
    while going:
        events = event_get()
        for e in events:
            if e.type in [pg.QUIT]:
                going = False
            if e.type in [pg.KEYDOWN]:
                going = False
            if e.type in [pygame.midi.MIDIIN]:
                print(e)
        if i.poll():
            midi_events = i.read(10)
            # convert them into pygame events.
            midi_evs = pygame.midi.midis2events(midi_events, i.device_id)
            for m_e in midi_evs:
                event_post(m_e)
    del i
    pygame.midi.quit()您可以在以下目录中找到该文件:C:\Users\myUser\AppData\Roaming\Python\Python37\site-packages\pygame\examples\midi.py
用Win用户名替换'myUser'。而且,'Python37'可以在您安装的Python版本上有所不同。
发布于 2021-08-07 20:29:55
我不认为Leonhard发布的代码是可用的: pygame.midi轮询()方法和pygame.midi read()方法都没有阻塞。其结果是CPU消耗达到最高(~50%)。
当然,在实践中,读取MIDI事件的代码将在一个单独的线程中运行,尽管这无助于CPU的消耗。
作为对其他地方另一个非常有用的评论的回应,我看了一下Mido库(https://mido.readthedocs.io/en/latest/index.html#)。这提供了阻塞读取方法,只需几行代码,我就可以从MIDI控制器键盘中查找消息,并将它们传递到MIDI合成器。
import mido
names = mido.get_input_names()
print(names)
out_port = mido.open_output()
with mido.open_input(names[0]) as inport:
    for msg in inport:
        out_port.send(msg)唯一的缺点是我在敲击键和听到音符之间会有很大的延迟(也许是1/4s)。哦,好吧,往前往上走。
https://stackoverflow.com/questions/64818410
复制相似问题