mirror of
https://github.com/janishutz/midi-micro-bit_sound-converter.git
synced 2025-11-25 22:04:25 +00:00
Improve midi conversion (actually make it work properly)
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
from mido import MidiFile
|
from mido import MidiFile, tempo2bpm
|
||||||
|
import math
|
||||||
import pyperclip as pc
|
import pyperclip as pc
|
||||||
|
|
||||||
|
|
||||||
class MidiManagement:
|
class MidiManagement:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
self.note_reference = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
|
||||||
|
|
||||||
def addToClipboard(self, text):
|
def addToClipboard(self, text):
|
||||||
pc.copy(text)
|
pc.copy(text)
|
||||||
@@ -25,75 +26,56 @@ class MidiManagement:
|
|||||||
tracknumber += 1
|
tracknumber += 1
|
||||||
output_list = []
|
output_list = []
|
||||||
|
|
||||||
|
tracked_notes = []
|
||||||
|
bpm = 0
|
||||||
|
timing = 20000
|
||||||
|
|
||||||
# Track messages
|
# Track messages
|
||||||
for msg in mid.tracks[tracknumber]:
|
for msg in mid.tracks[tracknumber]:
|
||||||
midi_msg = str(msg)
|
if msg.type == "note_on":
|
||||||
if midi_msg[0:8] == "note_on ":
|
|
||||||
try:
|
try:
|
||||||
msg_loc = midi_msg.index('note=')
|
tracked_notes.append(self.get_note_as_micro_bit_string(msg))
|
||||||
note = midi_msg[msg_loc + 5:msg_loc + 7]
|
|
||||||
note_height = int(note)
|
|
||||||
note_decod_oct = note_height // 12
|
|
||||||
note_decode_tone = note_height % 12
|
|
||||||
note_ext = ""
|
|
||||||
if note_decode_tone == 1:
|
|
||||||
note_ext = "C"
|
|
||||||
elif note_decode_tone == 2:
|
|
||||||
note_ext = "C#"
|
|
||||||
elif note_decode_tone == 3:
|
|
||||||
note_ext = "D"
|
|
||||||
elif note_decode_tone == 4:
|
|
||||||
note_ext = "D#"
|
|
||||||
elif note_decode_tone == 5:
|
|
||||||
note_ext = "E"
|
|
||||||
elif note_decode_tone == 6:
|
|
||||||
note_ext = "F"
|
|
||||||
elif note_decode_tone == 7:
|
|
||||||
note_ext = "F#"
|
|
||||||
elif note_decode_tone == 8:
|
|
||||||
note_ext = "G"
|
|
||||||
elif note_decode_tone == 9:
|
|
||||||
note_ext = "G#"
|
|
||||||
elif note_decode_tone == 10:
|
|
||||||
note_ext = "A"
|
|
||||||
elif note_decode_tone == 11:
|
|
||||||
note_ext = "A#"
|
|
||||||
elif note_decode_tone == 12:
|
|
||||||
note_ext = "H"
|
|
||||||
|
|
||||||
ext_shortened = midi_msg[40:]
|
|
||||||
pos = 0
|
|
||||||
for buchstabe in ext_shortened:
|
|
||||||
if buchstabe == "=":
|
|
||||||
pos += 1
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
pos += 1
|
|
||||||
|
|
||||||
timing_exp = ext_shortened[pos:]
|
|
||||||
output = note_ext
|
|
||||||
output += str(note_decod_oct)
|
|
||||||
output += f":{timing_exp}"
|
|
||||||
output_list.append(str(output))
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
elif midi_msg[0:8] == "note_off":
|
elif msg.type == "note_off":
|
||||||
ext_shortened = midi_msg[40:]
|
# End tracked note at time offset for midi msg (that is relative to start)
|
||||||
pos = 0
|
note = ''
|
||||||
for buchstabe in ext_shortened:
|
try:
|
||||||
if buchstabe == "=":
|
note = self.get_note_as_micro_bit_string(msg)
|
||||||
pos += 1
|
except:
|
||||||
break
|
pass
|
||||||
else:
|
|
||||||
pos += 1
|
|
||||||
output = "R"
|
|
||||||
output += f":{pos}"
|
|
||||||
|
|
||||||
timing_exp = ext_shortened[pos:]
|
# Find note in tracked notes, ignore if not in there
|
||||||
output_list.append(output)
|
index = -1
|
||||||
|
for n in range(len(tracked_notes)):
|
||||||
|
if tracked_notes[n] == note:
|
||||||
|
index = n
|
||||||
|
break;
|
||||||
|
|
||||||
|
# Get duration
|
||||||
|
if index >= 0:
|
||||||
|
tracked_notes.remove(note)
|
||||||
|
t = math.floor(msg.time / timing)
|
||||||
|
|
||||||
|
output_list.append(note + ':' + str(t))
|
||||||
else:
|
else:
|
||||||
|
try:
|
||||||
|
midi_msg = str(msg)
|
||||||
|
i = midi_msg.index('tempo=') + 6
|
||||||
|
units = int(midi_msg[i:i + midi_msg[i:].index(',')])
|
||||||
|
bpm = int(tempo2bpm(units))
|
||||||
|
timing = int(units / bpm / 16)
|
||||||
|
# timing = units per 1/16 beat
|
||||||
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.addToClipboard(str(output_list))
|
self.addToClipboard(str(output_list))
|
||||||
|
|
||||||
|
def get_note_as_micro_bit_string(self, midi_msg):
|
||||||
|
note_value = midi_msg.note
|
||||||
|
octave = note_value // 12
|
||||||
|
tone = note_value % 12
|
||||||
|
|
||||||
|
return self.note_reference[tone] + str(octave)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user