Differences From Artifact [52bf709d429e7eb3]:
- Executable file
cfg.py
- 2011-10-13 18:15:20 - part of checkin [fde4a012ea] on branch develop - Program now renders instruments according to sync order (user: brian) [annotate]
To Artifact [368187a13fa4afec]:
- Executable file
cfg.py
- 2011-10-18 20:19:17 - part of checkin [42c3ba150c] on branch refactor - Broke the score generator by not initialing a first phrase in an empty score. Checkpointing so I can refactor and clean things up to make more progress. (user: brian) [annotate]
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