forked from Arshad221b/Automatic-Music-Transcription
/
split.py
105 lines (90 loc) · 2.75 KB
/
split.py
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import mido
from mido import MidiFile, MidiTrack, Message, MetaMessage
from os import listdir
from os.path import isfile, split, join
import argparse
def split_midi(mid_file, target_dir, default_tempo=500000, target_segment_len=1):
'''Split midi file into many chunks'''
song_name = split(mid_file)[-1][:-4]
mid = MidiFile(mid_file)
# identify the meta messages
metas = []
tempo = default_tempo
for msg in mid:
if msg.type is 'set_tempo':
tempo = msg.tempo
if msg.is_meta:
metas.append(msg)
for meta in metas:
meta.time = int(mido.second2tick(meta.time, mid.ticks_per_beat, tempo))
target = MidiFile()
track = MidiTrack()
track.extend(metas)
target.tracks.append(track)
prefix = 0
time_elapsed = 0
for msg in mid:
# Skip non-note related messages
if msg.is_meta:
continue
time_elapsed += msg.time
if msg.type is not 'end_of_track':
msg.time = int(mido.second2tick(msg.time, mid.ticks_per_beat, tempo))
track.append(msg)
if msg.type is 'end_of_track' or time_elapsed >= target_segment_len:
track.append(MetaMessage('end_of_track'))
target.save(join(target_dir, song_name + '_{}.mid'.format(prefix)))
target = MidiFile()
track = MidiTrack()
track.extend(metas)
target.tracks.append(track)
time_elapsed = 0
prefix += 1
def merge_midi(midis, input_dir, output, default_tempo=500000):
'''Merge midi files into one'''
pairs = [(int(x[:-4].split('_')[-1]), x) for x in midis]
pairs = sorted(pairs, key=lambda x: x[0])
midis = [join(input_dir, x[1]) for x in pairs]
mid = MidiFile(midis[0])
# identify the meta messages
metas = []
# tempo = default_tempo
tempo = default_tempo // 2
for msg in mid:
if msg.type is 'set_tempo':
tempo = msg.tempo
if msg.is_meta:
metas.append(msg)
for meta in metas:
meta.time = int(mido.second2tick(meta.time, mid.ticks_per_beat, tempo))
target = MidiFile()
track = MidiTrack()
track.extend(metas)
target.tracks.append(track)
for midi in midis:
mid = MidiFile(midi)
for msg in mid:
if msg.is_meta:
continue
if msg.type is not 'end_of_track':
msg.time = int(mido.second2tick(msg.time, mid.ticks_per_beat, tempo))
track.append(msg)
track.append(MetaMessage('end_of_track'))
target.save(output)
def main():
print("Running")
input_dir = 'data5/'
target_dir = 'split_midi/'
length = 1/8
# Get all the input midi files
midis = [x for x in listdir(input_dir) if x.endswith('.midi')]
print(midis)
print(listdir(input_dir))
for midi in midis:
print(midi)
try:
split_midi(join(input_dir, midi), target_dir, target_segment_len=length)
except:
print('\tProblem!')
if __name__ == '__main__':
main()