spiffyscore
Diff
Not logged in

Differences From Artifact [52bf709d429e7eb3]:

To Artifact [368187a13fa4afec]:


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 os 5 import pdb | 5 import ipdb 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: 125 if not "sync" in subsection[instr]: | 149 if not "sync" in subsection[instr].keys(): 126 subsection[instr]["sync"] = None 150 subsection[instr]["sync"] = None 127 unordered_instrs.append([subsection[instr]["sync"], instr]) 151 unordered_instrs.append([subsection[instr]["sync"], instr]) 128 ordered_instrs = topsort.topsort(unordered_instrs) 152 ordered_instrs = topsort.topsort(unordered_instrs) 129 ordered_instrs.remove(None) | 153 ordered_instrs.remove(None) # None used as a placeholder for so 130 pdb.set_trace() < > 154 131 instrs = [] 155 instrs = [] > 156 syncs = {} 132 for instr in ordered_instrs: 157 for instr in ordered_instrs: 133 print ";Instrument " + instr 158 print ";Instrument " + instr 134 instr = subsection[instr] 159 instr = subsection[instr] 135 sync = None | 160 # ipdb.set_trace() 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 < 149 def render_instr(instr, sync, max_time): | 173 def render_instr(instr, syncs, max_time): 150 grammars = instr["grammars"] < 151 for g in instr["grammars"]: 174 for g in instr["grammars"]: 152 for i in range(len(grammars[g])): | 175 for i in range(len(instr["grammars"][g])): 153 grammars[g][i] = parse.parse(grammars[g][i]) | 176 instr["grammars"][g][i] = parse.parse(instr["grammars"][g][i]) 154 init_node = random.choice(instr["grammars"].keys()) < 155 init_score = random.choice(instr["grammars"][init_node]) < 156 score = init_score | 177 score = [] 157 while True: 178 while True: > 179 # ipdb.set_trace() 158 time_remaining = max_time - score_len(score) 180 time_remaining = max_time - score_len(score) 159 try: 181 try: 160 score = choose_node(score, grammars, time_remaining, sync) | 182 score, syncs = choose_node(score, instr, time_remaining, syncs) 161 except ValueError: 183 except ValueError: 162 break 184 break 163 return score | 185 return (score, syncs) 164 186 165 187 166 def choose_node(score, grammars, time_remaining, sync): | 188 def choose_node(score, instr, time_remaining, syncs): > 189 # ipdb.set_trace() > 190 grammars = instr["grammars"] 167 if time_remaining <= 0: 191 if time_remaining <= 0: 168 raise ValueError("No time remaining in the score") 192 raise ValueError("No time remaining in the score") > 193 > 194 if len(score) == 0: > 195 options = get_node_choices(instr, syncs, score_len(score)) > 196 node = random.choice(options) > 197 phrase = random.choice(instr["grammars"][node]) > 198 > 199 # Find the next node in the score that needs choosing 169 node = None 200 node = None 170 node_index = None 201 node_index = None 171 for item in range(len(score)): 202 for item in range(len(score)): 172 if isinstance(score[item], tree.Tree): 203 if isinstance(score[item], tree.Tree): 173 node = score[item].name 204 node = score[item].name 174 node_index = item 205 node_index = item 175 if node is None: 206 if node is None: 176 raise ValueError("No more nodes to fill in") 207 raise ValueError("No more nodes to fill in") > 208 > 209 options = get_node_choices(instr, syncs, score_len(score)) > 210 node = random.choice(options) > 211 phrase = random.choice(instr["grammars"][node]) > 212 score = score[:node_index-1] + phrase + score[node_index+1:] > 213 return score > 214 > 215 > 216 def get_node_choices(instr, syncs, current_time): > 217 # If this instrument should follow another, choose a grammar node from the c > 218 # ipdb.set_trace() > 219 grammars = instr["grammars"] 177 options = [] 220 options = [] > 221 if instr["sync"] is not None: > 222 guiding_instr = instr["sync"] > 223 sync_node = get_sync_node_at_time(syncs[guiding_instr], current_time) > 224 if sync_node in instr["grammars"].keys(): > 225 options.append(sync_node) > 226 else: 178 for g in range(len(grammars[node])): | 227 for g in range(len(grammars[node])): 179 if score_len(grammars[node][g]) <= time_remaining: | 228 if score_len(grammars[node][g]) <= time_remaining: 180 options.append(grammars[node][g]) | 229 options.append(grammars[node][g]) > 230 else: > 231 for g in range(len(grammars[node])): > 232 if score_len(grammars[node][g]) <= time_remaining: > 233 options.append(grammars[node][g]) 181 if len(options) == 0: 234 if len(options) == 0: 182 raise ValueError("No available grammars that will fit in the score") 235 raise ValueError("No available grammars that will fit in the score") > 236 return options > 237 > 238 > 239 def get_sync_node_at_time(syncs, t): > 240 for s in len(syncs): 183 if sync: | 241 if syncs[s]["time"] > t: 184 pass < 185 else: < 186 phrase = random.choice(options) < 187 score = score[:node_index-1] + phrase + score[node_index+1:] < 188 return score | 242 return syncs[s]["node"] 189 243 190 244 191 def score_len(score): 245 def score_len(score): 192 total = 0 246 total = 0 193 for n in score: 247 for n in score: 194 if not isinstance(n, tree.Tree): 248 if not isinstance(n, tree.Tree): 195 total += n.duration 249 total += n.duration 196 return total 250 return total