Created
June 1, 2023 20:32
-
-
Save off-by-some/339299589b5df5cc6e1215f4b5981218 to your computer and use it in GitHub Desktop.
MIDI to text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import mido | |
| def translate_midi_to_custom_format(midi_file): | |
| # Load the MIDI file | |
| mid = mido.MidiFile(midi_file) | |
| # Get the format and division from the MIDI file | |
| format = mid.type | |
| division = mid.ticks_per_beat | |
| # Find all the set tempo messages to determine the BPM range | |
| tempos = [] | |
| for msg in mid: | |
| if msg.type == 'set_tempo': | |
| tempo = mido.tempo2bpm(msg.tempo) | |
| tempos.append(tempo) | |
| # Calculate the BPM range if multiple tempos are found | |
| bpm_range = "" | |
| if len(tempos) > 1: | |
| bpm_range = f" {min(tempos)}-{max(tempos)}" | |
| elif len(tempos) == 1: | |
| bpm_range = f" {tempos[0]}" | |
| # Create the header for the custom format | |
| custom_format = [f"MFile(fmt={format} div={division} bpm={bpm_range})"] | |
| # Iterate over each track in the MIDI file | |
| for i, track in enumerate(mid.tracks): | |
| custom_format.append("\n") | |
| # Create a new track entry in the custom format | |
| custom_format.append(f"Track({i+1}) ") | |
| # Check if the track has a name and add it to the custom format | |
| if track.name: | |
| custom_format.append(f'.TN("{track.name}")') | |
| # Iterate over each message in the track | |
| for msg in track: | |
| # Handle known message types | |
| if msg.type in known_message_types: | |
| event = known_message_types[msg.type] | |
| parameters = event["parameters"](msg) | |
| custom_format.append(f"{event['name']} {msg.time}{parameters} ") | |
| # Handle unknown message types | |
| else: | |
| custom_format.append( | |
| f".Unknown({msg.time}, \"{msg.type}\", \"{msg.hex()}\")" | |
| ) | |
| # Add track end marker to the custom format | |
| # Join the custom format lines and return as a string | |
| return "".join(custom_format) | |
| # Dictionary of known MIDI message types and their corresponding custom format events | |
| known_message_types = { | |
| "note_on": {"name": "NOn", "parameters": lambda msg: f"{msg.note} {msg.velocity}"}, | |
| "note_off": {"name": "NOf", "parameters": lambda msg: f"{msg.note} {msg.velocity}"}, | |
| "control_change": {"name": "CC", "parameters": lambda msg: f"{msg.control} {msg.value}"}, | |
| "program_change": {"name": "PC", "parameters": lambda msg: f"{msg.program}"}, | |
| "aftertouch": {"name": "AT", "parameters": lambda msg: f"{msg.note} {msg.value}"}, | |
| "pitchwheel": {"name": "PB", "parameters": lambda msg: f"{msg.pitch}"}, | |
| "channel_pressure": {"name": "PA", "parameters": lambda msg: f"{msg.pressure}"}, | |
| "control_mode_change": {"name": "CMC", "parameters": lambda msg: f"{msg.control} {msg.value}"}, | |
| "songpos": {"name": "SPP", "parameters": lambda msg: f"{msg.pos}"}, | |
| "songselect": {"name": "SS", "parameters": lambda msg: f"{msg.song}"}, | |
| "tune_request": {"name": "TR", "parameters": lambda msg: ""}, | |
| "end_of_track": {"name": "EOT", "parameters": lambda msg: ""}, | |
| "set_tempo": {"name": "ST", "parameters": lambda msg: f" {mido.tempo2bpm(msg.tempo)}"}, | |
| "time_signature": { "name": "TS", "parameters": lambda msg: f"{msg.numerator} {msg.denominator} {msg.clocks_per_click} {msg.notated_32nd_notes_per_beat}"}, | |
| "key_signature": {"name": "KS", "parameters": lambda msg: f', "{msg.key}", {msg.scale}'}, | |
| "sysex": {"name": "SysEx", "parameters": lambda msg: f', "{msg.hex()}"'}, | |
| "universal_sys_ex": {"name": "USysEx", "parameters": lambda msg: f"{msg.device_id} \"{msg.hex()}\""}, | |
| "midi_time_code": {"name": "MTC", "parameters": lambda msg: f"{msg.frame_type} {msg.values}"}, | |
| "sequencer_specific": {"name": "SSMeta", "parameters": lambda msg: f', "{msg.hex()}"'}, | |
| "meta": {"name": "MetaText", "parameters": lambda msg: f', "{msg.text}"'} | |
| } | |
| # Example usage | |
| midi_file = "1.mid" # Replace with the path to your MIDI file | |
| custom_format = translate_midi_to_custom_format(midi_file) | |
| print(custom_format) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment