Jonny's Tutorials

Linux, Python, and so much more!

Reading from the Midi Through Port in Python

(Last Updated: June 8, 2024)

Hello and welcome to Jonny's Tutorials! Today, we will explore how to read MIDI data from the MIDI through port in Python using pygame. By the end of this tutorial, you will be able to interface a MIDI player with Python using the through port to capture and display incoming MIDI messages in real-time. This configuration can be used to synchronize audio with lights or motor movements on a Raspberry Pi, for example. Whether you are a musician looking to integrate MIDI into your Python projects, or just curious about working with MIDI data in Python, this tutorial is designed to help you achieve your goals.

Prerequisites

For this tutorial, I recommend using Debian 12 Bookworm or a compatible version. (Note: WSL has been tested and does not work)

Create a Directory

Open a terminal and navigate to the desired parent directory and create a directory for the tutorial.

  • mkdir midi-tutorial
  • cd midi-tutorial

MIDI File

Click here to download the daisy-bell.midi file for testing, accessible under the public domain (CC0).

daisy-bell.mid

Move the midi file to the midi-tutorial/directory.

  • mv -i ~/Downloads/daisy-bell.mid ./

Installation and Setup

Execute the following commands in the terminal to install necessary packages and set up the virtual environment.

  • sudo apt-get update  # Update the system
  • sudo apt-get install python3 python3-venv python3-pip  # Install required packages
  • python3 -m venv venv  # Create a virtual environment
  • source venv/bin/activate  # Activate the virtual environment
  • python3 -m pip install pygame  # Install the pygame module
 

ALSA Workaround

(https://github.com/pygame/pygame/issues/3756)

pygame uses ALSA for midi. An update to ALSA seems to have moved some files. To allow pygame to locate them, create a symbolic link in the old directory.

  • sudo ln -s /usr/share/alsa /usr/local/share/alsa

Write the Python Script

Type or paste the following into your favorite code editor and save it as midi_through_test.py inside the midi-tutorial directory.

import pygame.midi

pygame.midi.init()

device_id = None 

global device_count
device_count = pygame.midi.get_count()
for i in range(device_count):
    device_info = pygame.midi.get_device_info(i)
    if device_info[2] == 1 and b"Midi Through" in device_info[1]:
        device_id = i

device = pygame.midi.Input(device_id)

while True:
    if device.poll():
        print(device.read(1)[0])

Running the Script

Launch the Python script as follow.

  • python3 midi_through_test.py
 

Getting the MIDI Through Port

With Python still running, open another terminal and run:

  • aconnect -l

Note the number after "client" on the line titled "Midi Through". This is the port you will play the MIDI file through.

 

Playing the MIDI File

Play the MIDI file using the following. Replace "14" with the port number you got from aconnect -l.

  • aplaymidi --port 14 daisy-bell.mid
 

Expected Output

As you play the MIDI file, the Python script should display incoming MIDI events in the terminal (although you won't be able to hear anything). Congratulations! You have successfully captured MIDI data using Python. Now you can continue experimenting with different MIDI files and settings to further enhance your skills.

Happy Coding!