How to read midi files in Matlab code.

from ken Schutte’s Page

Reading and synthesizing MIDI

Here’s an example of reading within the enclosed file, jesu.mid. First, readmidi.m parses the file into messages and stores them in a matlab struct.

midi2audio will synthesize this midi data to a waveform. The default then uses a simple FM synthesis technique. This can then be written to a file.

To add or modify synthesis algorithms, you can change or replace the ‘synth.m’ file.

Analyzing the MIDI file

Internally, midi2audio uses the midiInfo function to generate start & end times of all the notes within the file. midiInfo will display a list of all the midi messages within the file:

midiInfo also returns a matrix of size Nx8, where N is the number of notes in the file. The 8 columns indicate:

  1. Track number
  2. Channel number
  3. Note number (midi encoding of pitch)
  4. Velocity
  5. Start time (seconds)
  6. End time (seconds)
  7. Message number of note_on
  8. Message number of note_off

 

Piano Roll

This “Notes” matrix can be easily used to create a “piano-roll” display. I’ve included a script for the same:

This results in:

piano roll thumbnail

piano roll with velocity thumbnail

Writing MIDI

Simple scale

writemidi.m and matrix2midi.m enables you to generate some notes somehow in Matlab, and write them out to a MIDI file. Here’s a straightforward example of making a chromatic scale:

Note, you only need to specify the first six columns of the note matrix (7 and 8 hold the index of MIDI messages). Now, you should have a valid MIDI file to open elsewhere. If you are on linux, you might have timidity installed.

Random Notes

Now, let’s try creating some random music: let’s say 200 random notes with random start times & volumes, etc…

This sounds much more cooler with timidity’s grand piano synth:

Congratulations! You’re now a modern art composer.

These result in the following piano-rolls:

piano roll scale thumbnail

piano roll random thumbnail

Notes

  • readmidi should be able to read any MIDI file – it does very little parsing except breaking up into individual messages (handles deltatimes, running-mode, and determines the message type).
  • In synthesis, several message types are unheeded (for example, it does not handle controller messages, e.g. pitch-wheel bends, etc.).
  • Using readmidi and writemidi with no modifications can be used to check behavior. for example, run something like,

    and make sure ‘orig.mid’ and ‘new.mid’ are identical binary files. If you find this does not create an identical file, please let me know (but ensure it is a valid MIDI file). Or, you can check the entire thing in Matlab, (since writemidi returns a byte string)

 

The files are hosted on github. The project includes these files:

readmidi.m reads MIDI file into a Matlab structure
midi2audio.m convert the Matlab midi structure into an audio vector
midiInfo.m display detailed information about MIDI Matlab structure
synth.m synthesize a single note
getTempoChanges.m finds times of all tempo changes
midi2freq.m convert MIDI note number (0-127) to frequency in Hz
matrix2midi.m create MIDI Matlab structure from a matrix with information on individual notes