spiffyscore

Diff
Login

Differences From Artifact [47205bbb94]:

To Artifact [9313c52f09]:


106
107
108
109
110
111
112
113
114


115
116
117
118
119
120
121
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)"],
                        "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
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)
        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):
                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)
            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):
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 grammar is None:
    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
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