How to Create Procedural Music in Python Using PyDub and MIDI Files

Procedural music refers to the generation of music algorithmically, often using rules, patterns, or randomness. In this tutorial, we’ll explore how to use Python to generate simple MIDI melodies and then convert them to audio using PyDub. 1. Install Required Libraries We’ll use mido to generate MIDI files and pydub to convert audio formats. You’ll also need a soundfont player or MIDI-to-audio renderer like fluidsynth. pip install mido pydub 2. Generate a Simple MIDI File This example creates a simple arpeggio in C major: from mido import Message, MidiFile, MidiTrack mid = MidiFile() track = MidiTrack() mid.tracks.append(track) notes = [60, 64, 67, 72] # C major arpeggio for note in notes: track.append(Message('note_on', note=note, velocity=64, time=0)) track.append(Message('note_off', note=note, velocity=64, time=480)) mid.save('arpeggio.mid') 3. Convert MIDI to WAV (Optional) To hear the music, convert the MIDI to WAV using fluidsynth. First install it: # On Linux/macOS brew install fluid-synth # or sudo apt install fluidsynth # Convert fluidsynth -ni soundfont.sf2 arpeggio.mid -F output.wav -r 44100 Replace soundfont.sf2 with a valid soundfont file on your system. 4. Add Effects with PyDub Once you have a WAV file, you can apply audio effects using PyDub: from pydub import AudioSegment from pydub.playback import play sound = AudioSegment.from_wav("output.wav") # Add echo effect echo = sound + sound.reverse().fade_out(2000) play(echo) 5. Advanced: Random Melody Generator Let’s generate a randomized melody in a scale: import random from mido import Message, MidiFile, MidiTrack scale = [60, 62, 64, 65, 67, 69, 71, 72] # C major mid = MidiFile() track = MidiTrack() mid.tracks.append(track) for _ in range(16): note = random.choice(scale) track.append(Message('note_on', note=note, velocity=64, time=0)) track.append(Message('note_off', note=note, velocity=64, time=480)) mid.save('random_melody.mid') Conclusion With just a few lines of Python, you can start exploring generative music and procedural audio techniques. From creating MIDI sequences to applying post-processing effects with PyDub, this workflow enables a lot of creative potential for games, interactive installations, or just fun experimentation. If this post helped you, consider supporting me here: buymeacoffee.com/hexshift

Apr 18, 2025 - 15:01
 0
How to Create Procedural Music in Python Using PyDub and MIDI Files

Procedural music refers to the generation of music algorithmically, often using rules, patterns, or randomness. In this tutorial, we’ll explore how to use Python to generate simple MIDI melodies and then convert them to audio using PyDub.

1. Install Required Libraries

We’ll use mido to generate MIDI files and pydub to convert audio formats. You’ll also need a soundfont player or MIDI-to-audio renderer like fluidsynth.

pip install mido pydub

2. Generate a Simple MIDI File

This example creates a simple arpeggio in C major:

from mido import Message, MidiFile, MidiTrack

mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

notes = [60, 64, 67, 72]  # C major arpeggio
for note in notes:
    track.append(Message('note_on', note=note, velocity=64, time=0))
    track.append(Message('note_off', note=note, velocity=64, time=480))

mid.save('arpeggio.mid')

3. Convert MIDI to WAV (Optional)

To hear the music, convert the MIDI to WAV using fluidsynth. First install it:

# On Linux/macOS
brew install fluid-synth  # or sudo apt install fluidsynth

# Convert
fluidsynth -ni soundfont.sf2 arpeggio.mid -F output.wav -r 44100

Replace soundfont.sf2 with a valid soundfont file on your system.

4. Add Effects with PyDub

Once you have a WAV file, you can apply audio effects using PyDub:

from pydub import AudioSegment
from pydub.playback import play

sound = AudioSegment.from_wav("output.wav")

# Add echo effect
echo = sound + sound.reverse().fade_out(2000)
play(echo)

5. Advanced: Random Melody Generator

Let’s generate a randomized melody in a scale:

import random
from mido import Message, MidiFile, MidiTrack

scale = [60, 62, 64, 65, 67, 69, 71, 72]  # C major

mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)

for _ in range(16):
    note = random.choice(scale)
    track.append(Message('note_on', note=note, velocity=64, time=0))
    track.append(Message('note_off', note=note, velocity=64, time=480))

mid.save('random_melody.mid')

Conclusion

With just a few lines of Python, you can start exploring generative music and procedural audio techniques. From creating MIDI sequences to applying post-processing effects with PyDub, this workflow enables a lot of creative potential for games, interactive installations, or just fun experimentation.

If this post helped you, consider supporting me here: buymeacoffee.com/hexshift