DEV Community

Cover image for How to Create Procedural Music in Python Using PyDub and MIDI Files
HexShift
HexShift

Posted on

2 1 2 2 1

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

Quadratic AI

Quadratic AI – The Spreadsheet with AI, Code, and Connections

  • AI-Powered Insights: Ask questions in plain English and get instant visualizations
  • Multi-Language Support: Seamlessly switch between Python, SQL, and JavaScript in one workspace
  • Zero Setup Required: Connect to databases or drag-and-drop files straight from your browser
  • Live Collaboration: Work together in real-time, no matter where your team is located
  • Beyond Formulas: Tackle complex analysis that traditional spreadsheets can't handle

Get started for free.

Watch The Demo 📊✨

Top comments (0)

Jetbrains Survey

Calling all developers!

Participate in the Developer Ecosystem Survey 2025 and get the chance to win a MacBook Pro, an iPhone 16, or other exciting prizes. Contribute to our research on the development landscape.

Take the survey