Skip to content

Instantly share code, notes, and snippets.

@daitomanabe
Last active June 4, 2023 04:30
Show Gist options
  • Save daitomanabe/8bb989334dd686d334619a41d72539c5 to your computer and use it in GitHub Desktop.
Save daitomanabe/8bb989334dd686d334619a41d72539c5 to your computer and use it in GitHub Desktop.
midi_to_csv.py
import mido
import pandas as pd
import argparse
import os
from collections import defaultdict
def midi_to_csv(midi_path, bpm):
mid = mido.MidiFile(midi_path)
active_notes = defaultdict(int)
rows = []
current_time = 0
for i, track in enumerate(mid.tracks):
for msg in track:
if msg.type in ['note_on', 'note_off']:
# Convert ticks to seconds
current_time += mido.tick2second(msg.time, mid.ticks_per_beat, mido.bpm2tempo(bpm))
# Convert seconds to frames (24 frames per second)
frame = round(current_time * 24)
if msg.type == 'note_on':
active_notes[msg.note] = msg.velocity
elif msg.type == 'note_off':
active_notes[msg.note] = 0
# Create a new row for each frame
row = {'frame': frame}
row.update(active_notes)
rows.append(row)
df = pd.DataFrame(rows).fillna(0)
# Derive output file name from input file name
dir_name = os.path.dirname(midi_path)
base_name = os.path.basename(midi_path)
name_without_extension = os.path.splitext(base_name)[0]
csv_path = os.path.join(dir_name, name_without_extension + '.csv')
df.to_csv(csv_path, index=False)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Convert MIDI file to CSV.')
parser.add_argument('midi_file', type=str, help='The path to the MIDI file to convert.')
parser.add_argument('bpm', type=float, help='The beats per minute to use for conversion.')
args = parser.parse_args()
midi_to_csv(args.midi_file, args.bpm)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment