-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpreprocessing.py
More file actions
76 lines (60 loc) · 3.04 KB
/
Copy pathpreprocessing.py
File metadata and controls
76 lines (60 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import os
import mido
from utils import clamp, string_of, is_note_off, is_note_on, compress_outliers, find_best_shift, remove_muted_tracks, remove_short_notes
from ESP32.LookupTables import slowdown_factor, short_note_ticks
path = "./Input_MIDIs"
file_list = os.listdir(path)
all_songs = [file_name[:-4] for file_name in file_list]
input_songs = all_songs
# input_songs = ['MinecraftSweden']
for input_song in input_songs:
print(f'Preprocessing {input_song}...', f'\t\t\t\tSlowed down {slowdown_factor.get(input_song,1.2)}x')
input_file = mido.MidiFile(f'Input_MIDIs/{input_song}.mid')
try:
all_tracks = mido.merge_tracks(input_file.tracks)
best_shift = find_best_shift(all_tracks)
kept_tracks = remove_muted_tracks(input_song, input_file.tracks)
input_track = mido.merge_tracks(kept_tracks)
except:
best_shift = find_best_shift(input_file.tracks[0])
input_track = input_file.tracks[0]
output_track = mido.MidiTrack()
# [Program=25] sets instrument to "acoustic guitar (steel string)"
output_track.append(mido.Message(type='program_change', channel=0, program=25, time=0))
# Strings indexed as per musical convention (e B G D A E)
last_note_played_on = {'e':0, 'B':0, 'G':0, 'D':0, 'A':0, 'E':0}
time_accumulated = 0
for msg in input_track:
# Skip unplayable instructions (instrument, volume, pitch bending, note_off)
if msg.type in ['program_change', 'control_change', 'pitchwheel'] or is_note_off(msg):
time_accumulated += msg.time
continue
if is_note_on(msg):
msg.note += best_shift # Shift all notes to maximize amount in playable range (E2 - G#4)
msg.note = compress_outliers(msg.note) # Any leftover notes raised/lowered in octaves to fit
msg.channel = 0 # Set all notes to same instrument channel
msg.velocity = 64 # All notes at same volume
# Force end last note on current string so new note can be played
guitar_string = string_of(msg.note)
turn_off = mido.Message('note_off')
turn_off.note = last_note_played_on[guitar_string]
turn_off.time = msg.time + time_accumulated
output_track.append(turn_off)
# Reset for current note
msg.time = 0
time_accumulated = 0
last_note_played_on[guitar_string] = msg.note
# Add current instruction to output
output_track.append(msg)
# End final notes
wait_first = 50
for off_note in last_note_played_on.values():
if off_note == 0:
continue
output_track.append(mido.Message('note_off', note=off_note, time=wait_first))
wait_first = 0
output_track = remove_short_notes(output_track, shorter_than_ticks=short_note_ticks.get(input_song, 50))
output_file = mido.MidiFile()
output_file.ticks_per_beat = int(input_file.ticks_per_beat / slowdown_factor.get(input_song, 1.2))
output_file.tracks.append(output_track)
output_file.save(f'Output_MIDIs/{input_song}_Output.mid')