106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
"sync_test": {
"body": {
"lead_instr": { # Instrument 'melody'
"score_line": "i1 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6",
"octave": 8,
"duration": 30,
"grammars": { # Notes for this instrument to use in this piece
"u": ["D/4 D/4 D/4 D/4 (u)"],
"v": ["C/4 C/4 C/4 C/4 (v)"],
},
},
"follow_instr": { # Instrument 'melody'
"score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 1",
"sync": "lead_instr",
"octave": 8,
"duration": 30,
|
|
|
|
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
"sync_test": {
"body": {
"lead_instr": { # Instrument 'melody'
"score_line": "i1 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6",
"octave": 8,
"duration": 30,
"grammars": { # Notes for this instrument to use in this piece
"u": ["D/4 D/4 D/4 D/4 (v)"],
"v": ["C/4 C/4 C/4 C/4 (u)"],
},
},
"follow_instr": { # Instrument 'melody'
"score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 1",
"sync": "lead_instr",
"octave": 8,
"duration": 30,
|
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
def render_instr(instr, syncs, max_time):
for g in instr["grammars"]:
for i in range(len(instr["grammars"][g])):
instr["grammars"][g][i] = parse.parse(instr["grammars"][g][i])
score= []
try:
score, syncs = choose_phrase(instr, syncs, 0, max_time)
while True:
score_index_to_replace = None
for item in range(len(score)): # Optimize this by caching the index of the last node I replaced and startng there
if isinstance(score[item], tree.Tree):
score_index_to_replace = item
if score_index_to_replace is None:
raise ValueError("No more nodes to fill in")
time_remaining = max_time - score_len(score)
new_phrase, syncs = choose_phrase(instr, syncs, score_len(score), time_remaining)
score = score[:score_index_to_replace-1] + new_phrase + score[score_index_to_replace+1:]
except ValueError:
return (score, syncs)
def choose_phrase(instr, syncs, current_time, time_remaining):
'''Filters grammars for ones that match the sync option, and phrases that fit the time remaining in the score'''
time_filtered_grammars = {}
for grammar in instr["grammars"]:
fitting_phrases = get_phrases_that_fit(instr["grammars"][grammar], time_remaining)
if len(fitting_phrases) > 0:
time_filtered_grammars[grammar] = fitting_phrases
if len(time_filtered_grammars.keys()) == 0:
raise ValueError("No available grammars that will fit in the score")
grammar = None
if instr["sync"] is not None:
guiding_instr = instr["sync"]
sync_node = get_sync_node_at_time(syncs[guiding_instr], current_time)
if sync_node in time_filtered_grammars.keys():
grammar = sync_node
if grammar is None:
grammar = random.choice(time_filtered_grammars.keys())
phrases = time_filtered_grammars[grammar]
if instr["name"] not in syncs.keys():
syncs[instr["name"]] = []
syncs[instr["name"]].append({"node": grammar, "time": current_time})
return random.choice(phrases), syncs
|
|
|
|
|
>
>
|
>
>
|
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
def render_instr(instr, syncs, max_time):
for g in instr["grammars"]:
for i in range(len(instr["grammars"][g])):
instr["grammars"][g][i] = parse.parse(instr["grammars"][g][i])
score= []
try:
score, syncs = choose_phrase(instr, syncs, 0, max_time, None)
while True:
score_index_to_replace = None
for item in range(len(score)): # Optimize this by caching the index of the last node I replaced and startng there
if isinstance(score[item], tree.Tree): # Also, make this use the find_next_node() function (or whatever I called it)
score_index_to_replace = item
if score_index_to_replace is None:
raise ValueError("No more nodes to fill in")
time_remaining = max_time - score_len(score)
new_phrase, syncs = choose_phrase(instr, syncs, score_len(score), time_remaining, score)
score = score[:score_index_to_replace-1] + new_phrase + score[score_index_to_replace+1:]
except ValueError:
return (score, syncs)
def choose_phrase(instr, syncs, current_time, time_remaining, score):
'''Filters grammars for ones that match the sync option, and phrases that fit the time remaining in the score'''
time_filtered_grammars = {}
for grammar in instr["grammars"]:
fitting_phrases = get_phrases_that_fit(instr["grammars"][grammar], time_remaining)
if len(fitting_phrases) > 0:
time_filtered_grammars[grammar] = fitting_phrases
if len(time_filtered_grammars.keys()) == 0:
raise ValueError("No available grammars that will fit in the score")
grammar = None
if instr["sync"] is not None:
guiding_instr = instr["sync"]
sync_node = get_sync_node_at_time(syncs[guiding_instr], current_time)
if sync_node in time_filtered_grammars.keys():
grammar = sync_node
else:
grammar = random.choice(time_filtered_grammars.keys())
if score is None:
grammar = random.choice(time_filtered_grammars.keys())
elif instr["sync"] is None:
grammar = get_next_node(score);
phrases = time_filtered_grammars[grammar]
if instr["name"] not in syncs.keys():
syncs[instr["name"]] = []
syncs[instr["name"]].append({"node": grammar, "time": current_time})
return random.choice(phrases), syncs
|
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
def get_sync_node_at_time(syncs, t):
for s in range(len(syncs)):
if syncs[s]["time"] >= t:
return syncs[s]["node"]
def score_len(score):
total = 0
for n in score:
if not isinstance(n, tree.Tree):
total += n.duration
return total
|
>
>
>
>
>
|
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
def get_sync_node_at_time(syncs, t):
for s in range(len(syncs)):
if syncs[s]["time"] >= t:
return syncs[s]["node"]
def get_next_node(score):
for token in score:
if isinstance(token, tree.Tree):
return token.name
def score_len(score):
total = 0
for n in score:
if not isinstance(n, tree.Tree):
total += n.duration
return total
|