New module to parse MIDI files available

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
bixb
Posts: 2
Joined: Sat Jul 02, 2022 2:31 am

New module to parse MIDI files available

Post by bixb » Wed Aug 24, 2022 4:41 am

Hello,
I coded a module to parse MIDI files, that is, to read a MIDI file and return all the events in the file, calculating time between events.

Available at https://github.com/bixb922/umidiparser under MIT license.

Example:

import umidiparser
import utime
for event in umidiplay.MidiFile("example.mid"):
# Wait until this event is due
utime.sleep_us( event.delta_us )
# Process the event according to type
if event.status == umidiplay.NOTE_ON:
... start the note event.note on event.channel with event.velocity
elif event.status == umidiplay.NOTE_OFF :
... stop the note event.note stop to sound ...
elif event.status == umidiplay.PROGRAM_CHANGE:
... change midi program to event.program on event.channel ....
else:
# Show all events not processed
print("other event", event )

This module does not contain a sound synthesizer, only the capabilities to read and interpret a MIDI file.

Memory and CPU usage is optimized for a microcontroller with limited resources with Micropython. CPU and memory usage can be lowered even more by reusing the same MidiEvent over and over during the process:

for event in MidiFile("example.mid", reuse_event_object=True ):
... process event....

Normally the complete midi file will be buffered in RAM when opening the file. If RAM is scarce or may be fragmented, use:

for event in MidiFile("example.mid", buffer_size=100 ):
.... process event...
This will allocate buffer_size bytes as a buffer for each track in the midi file, open one file descriptor for each track and then read the file piecemeal. CPU usage may increase about 10% slightly (about 10%) but RAM usage is limited to the buffer_size bytes per track, and you can process a files much larger than the available heap or RAM. See "CPU AND MEMORY" below.

This module will calculate the time between events, using the parameters and events available in the MIDI file (pulses per beat field in the file header and set tempo events).

I hope this can be useful.

User avatar
Wind-stormger
Posts: 17
Joined: Fri Nov 05, 2021 6:59 am

Re: New module to parse MIDI files available

Post by Wind-stormger » Wed Aug 24, 2022 7:11 am

Looking forward to a simple video demo.

User avatar
scruss
Posts: 360
Joined: Sat Aug 12, 2017 2:27 pm
Location: Toronto, Canada
Contact:

Re: New module to parse MIDI files available

Post by scruss » Wed Aug 24, 2022 3:32 pm

Ooh, neat. I am a complete MIDI numpty, but I can follow how this works. What annoyance can I bring using this plus a simple piezo buzzer, I wonder?

If anyone's looking to convert MIDI notes (0 - 127) to frequencies,

Code: Select all

440 * 2**((float(note) - 69) / 12)
will do it (as suggested by Note names, MIDI numbers and frequencies).

User avatar
scruss
Posts: 360
Joined: Sat Aug 12, 2017 2:27 pm
Location: Toronto, Canada
Contact:

Re: New module to parse MIDI files available

Post by scruss » Fri Aug 26, 2022 1:38 am

I got it to make noise! Glorious dreadful noise!
MicroPython MIDI mayhem (kinda)

bixb
Posts: 2
Joined: Sat Jul 02, 2022 2:31 am

Re: New module to parse MIDI files available

Post by bixb » Sat Aug 27, 2022 2:13 am

Hello @scruss,
I liked that!! Almost obnoxious!!
Cheers!!

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: New module to parse MIDI files available

Post by fma » Sun Apr 16, 2023 9:21 am

Hi!

A few months ago, I modified an existing project based on a BluePill to play MIDI files from an Amstrad CPC. All written in C, of course, in order to manage the timings with the CPC bus.

Today, I'm digging in the RPi Pico, and I'm porting my code to micropython / PIO, so the umidiparser library will be very helpful.

Thanks for sharing!
Frédéric

Post Reply