spiffyscore
Diff
Not logged in

Differences From Artifact [52bf709d429e7eb3]:

To Artifact [6468589fdee69e24]:


1 #!/usr/bin/env python 1 #!/usr/bin/env python 2 2 3 from __future__ import division 3 from __future__ import division 4 import os | 4 import ipdb 5 import pdb | 5 import os 6 import random 6 import random 7 import sys 7 import sys 8 import time 8 import time 9 9 10 import parse 10 import parse 11 import topsort 11 import topsort 12 import yaml 12 import yaml ................................................................................................................................................................................ 99 "duration": 30, 99 "duration": 30, 100 "grammars": { # Notes for this instrument to use in this pi 100 "grammars": { # Notes for this instrument to use in this pi 101 "u": ["C/4 C/4 C/4 C/4"], 101 "u": ["C/4 C/4 C/4 C/4"], 102 }, 102 }, 103 }, 103 }, 104 }, 104 }, 105 }, 105 }, > 106 "sync_test": { > 107 "body": { > 108 "lead_instr": { # Instrument 'melody' > 109 "score_line": "i1 %(time)f %(duration)f 7000 %(octave)d.%(no > 110 "octave": 8, > 111 "duration": 30, > 112 "grammars": { # Notes for this instrument to use in this pi > 113 "u": ["D/4 D/4 D/4 D/4"], > 114 "v": ["C/4 C/4 C/4 C/4"], > 115 }, > 116 }, > 117 "follow_instr": { # Instrument 'melody' > 118 "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(no > 119 "sync": "lead_instr", > 120 "octave": 8, > 121 "duration": 30, > 122 "grammars": { # Notes for this instrument to use in this pi > 123 "u": ["D/4 D/4 D/4 D/4"], > 124 "v": ["C/4 C/4 C/4 C/4"], > 125 }, > 126 }, > 127 }, > 128 }, 106 } 129 } 107 print '''f1 0 512 10 1 130 print '''f1 0 512 10 1 108 f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08 131 f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08 109 f3 0 1025 10 1 132 f3 0 1025 10 1 110 t 0 100 133 t 0 100 111 ''' 134 ''' 112 135 113 section_start = 0 136 section_start = 0 114 # for section in ["verse1", "verse2"]: 137 # for section in ["verse1", "verse2"]: 115 for section in ["fm_test"]: | 138 for section in ["sync_test"]: 116 print "; Section " + section 139 print "; Section " + section 117 subsection_start = section_start 140 subsection_start = section_start 118 section = composition[section] 141 section = composition[section] 119 for subsection in ["intro", "body", "outro"]: 142 for subsection in ["intro", "body", "outro"]: 120 try: 143 try: 121 print "; Subsection " + subsection 144 print "; Subsection " + subsection 122 subsection = section[subsection] 145 subsection = section[subsection] > 146 123 unordered_instrs = [] 147 unordered_instrs = [] 124 for instr in subsection: 148 for instr in subsection: > 149 subsection[instr]["name"] = instr 125 if not "sync" in subsection[instr]: | 150 if not "sync" in subsection[instr].keys(): 126 subsection[instr]["sync"] = None 151 subsection[instr]["sync"] = None 127 unordered_instrs.append([subsection[instr]["sync"], instr]) 152 unordered_instrs.append([subsection[instr]["sync"], instr]) 128 ordered_instrs = topsort.topsort(unordered_instrs) 153 ordered_instrs = topsort.topsort(unordered_instrs) 129 ordered_instrs.remove(None) | 154 ordered_instrs.remove(None) # None used as a placeholder for so 130 pdb.set_trace() < > 155 131 instrs = [] 156 instrs = [] > 157 syncs = {} 132 for instr in ordered_instrs: 158 for instr in ordered_instrs: 133 print ";Instrument " + instr 159 print ";Instrument " + instr 134 instr = subsection[instr] 160 instr = subsection[instr] 135 sync = None < 136 max_time = instr["duration"] 161 max_time = instr["duration"] 137 instr_score = render_instr(instr, sync, max_time) | 162 instr_score, syncs = render_instr(instr, syncs, max_time) 138 instrs.append(instr_score) 163 instrs.append(instr_score) 139 for line in generate_csound_score(instr_score, instr["score_ 164 for line in generate_csound_score(instr_score, instr["score_ 140 print line 165 print line 141 longest_score = max(instrs, key=lambda i: score_len(i)) 166 longest_score = max(instrs, key=lambda i: score_len(i)) 142 subsection_start += score_len(longest_score) 167 subsection_start += score_len(longest_score) 143 section_start += score_len(longest_score) 168 section_start += score_len(longest_score) 144 except KeyError: 169 except KeyError: 145 pass 170 pass 146 | 171 147 | 172 148 | 173 def render_instr(instr, syncs, max_time): 149 def render_instr(instr, sync, max_time): | 174 for g in instr["grammars"]: 150 grammars = instr["grammars"] | 175 for i in range(len(instr["grammars"][g])): 151 for g in instr["grammars"]: | 176 instr["grammars"][g][i] = parse.parse(instr["grammars"][g][i]) 152 for i in range(len(grammars[g])): | 177 153 grammars[g][i] = parse.parse(grammars[g][i]) | 178 score= [] 154 init_node = random.choice(instr["grammars"].keys()) | 179 try: 155 init_score = random.choice(instr["grammars"][init_node]) | 180 score, syncs = choose_phrase(instr, syncs, 0, max_time) 156 score = init_score | 181 157 while True: | 182 while True: 158 time_remaining = max_time - score_len(score) | 183 score_index_to_replace = None 159 try: | 184 for item in range(len(score)): # Optimize this by caching the index 160 score = choose_node(score, grammars, time_remaining, sync) | 185 if isinstance(score[item], tree.Tree): 161 except ValueError: | 186 score_index_to_replace = item 162 break | 187 if score_index_to_replace is None: 163 return score | 188 raise ValueError("No more nodes to fill in") 164 | 189 165 | 190 time_remaining = max_time - score_len(score) 166 def choose_node(score, grammars, time_remaining, sync): | 191 new_phrase, syncs = choose_phrase(instr, syncs, score_len(score), ti 167 if time_remaining <= 0: | 192 score = score[:node_index-1] + new_phrase + score[node_index+1:] 168 raise ValueError("No time remaining in the score") | 193 169 node = None | 194 except ValueError: 170 node_index = None | 195 return (score, syncs) 171 for item in range(len(score)): | 196 172 if isinstance(score[item], tree.Tree): | 197 173 node = score[item].name | 198 def choose_phrase(instr, syncs, current_time, time_remaining): 174 node_index = item | 199 '''Filters grammars for ones that match the sync option, and phrases that fi 175 if node is None: | 200 time_filtered_grammars = {} 176 raise ValueError("No more nodes to fill in") | 201 for grammar in instr["grammars"]: 177 options = [] | 202 time_filtered_grammars[grammar] = get_phrases_that_fit(instr["grammars"] 178 for g in range(len(grammars[node])): | 203 if len(time_filtered_grammars.keys()) == 0: 179 if score_len(grammars[node][g]) <= time_remaining: | 204 raise ValueError("No available grammars that will fit in the score") 180 options.append(grammars[node][g]) | 205 181 if len(options) == 0: | 206 grammar = None 182 raise ValueError("No available grammars that will fit in the score") | 207 # if instr["name"] == "follow_instr": 183 if sync: | 208 # ipdb.set_trace() 184 pass | 209 if instr["sync"] is not None: 185 else: | 210 guiding_instr = instr["sync"] 186 phrase = random.choice(options) | 211 sync_node = get_sync_node_at_time(syncs[guiding_instr], current_time) 187 score = score[:node_index-1] + phrase + score[node_index+1:] | 212 if sync_node in time_filtered_grammars.keys(): 188 return score | 213 grammar = sync_node > 214 if grammar is None: > 215 grammar = random.choice(time_filtered_grammars.keys()) > 216 phrases = time_filtered_grammars[grammar] > 217 if instr["name"] not in syncs.keys(): > 218 syncs[instr["name"]] = [] > 219 syncs[instr["name"]].append({"node": grammar, "time": current_time}) > 220 > 221 return random.choice(phrases), syncs > 222 > 223 > 224 def get_phrases_that_fit(grammar, time_remaining): > 225 valid_phrases = [] > 226 for phrase in grammar: > 227 if score_len(phrase) <= time_remaining: > 228 valid_phrases.append(phrase) > 229 return valid_phrases > 230 > 231 > 232 def get_sync_node_at_time(syncs, t): > 233 for s in range(len(syncs)): > 234 if syncs[s]["time"] >= t: > 235 return syncs[s]["node"] 189 236 190 237 191 def score_len(score): 238 def score_len(score): 192 total = 0 239 total = 0 193 for n in score: 240 for n in score: 194 if not isinstance(n, tree.Tree): 241 if not isinstance(n, tree.Tree): 195 total += n.duration 242 total += n.duration