forked from danieldjohnson/biaxial-rnn-music-composition
-
Notifications
You must be signed in to change notification settings - Fork 0
/
data.py
54 lines (42 loc) · 1.85 KB
/
data.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
import itertools
from midi_to_statematrix import upperBound, lowerBound
def startSentinel():
def noteSentinel(note):
position = note
part_position = [position]
pitchclass = (note + lowerBound) % 12
part_pitchclass = [int(i == pitchclass) for i in range(12)]
return part_position + part_pitchclass + [0]*66 + [1]
return [noteSentinel(note) for note in range(upperBound-lowerBound)]
def getOrDefault(l, i, d):
try:
return l[i]
except IndexError:
return d
def buildContext(state):
context = [0]*12
for note, notestate in enumerate(state):
if notestate[0] == 1:
pitchclass = (note + lowerBound) % 12
context[pitchclass] += 1
return context
def buildBeat(time):
return [2*x-1 for x in [time%2, (time//2)%2, (time//4)%2, (time//8)%2]]
def noteInputForm(note, state, context, beat):
position = note
part_position = [position]
pitchclass = (note + lowerBound) % 12
part_pitchclass = [int(i == pitchclass) for i in range(12)]
# Concatenate the note states for the previous vicinity
part_prev_vicinity = list(itertools.chain.from_iterable((getOrDefault(state, note+i, [0,0]) for i in range(-12, 13))))
part_context = context[pitchclass:] + context[:pitchclass]
return part_position + part_pitchclass + part_prev_vicinity + part_context + beat + [0]
def noteStateSingleToInputForm(state,time):
beat = buildBeat(time)
context = buildContext(state)
return [noteInputForm(note, state, context, beat) for note in range(len(state))]
def noteStateMatrixToInputForm(statematrix):
# NOTE: May have to transpose this or transform it in some way to make Theano like it
#[startSentinel()] +
inputform = [ noteStateSingleToInputForm(state,time) for time,state in enumerate(statematrix) ]
return inputform