spiffyscore
File Annotation
Not logged in
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()