liveBook · Manning

MIDI

As explained in Learn Generative AI with PyTorch

A file containing musical performance data encoded according to the MIDI standard.

MIDI is a standard for communication among electronic musical instruments, computers, and related devices. A MIDI file stores musical performance data rather than the multidimensional arrays or token indexes used directly to train music-generation models. It provides a playable way to inspect training examples and generated results. section 13.1.2 section 14.1.3

In a performance-based representation, note-on and note-off messages mark when pitches start and stop. Pitch and velocity values each range from 0 to 127; velocity describes how forcefully a note is played. For example, a note-on message at about 1.03 seconds starts pitch 74 (D5) with velocity 86. Timing, messages, and velocity together preserve details needed for expressive playback. section 14.1.1

The same file format supports two different generation workflows:

  • For multitrack generation, represent a piece as a (4, 2, 16, 84) array: four tracks, two bars, 16 steps per bar, and 84 possible pitch positions. Convert the selected pitches back into notes and write a MIDI file to hear the result. The 84 positions belong to this dataset representation, not MIDI’s full 0–127 pitch range. section 13.1 section 13.3.2
  • For sequence generation, turn a MIDI performance into note-on, note-off, time-shift, and velocity events. Map those events to integer indexes for a music Transformer; convert generated events back to a playable MIDI file. section 14.1.1 section 14.0

From a multitrack array to something you can hear

Select each step’s pitch with argmax, reshape two bars of 16 steps into 32 rows across four tracks, and create a music21 Part for each track. Accumulate note duration as you walk the steps, append the parts to a Score, then write first_song.midi. Playing the file gives a direct check on the music represented by the array. section 13.3.2

Listing 13.2 Converting pitch numbers to a MIDI file
for i in range(4):                                         #1
    last_x = int(midi_note_score[:, i][0])
    s = stream.Part()
    dur = 0
    for idx, x in enumerate(midi_note_score[:, i]):        #2
        x = int(x)
        if (x != last_x or idx % 4 == 0) and idx > 0:
            n = note.Note(last_x)
            n.duration = duration.Duration(dur)
            s.append(n)
            dur = 0
        last_x = x
        dur = dur + 0.25                                   #3
    n = note.Note(last_x)
    n.duration = duration.Duration(dur)
    s.append(n)                                            #4
    parts.append(s)  
parts.write("midi","files/first_song.midi")

The conversion listing shows how pitch rows become four timed parts in a playable MIDI file. section 13.3.2

For piano-performance training, MAESTRO v2.0.0 supplies MIDI files. The processor.py module converts them to index sequences and back. Its detailed event-encoding algorithm is not required to train the Transformer; the practical handoff is from a playable performance to numerical training data. section 14.2.1 section 14.2.2

How Learn Generative AI with PyTorch covers it

How deep it goes
Defines note messages, pitch, and velocity and works through conversions, but defers the detailed event-encoding algorithm to processor.py.
Examples
Uses a four-track chorale, a playable MIDI export, and MAESTRO piano performances.
What it assumes
Introduces notes, octaves, and pitch numbers before MIDI, then builds on GAN and NLP-style generation workflows.
What you can do after
Apply it via music21 and processor.py to export multitrack arrays as MIDI and prepare MIDI performances as training indexes.
How it connects
Links MIDI to one-hot encoding, multitrack music, event tokenization, and music Transformers.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Generative AI with PyTorch. The section links point to the parts of the book it draws on.