-
Notifications
You must be signed in to change notification settings - Fork 1
/
rhythm_util.py
77 lines (73 loc) · 2.21 KB
/
rhythm_util.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
def get_sixteenths(token):
if token == 'quadruple_whole':
return 64
elif token == 'double_whole':
return 32
elif token == 'whole':
return 16
elif token == 'half':
return 8
elif token == 'quarter':
return 4
elif token == 'eighth':
return 2
elif token == 'sixteenth':
return 1
elif token == 'thirty_second':
return 0.5
elif token == 'sixty_fourth':
return 0.25
return 0
def parse_time_sig(time_sig):
time_sig = time_sig.split('-')[1]
if time_sig == 'C':
return 4, 4
elif time_sig == 'C/':
return 2, 2
elif '/' in time_sig:
top, bottom = time_sig.split('/')
return int(top), int(bottom)
else:
return 4, 4
def time_sig_to_sixteenths(time_sig):
top, bottom = parse_time_sig(time_sig)
return (16 // bottom) * top
def token_to_action(token):
if token in ['barline', '</s>', '<s>']:
return ("RESET", 0)
elif token == 'dot':
return ("USE_LAST_DURATION", 0.5)
elif token == 'dotdot':
return ("USE_LAST_DURATION", 0.25)
elif len(token) > 14 and token[:14] == 'timeSignature-':
return ("SET_TIMESIG", time_sig_to_sixteenths(token))
else:
return ("DECREMENT", get_sixteenths(token))
def is_rhythmically_coherent(tokens):
timeSigs = [t for t in tokens if t[:4] == 'time']
if len(timeSigs) > 1:
return False
sixteenths_left = 0
sixteenths_per_bar = 0
last_duration = 0
anacrusis = True
for token in tokens:
if token[0] == '<':
continue
action, data = token_to_action(token)
if token == "barline":
if sixteenths_left != 0 and not anacrusis:
return False
anacrusis = False
if action == "RESET":
sixteenths_left = sixteenths_per_bar
last_duration = 0
elif action == "USE_LAST_DURATION":
sixteenths_left -= data * last_duration
elif action == "SET_TIMESIG":
sixteenths_per_bar = data
sixteenths_left = data
elif action == "DECREMENT":
sixteenths_left -= data
last_duration = data
return True