Отправка MIDI-сообщений с использованием Python (на Ubuntu)

Я пытаюсь отправить базовое MIDI-сообщение в синтезатор, используя Python.

Я знаю, что ссылка PC-Synthesizer функциональна, потому что приложение Rosegarden может быть настроено на воспроизведение MIDI файлов на устройстве, когда на MIDI-выход установлено значение "DigitalKBD 20: 0".

Я обнаружил эту библиотеку 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))

В обоих случаях звук от синтезатора отсутствует.

Пожалуйста, могу ли я получить совет по исправлению кода (или настройки), чтобы инструмент правильно принимал и интерпретировал сообщения?

Ответ 1

Хорошо, я получил MIDI-вход/выход, создав небольшой script, который перекликается с тем, что воспроизводится на клавиатуре, с определенной задержкой:

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"])

Этот script работает очень хорошо, поэтому у меня была возможность тщательно подойти, чтобы понять, почему мой первоначальный тест не увенчался успехом. Оказывается, для получения выходных сообщений входной порт также должен быть открыт. Не знаю, почему, но это самый простой код, который работает:

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 не удалось отправить сообщение, поэтому звук не будет воспроизводиться. Дайте ему время для завершения.