-
Notifications
You must be signed in to change notification settings - Fork 20
/
drum_note_processor.py
125 lines (103 loc) · 3.72 KB
/
drum_note_processor.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import midi
import pdb
PPQ = 480 # Pulse per quater note
event_per_bar = 16 # to quantise.
min_ppq = PPQ / (event_per_bar/4)
# ignore: 39 hand clap, 54 tambourine, 56 Cowbell, 58 Vibraslap, 60-81
drum_conversion = {35:36, # acoustic bass drum -> bass drum (36)
37:38, 40:38, # 37:side stick, 38: acou snare, 40: electric snare
43:41, # 41 low floor tom, 43 ghigh floor tom
47:45, # 45 low tom, 47 low-mid tom
50:48, # 50 high tom, 48 hi mid tom
44:42, # 42 closed HH, 44 pedal HH
57:49, # 57 Crash 2, 49 Crash 1
59:51, 53:51, 55:51, # 59 Ride 2, 51 Ride 1, 53 Ride bell, 55 Splash
52:49 # 52: China cymbal
}
# k, sn,cHH,oHH,LFtom,ltm,htm,Rde,Crash
allowed_pitch = [36, 38, 42, 46, 41, 45, 48, 51, 49] # 46: open HH
cymbals_pitch = [49, 51] # crash, ride
cymbals_pitch = [] # crash, ride
# pitch_to_midipitch = {36:midi.C_2, # kick # for general MIDI Drum map
# 38:midi.D_2, # Snare
# 39:midi.Eb_2, # hand clap (it's alive by mistake..)
# 41:midi.F_2, # Low floor tom
# 42:midi.Gb_2, # Close HH
# 45:midi.A_2, # Low tom
# 46:midi.Bb_2, # Open HH
# 48:midi.C_3, # Hi Mid Tom
# 49:midi.Db_3, # Crash
# 51:midi.Eb_3 # Ride
# }
pitch_to_midipitch = {36:midi.C_3, # for logic 'SoCal' drum mapping
38:midi.D_3,
39:midi.Eb_3,
41:midi.F_3,
42:midi.Gb_3,
45:midi.A_3,
46:midi.Bb_3,
48:midi.C_4,
49:midi.Db_4,
51:midi.Eb_4
}
class Note:
def __init__(self, pitch, c_tick):
self.pitch = pitch
self.c_tick = c_tick # cumulated_tick of a midi note
def add_index(self, idx):
'''index --> 16-th note-based index starts from 0'''
self.idx = idx
class Note_List():
def __init__(self):
''''''
self.notes = []
self.quantised = False
self.max_idx = None
def add_note(self, note):
'''note: instance of Note class'''
self.notes.append(note)
def quantise(self, minimum_ppq):
'''
e.g. if minimum_ppq=120, quantise by 16-th note.
'''
if not self.quantised:
for note in self.notes:
note.c_tick = ((note.c_tick+minimum_ppq/2)/minimum_ppq)* minimum_ppq # quantise
note.add_index(note.c_tick/minimum_ppq)
self.max_idx = note.idx
if (self.max_idx + 1) % event_per_bar != 0:
self.max_idx += event_per_bar - ((self.max_idx + 1) % event_per_bar) # make sure it has a FULL bar at the end.
self.quantised = True
return
def simplify_drums(self):
''' use only allowed pitch - and converted not allowed pitch to the similar in a sense of drums!
'''
for note in self.notes:
if note.pitch in drum_conversion: # ignore those not included in the key
note.pitch = drum_conversion[note.pitch]
self.notes = [note for note in self.notes if note.pitch in allowed_pitch]
return
def return_as_text(self):
''''''
length = self.max_idx + 1 # of events in the track.
event_track = []
for note_idx in xrange(length):
event_track.append(['0']*len(allowed_pitch))
num_bars = length/event_per_bar# + ceil(len(event_texts_temp) % _event_per_bar)
for note in self.notes:
pitch_here = note.pitch
note_add_pitch_index = allowed_pitch.index(pitch_here) # 0-8
event_track[note.idx][note_add_pitch_index] = '1'
# print note.idx, note.c_tick, note_add_pitch_index, ''.join(event_track[note.idx])
# pdb.set_trace()
event_text_temp = ['0b'+''.join(e) for e in event_track] # encoding to binary
event_text = []
# event_text.append('SONG_BEGIN')
# event_text.append('BAR')
for bar_idx in xrange(num_bars):
event_from = bar_idx * event_per_bar
event_to = event_from + event_per_bar
event_text = event_text + event_text_temp[event_from:event_to]
event_text.append('BAR')
# event_text.append('SONG_END')
return ' '.join(event_text)