Creating Audio Files with Mido in Python

Mido is a Python library that deals with MIDI, an acronym for Musical Instrument Digital Interface, a protocol that allows computers, musical instruments, and other hardware to communicate.

πŸ’‘ With Mido, you can create, inspect, and manipulate MIDI files and messages, making it an excellent tool for generating audio files programmatically.

Installation

First things first, you need to install the library. Mido can be easily installed via pip, a package installer for Python.

Open your terminal or command prompt and type the following command:

pip install mido

If you’re on a Jupyter notebook such as Google Colab, you can simply add the exclamation mark in front of it:

!pip install mido

Creating a MIDI File

Creating a MIDI file with Mido is a straightforward process. Here’s a basic outline of how it’s done:

  1. Import the necessary modules:
import mido
from mido import MidiFile, MidiTrack
  1. Create a new MIDI file and track:
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

Adding Messages to the Track

πŸ’‘ A MIDI file consists of a series of “messages” or commands that tell the MIDI device what to do. The most common messages are note_on and note_off, which start and stop a note, respectively.

Here’s how you add a note_on message to the track:

track.append(mido.Message('note_on', note=60, velocity=64, time=32))

In this line, note=60 refers to the MIDI number for the note you want to play (in this case, middle C), velocity=64 refers to the loudness of the note (0 being silent and 127 being the maximum volume), and time=32 is the delay before the message is sent, measured in ticks.

You can add a note_off message in a similar way. Typically, you’d add a note_off message after a note_on message to indicate the end of the note:

track.append(mido.Message('note_off', note=60, velocity=64, time=64))

Saving the MIDI File

Once you’ve added all your messages, you can save the MIDI file with the following command:

mid.save('output.mid')

This will create a new MIDI file called 'output.mid' in the current directory. You can open this file with any software that supports MIDI.

Creating a Random Note Sequence

With Mido, you can easily generate random note sequences. For instance, if you want to create a random sequence of 16 notes, you can use Python’s built-in random module:

import mido
from mido import Message, MidiFile, MidiTrack
import random

# List of possible piano notes
notes = [60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86]

# Create a new MIDI file and a track
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

# Add 16 random notes to the track
for i in range(16):
    note = random.choice(notes)
    track.append(Message('note_on', note=note, velocity=64, time=32))
    track.append(Message('note_off', note=note, velocity=64, time=32))

# Save the MIDI file
mid.save('random_piano_song.mid')

This script generates a MIDI file (random_piano_song.mid) that plays 16 notes, chosen randomly from the notes list, which contains MIDI note numbers corresponding to a range of piano notes. The velocity parameter controls the volume of the notes (64 is a moderately soft volume), and the time parameter sets a delay before each note is played (32 ticks in this case).

You can play the resulting MIDI file in any software that supports MIDI playback, or use it in other programs for further processing. Unfortunately, I couldn’t upload it to the website as it doesn’t support Midi.

Now you may ask:

How to Convert Midi to MP3 in Python?

Converting MIDI to MP3 in Python involves two steps.

  • First, you convert the MIDI file into a WAV file.
  • Second, you convert the WAV file into an MP3 file.

Step 1: MIDI to WAV

This step is accomplished using a soundfont and a library like fluidsynth, which can actually play the MIDI file and save the audio output. FluidSynth is a software synthesizer for generating music, and it works well for MIDI to WAV conversions.

Here’s an example of how to use it in Python:

import fluidsynth

fs = fluidsynth.Synth()

# You can find soundfonts online for free, like the one from MuseScore.
# Here's the link: https://musescore.org/en/handbook/3/soundfonts-and-sfz-files#gm
fs.start(driver="alsa") 
sfid = fs.sfload("/path/to/your/soundfont.sf2")
fs.program_select(0, sfid, 0, 0)

# Your MIDI file goes here.
fs.midi_to_audio('/path/to/your/file.mid', '/path/to/output.wav')

fs.delete()

Step 2: WAV to MP3

To convert the WAV file into MP3, you can use a library like pydub, which is a simple and easy-to-use library that can do this conversion. It uses ffmpeg under the hood, so you need to have it installed on your system.

Here’s how to do it:

from pydub import AudioSegment

song = AudioSegment.from_wav("/path/to/output.wav")
song.export("/path/to/output.mp3", format="mp3")

Please note that both fluidsynth and pydub need to be installed via pip:

pip install fluidsynth pydub

Also note that this operation can be quite CPU-intensive, especially for longer MIDI files. It may take a while for the operation to complete, and the final MP3 file can be quite large. Be sure that your machine has the necessary resources to handle this operation before you begin.

And finally, remember to replace "/path/to/your/soundfont.sf2", "/path/to/your/file.mid", and "/path/to/output.mp3" with your actual file paths.

A related problem you may have is creating a sequencer using the mido library:

Python Mido Sequencer

A sequencer is a device or application that can record, edit, or play back music, by handling note and performance information in several forms, primarily MIDI data.

In Python, you can create a simple sequencer using Mido, by creating sequences of note_on and note_off messages with the desired notes, velocities and times.

Here is a simple example of a sequencer:

import mido
from mido import MidiFile, MidiTrack, Message
import time

# Define a sequence: (note, velocity, delay)
sequence = [
    (60, 64, 0.5),  # Note C4
    (62, 64, 0.5),  # Note D4
    (64, 64, 0.5),  # Note E4
    (65, 64, 0.5),  # Note F4
    (67, 64, 0.5),  # Note G4
    (69, 64, 0.5),  # Note A4
    (71, 64, 0.5),  # Note B4
    (72, 64, 0.5),  # Note C5
]

# Create a MIDI file and track
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

# Play the sequence
for note, velocity, delay in sequence:
    # Note on
    track.append(Message('note_on', note=note, velocity=velocity, time=0))
    time.sleep(delay)  # Delay before note_off
    # Note off
    track.append(Message('note_off', note=note, velocity=velocity, time=0))

# Save the MIDI file
mid.save('sequence.mid')

This script plays a sequence of notes (C4 to C5) with a delay of 0.5 seconds between each note. The resulting sequence is then saved to a MIDI file (sequence.mid) which can be played in any software that supports MIDI playback.

If you want to keep improving your Python skills and stay up to date with recent tech news, download our free cheat sheets here: