-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmidi_inst_rules.py
executable file
·92 lines (67 loc) · 1.81 KB
/
midi_inst_rules.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
import json
import pretty_midi as pm
import utils
def apply_midi_rules(instrument, inst_cls):
"""
:param instrument:
:return:
"""
# TODO: not hard code the file path here...
instrument = pitch_rule(instrument, inst_cls, 'midi_rules/pitch.json')
return instrument
def pitch_rule(inst, inst_cls, rules_file):
"""
:param inst:
:param rules_file:
:return:
"""
rules = json.load(open(rules_file, 'r'))
if inst_cls not in rules.keys():
return inst
if not any(r['enabled'] for r in rules[inst_cls]):
return inst
for rule in rules[inst_cls]:
rule_name = rule['rule_name']
rule_func = utils.get_midi_rule(rule_name)
inst = rule_func(inst, rule)
return inst
def min_max_octave(inst, rule):
"""
Defines a range for instrument.
Shifts any notes are above the max down an octave,
and any notes below the min up an octave.
:param inst:
:param rule:
:return:
"""
min_note = rule['min']
max_note = rule['max']
for note in inst.notes:
while note.pitch < min_note:
note.pitch += 12
while note.pitch > max_note:
note.pitch -= 12
return inst
def move_note(inst, rule):
"""
Moves individual notes from a src to a dest.
:param inst:
:param rule:
:return:
"""
for note_rule in rule['note_rules']:
src_note = note_rule['old']
dest_note = note_rule['new']
for note in inst.notes:
if note.pitch == src_note:
note.pitch = dest_note
return inst
def shift_all_notes(inst, rule):
"""
:param inst:
:param rule:
:return:
"""
shift = rule['shift']
inst.notes = [pm.Note(n.velocity, n.pitch + shift, n.start, n.end) for n in inst.notes]
return inst