pythonraspberry-pimidimido

Python mido not detecting keyboard input in Raspberry Pi


I have a simple python code that takes MIDI signal from a musical keyboard via USB connected to a PC which then sends command to an Arduino board to write to its digital out. This works perfectly fine and is without issues. I tried migrating the same code to Raspberry Pi with some modification specific to the Pi. My code is as follows:

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 ()

Adding RPi.GPIO is the only difference with the code running on Windows. If I moved the code

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

just above the line

print("START!")

Raspberry Pi writes to the correct port which I tested by connecting to an LED. The problem here is that the line after

for msg in inport.iter_pending():

never gets executed. I have checked to see if the Pi detects the keyboard and these are the outputs:

lsusb

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)

amidi -l

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

aconnect -i

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'

The Pi can read the MIDI from the keyboard just fine because this is the output for aseqdump -p 28 while playing keys from the keyboard

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.


Solution

  • When you open a port in Mido, you should specify which port you want it to open, by name. If you don't specify a port, it will open the system-specific default port, which can be overridden by environment variables

    So, the fix for your project would be to specify the CASIO USB-MIDI as the input port

    inport = mido.open_input("CASIO USB-MIDI MIDI 1")
    

    Alternatively, you could leave the parameter empty in mido.open_input() and instead configure the CASIO as the system default port by setting the environment variable:

    export MIDO_DEFAULT_INPUT='CASIO USB-MIDI MIDI 1'
    

    This might be preferable if you might use the same script with other devices later.