TUTORIAL 4 – MIDI CONTENTS TRANSLATION AND MANIPULATION
I. Generating a midi file from flat text
Converting arbitrary text to a MIDI file involves mapping characters to musical notes. There are
multiple ways to do this, such as:
• Assigning ASCII values to MIDI notes.
• Mapping letters (A-G) to musical notes.
• Generating rhythms based on punctuation or spaces.
This program:
1. Maps each character to a MIDI note.
2. Assigns a fixed duration for each note.
3. Saves the output as a MIDI file.
Install mido for MIDI handling
pip install mido
Python Script
from mido import Message, MidiFile, MidiTrack
# Function to convert text to MIDI
def text_to_midi(text, output_file="output.mid"):
midi_file = MidiFile()
track = MidiTrack()
midi_file.tracks.append(track)
# Map characters to MIDI notes (A-G = 60-67, others mapped to nearby range)
for char in text:
note = (ord(char) % 25) + 60 # Keep notes within a musical range
track.append(Message('note_on', note=note, velocity=64, time=100))
track.append(Message('note_off', note=note, velocity=64, time=100))
# Save MIDI file
midi_file.save(output_file)
print(f"MIDI file saved as {output_file}")
# Example text
text = "Hello ET16, you are truly cute mobs!"
text_to_midi(text)
How It Works
1. Each character is converted to a MIDI note.
2. ASCII values are modulo-mapped to stay within a musical range.
3. The script generates note on/off messages.
4. Saves the final MIDI file.
II. Playing back MIDI
Generating a MIDI file from a given music file (such as WAV or MP3) involves two main steps:
import pygame
# Initialize pygame mixer
pygame.init()
pygame.mixer.init()
# Load the MIDI file
midi_file = "output.mid" # Replace with your MIDI file path
pygame.mixer.music.load(midi_file)
# Play the MIDI file
print("Playing MIDI file...")
pygame.mixer.music.play()
# Keep the script running until playback is complete
while pygame.mixer.music.get_busy():
pygame.time.wait(100)
print("Playback finished.")
pygame.mixer.quit()
III. Converting MIDI to text
Let’s use mido again to translate:
import mido
from mido import MidiFile, MidiTrack, Message
def midi_to_text(midi_file, text_file):
midi = MidiFile(midi_file)
with open(text_file, 'w') as f:
for i, track in enumerate(midi.tracks):
f.write(f"Track {i}: {track.name}\n")
for msg in track:
f.write(str(msg) + '\n')
print(f"MIDI converted to text: {text_file}")
# Example usage
midi_to_text("output.mid", "output.txt")
IV. Converting ABC text to MIDI
import mido
from mido import MidiFile, MidiTrack, Message
def text_to_midi(text_file, midi_file):
midi = MidiFile()
track = MidiTrack()
midi.tracks.append(track)
with open(text_file, 'r') as f:
for line in f:
line = line.strip()
if line.startswith("Track"):
continue
try:
msg = mido.Message.from_str(line)
track.append(msg)
except ValueError:
print(f"Skipping invalid line: {line}")
midi.save(midi_file)
print(f"Text converted to MIDI: {midi_file}")
# Example usage
text_to_midi("output.txt", "converted.mid")
V. Converting ABC notation to MIDI
Converting a MIDI file to ABC notation involves:
1. Extracting MIDI events (notes, durations, and tempo).
2. Mapping MIDI note numbers to ABC notation (e.g., MIDI note 60 = C4 in ABC).
3. Generating ABC text format for playback in ABC software (like abc2midi).
Install Dependencies
pip install mido music21
• mido – For reading MIDI files.
• music21 – For note-to-ABC conversion.
Python Program: MIDI to ABC
from mido import MidiFile
from music21 import note, meter
# MIDI note number to ABC notation
def midi_to_abc(midi_note):
pitch = note.Note(midi_note).nameWithOctave # Convert MIDI to note name
pitch = pitch.replace("-", "") # Remove accidentals like "C-4"
return pitch
# Convert MIDI to ABC notation
def midi_to_abc_text(midi_file_path, abc_output_file="output.abc"):
midi = MidiFile(midi_file_path)
abc_notes = []
ticks_per_beat = midi.ticks_per_beat
time_signature = "4/4" # Default time signature
tempo = 120 # Default tempo
for track in midi.tracks:
time = 0
for msg in track:
time += msg.time
if msg.type == 'note_on' and msg.velocity > 0:
duration = round(time / ticks_per_beat, 2) # Convert ticks to beats
pitch = midi_to_abc(msg.note)
abc_notes.append(f"{pitch}{duration}")
# Generate ABC notation
abc_text = f"""X:1
T:MIDI Conversion
M:{time_signature}
Q:1/4={tempo}
L:1/4
K:C
{" ".join(abc_notes)}
"""
# Save to file
with open(abc_output_file, "w") as f:
f.write(abc_text)
print(f"ABC notation saved to {abc_output_file}")
# Example usage
midi_to_abc_text("input.mid")
How It Works
1. Reads MIDI file and extracts note information.
2. Converts MIDI note numbers to ABC pitch names (C4, D4, E4, etc.).
3. Computes durations and converts them to ABC time values.
4. Outputs an ABC file for use with ABC music software.
To convert an ABC notation file to a MIDI file, you can use the music21 library. It can parse ABC
notation, generate MIDI events, and save them as a .mid file.
Python Program: ABC to MIDI
from music21 import converter, midi
def abc_to_midi(abc_file, output_midi="output.mid"):
# Read the ABC file
with open(abc_file, "r") as f:
abc_data = f.read()
# Convert ABC notation to a music21 Stream
score = converter.parse(abc_data, format='abc')
# Convert to MIDI
midi_file = midi.translate.music21ObjectToMidiFile(score)
# Save MIDI file
midi_file.open(output_midi, 'wb')
midi_file.write()
midi_file.close()
print(f"MIDI file saved as {output_midi}")
# Example usage
abc_to_midi("input.abc")
How It Works
1. Reads the ABC notation from a file.
2. Parses it using music21.
3. Converts it into a MIDI sequence.
4. Saves the MIDI file for playback.
Editing MIDI online
You may visually work on a MIDI file via https://signal.vercel.app/edit