6bfc2449ff 2010-11-04 spiffytech@gm: #!/usr/bin/env python 6bfc2449ff 2010-11-04 spiffytech@gm: 5a35ffdd27 2010-11-17 spiffytech@gm: from __future__ import division 6bfc2449ff 2010-11-04 spiffytech@gm: import os 192b8b1639 2011-10-11 brian: import pdb 6bfc2449ff 2010-11-04 spiffytech@gm: import random 6bfc2449ff 2010-11-04 spiffytech@gm: import sys 6bfc2449ff 2010-11-04 spiffytech@gm: import time 689adc054e 2011-02-10 brian@linux-8: 9bd31df856 2010-11-16 spiffytech@gm: import parse 689adc054e 2011-02-10 brian@linux-8: import topsort 689adc054e 2011-02-10 brian@linux-8: import yaml 689adc054e 2011-02-10 brian@linux-8: 192b8b1639 2011-10-11 brian: import tree 192b8b1639 2011-10-11 brian: 192b8b1639 2011-10-11 brian: random.seed(time.time()) 192b8b1639 2011-10-11 brian: 6a17d4d36a 2010-11-12 spiffytech@gm: def main(): 192b8b1639 2011-10-11 brian: composition = { 192b8b1639 2011-10-11 brian: "fm_test": { 192b8b1639 2011-10-11 brian: "intro": { 192b8b1639 2011-10-11 brian: "melody": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2 6 5 1", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 10, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["G/2 G/2 | G/4 G/4 A/4 A/4 | A/2 A/2 | G | G | A | A | A3 (w)"], 192b8b1639 2011-10-11 brian: "w": ["E | E | F | F | G/2 G/2 | G3 (u)"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "verse1": { 192b8b1639 2011-10-11 brian: "intro": { 192b8b1639 2011-10-11 brian: "melody": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 1", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 10, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["G/2 G/2 | G/4 G/4 A/4 A/4 | A/2 A/2 | G | G | A | A | A3 (w)"], 192b8b1639 2011-10-11 brian: "w": ["E | E | F | F | G/2 G/2 | G3 (u)"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "body": { 192b8b1639 2011-10-11 brian: "melody": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 1", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 10, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["C | G/2 G/2 | G/2 G/2 | C | B, | F' | C | F | C | B | F | (w)"], 192b8b1639 2011-10-11 brian: "w": ["E/4 A/4 D/4 G/4 | F/4 F/4 B2 | (u)"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "outro": { 192b8b1639 2011-10-11 brian: "melody": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 1", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 10, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["C/4 C/4 C/4 C/4 | z2"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "verse2": { 192b8b1639 2011-10-11 brian: "body": { 192b8b1639 2011-10-11 brian: "melody": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 1", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 30, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["C | C | C | C | F/2 F/2 | F/2 F/2 | (u)", "D | D | G/2 A/2 | D | D | (u)"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "harmony": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i3 %(time)f %(duration)f 4000 %(octave)d.%(note)s 2 3 5 3", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 30, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["C | C | z | C | C | z/2 F/4 F/2 F/2 | F/2 F/2 | z (u)", "D | D | G/2 A/2 | D | D | z (u)"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "percussion": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i1 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 30, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["C/4 C/4 C/4 C/4 | F/2 F/2 | F/2 F/2 | (u)", "D/4 D/4 G/4 A/4 | D | D | (v)"], 192b8b1639 2011-10-11 brian: "v": ["C | D | E | F | E | D | C | (u)",], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: "outro": { 192b8b1639 2011-10-11 brian: "percussion": { # Instrument 'melody' 192b8b1639 2011-10-11 brian: "score_line": "i1 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6", 192b8b1639 2011-10-11 brian: "octave": 8, 192b8b1639 2011-10-11 brian: "duration": 30, 192b8b1639 2011-10-11 brian: "grammars": { # Notes for this instrument to use in this piece 192b8b1639 2011-10-11 brian: "u": ["C/4 C/4 C/4 C/4"], 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: }, 192b8b1639 2011-10-11 brian: } 192b8b1639 2011-10-11 brian: print '''f1 0 512 10 1 192b8b1639 2011-10-11 brian: f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08 192b8b1639 2011-10-11 brian: f3 0 1025 10 1 192b8b1639 2011-10-11 brian: t 0 100 689adc054e 2011-02-10 brian@linux-8: ''' 702d933446 2011-02-10 brian@linux-8: 192b8b1639 2011-10-11 brian: section_start = 0 192b8b1639 2011-10-11 brian: # for section in ["verse1", "verse2"]: 192b8b1639 2011-10-11 brian: for section in ["fm_test"]: 192b8b1639 2011-10-11 brian: print "; Section " + section 192b8b1639 2011-10-11 brian: subsection_start = section_start 192b8b1639 2011-10-11 brian: section = composition[section] 192b8b1639 2011-10-11 brian: for subsection in ["intro", "body", "outro"]: 192b8b1639 2011-10-11 brian: try: 192b8b1639 2011-10-11 brian: print "; Subsection " + subsection 192b8b1639 2011-10-11 brian: subsection = section[subsection] 192b8b1639 2011-10-11 brian: instrs = [] 192b8b1639 2011-10-11 brian: for instr in subsection: 192b8b1639 2011-10-11 brian: print ";Instrument " + instr 192b8b1639 2011-10-11 brian: instr = subsection[instr] 192b8b1639 2011-10-11 brian: sync = None 192b8b1639 2011-10-11 brian: max_time = instr["duration"] 192b8b1639 2011-10-11 brian: instr_score = render_instr(instr, sync, max_time) 192b8b1639 2011-10-11 brian: instrs.append(instr_score) 192b8b1639 2011-10-11 brian: for line in generate_csound_score(instr_score, instr["score_line"], subsection_start): 192b8b1639 2011-10-11 brian: print line 192b8b1639 2011-10-11 brian: longest_score = max(instrs, key=lambda i: score_len(i)) 192b8b1639 2011-10-11 brian: subsection_start += score_len(longest_score) 192b8b1639 2011-10-11 brian: section_start += score_len(longest_score) 192b8b1639 2011-10-11 brian: except KeyError: 192b8b1639 2011-10-11 brian: pass 192b8b1639 2011-10-11 brian: 702d933446 2011-02-10 brian@linux-8: 702d933446 2011-02-10 brian@linux-8: 192b8b1639 2011-10-11 brian: def render_instr(instr, sync, max_time): 192b8b1639 2011-10-11 brian: grammars = instr["grammars"] 192b8b1639 2011-10-11 brian: for g in instr["grammars"]: 192b8b1639 2011-10-11 brian: for i in range(len(grammars[g])): 192b8b1639 2011-10-11 brian: grammars[g][i] = parse.parse(grammars[g][i]) 192b8b1639 2011-10-11 brian: init_node = random.choice(instr["grammars"].keys()) 192b8b1639 2011-10-11 brian: init_score = random.choice(instr["grammars"][init_node]) 192b8b1639 2011-10-11 brian: score = init_score 192b8b1639 2011-10-11 brian: while True: 192b8b1639 2011-10-11 brian: time_remaining = max_time - score_len(score) 192b8b1639 2011-10-11 brian: try: 192b8b1639 2011-10-11 brian: score = choose_node(score, grammars, time_remaining, sync) 192b8b1639 2011-10-11 brian: except ValueError: 702d933446 2011-02-10 brian@linux-8: break 702d933446 2011-02-10 brian@linux-8: return score 702d933446 2011-02-10 brian@linux-8: 192b8b1639 2011-10-11 brian: 192b8b1639 2011-10-11 brian: def choose_node(score, grammars, time_remaining, sync): 192b8b1639 2011-10-11 brian: if time_remaining <= 0: 192b8b1639 2011-10-11 brian: raise ValueError("No time remaining in the score") 192b8b1639 2011-10-11 brian: node = None 192b8b1639 2011-10-11 brian: node_index = None 192b8b1639 2011-10-11 brian: for item in range(len(score)): 192b8b1639 2011-10-11 brian: if isinstance(score[item], tree.Tree): 192b8b1639 2011-10-11 brian: node = score[item].name 192b8b1639 2011-10-11 brian: node_index = item 192b8b1639 2011-10-11 brian: if node is None: 192b8b1639 2011-10-11 brian: raise ValueError("No more nodes to fill in") 192b8b1639 2011-10-11 brian: options = [] 192b8b1639 2011-10-11 brian: for g in range(len(grammars[node])): 192b8b1639 2011-10-11 brian: if score_len(grammars[node][g]) <= time_remaining: 192b8b1639 2011-10-11 brian: options.append(grammars[node][g]) 192b8b1639 2011-10-11 brian: if len(options) == 0: 192b8b1639 2011-10-11 brian: raise ValueError("No available grammars that will fit in the score") 192b8b1639 2011-10-11 brian: if sync: 192b8b1639 2011-10-11 brian: pass 192b8b1639 2011-10-11 brian: else: 192b8b1639 2011-10-11 brian: phrase = random.choice(options) 192b8b1639 2011-10-11 brian: score = score[:node_index-1] + phrase + score[node_index+1:] 702d933446 2011-02-10 brian@linux-8: return score 702d933446 2011-02-10 brian@linux-8: 702d933446 2011-02-10 brian@linux-8: 192b8b1639 2011-10-11 brian: def score_len(score): 192b8b1639 2011-10-11 brian: total = 0 192b8b1639 2011-10-11 brian: for n in score: 192b8b1639 2011-10-11 brian: if not isinstance(n, tree.Tree): 192b8b1639 2011-10-11 brian: total += n.duration 192b8b1639 2011-10-11 brian: return total 192b8b1639 2011-10-11 brian: 192b8b1639 2011-10-11 brian: 192b8b1639 2011-10-11 brian: def generate_csound_score(score, score_line, t): 6a17d4d36a 2010-11-12 spiffytech@gm: csound_note_values = { 6a17d4d36a 2010-11-12 spiffytech@gm: "C": "00", 6a17d4d36a 2010-11-12 spiffytech@gm: "C#": "01", 6a17d4d36a 2010-11-12 spiffytech@gm: "D": "02", 6a17d4d36a 2010-11-12 spiffytech@gm: "D#": "03", 6a17d4d36a 2010-11-12 spiffytech@gm: "E": "04", 6a17d4d36a 2010-11-12 spiffytech@gm: "F": "05", 6a17d4d36a 2010-11-12 spiffytech@gm: "F#": "06", 6a17d4d36a 2010-11-12 spiffytech@gm: "G": "07", 3cd7a5dcd0 2010-11-12 spiffytech@gm: "G#": "08", 6a17d4d36a 2010-11-12 spiffytech@gm: "A": "09", 6a17d4d36a 2010-11-12 spiffytech@gm: "A#": "10", 6a17d4d36a 2010-11-12 spiffytech@gm: "B": "11", 6a17d4d36a 2010-11-12 spiffytech@gm: } 6a17d4d36a 2010-11-12 spiffytech@gm: csound_score = [] 6a17d4d36a 2010-11-12 spiffytech@gm: for token in score: 9bd31df856 2010-11-16 spiffytech@gm: if isinstance(token, parse.Chord): # Chords 9bd31df856 2010-11-16 spiffytech@gm: for note in token.chord: 5aa14570f1 2010-11-13 spiffytech@gm: note = csound_note_values[note] 192b8b1639 2011-10-11 brian: csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration}) aa88358397 2010-11-17 spiffytech@gm: elif isinstance(token, parse.Note): # Individual notes 9bd31df856 2010-11-16 spiffytech@gm: note = csound_note_values[token.value] 192b8b1639 2011-10-11 brian: csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration}) 192b8b1639 2011-10-11 brian: elif isinstance(token, tree.Tree): 192b8b1639 2011-10-11 brian: continue 192b8b1639 2011-10-11 brian: t += token.duration 6a17d4d36a 2010-11-12 spiffytech@gm: return csound_score 338933c1a8 2010-11-12 spiffytech@gm: 6bfc2449ff 2010-11-04 spiffytech@gm: 6a17d4d36a 2010-11-12 spiffytech@gm: if __name__ == "__main__": main()