Index: cfg.py ================================================================== --- cfg.py +++ cfg.py @@ -1,17 +1,20 @@ #!/usr/bin/env python from __future__ import division import os +import pdb import random import sys import time random.seed(time.time()) import parse import topsort import yaml + +from tree import * def main(): key = "A" bps = 60/60 tempo = 1/bps @@ -19,10 +22,11 @@ composition = yaml.load(open("score.yaml")) max_t = 0 # max time encountered so far. Used for movement timing progression = "chorus" + timeline = {} for movement in progression.split(): for section in ["intro", "core", "outro"]: if section in composition[movement].keys(): try: @@ -30,10 +34,35 @@ except topsort.CycleError as ex: print "Your instruments are synced in a circle! This makes no sense!" print movement, section print ex sys.exit(1) + while None in render_order: + render_order.remove(None) + for instrument in render_order: + grammars = composition[movement][section][instrument]["grammars"] + for grammar in grammars: + if isinstance(grammars[grammar], list): + for option in range(len(grammar)): + grammars[grammar][option] = parse.parse(grammars[grammar][option]) + else: + grammars[grammar] = parse.parse(grammars[grammar]) + print section, movement, instrument + print grammars + for grammar in grammars: + t = Tree() + pdb.set_trace() + while reduce(lambda x, y: x+y, [node.time for node in t.traverse_depth_first()]) < instrument["max_duration"]: + pass + timeline[movement][section][instrument] = Tree() + + +def generate_score_phrase(grammar, grammars): +# count_length = +# while count_length < 100000: + + # for comp_name in progression.split(): # comp_start_time = max_t # for instr_name, instr in composition[comp_name].iteritems(): Index: parse.py ================================================================== --- parse.py +++ parse.py @@ -15,11 +15,11 @@ self.value = value self.duration = duration self.chord_type = chord_type self.octave = octave def __repr__(self): - return "Chord %s %s %s" % (self.value, self.duration, self.chord_type, self.octave) + return "Chord %s %d %s %s" % (self.value, self.duration, self.chord_type, self.octave) class Rest(): def __init__(self, duration=.25): self.duration = duration def __repr__(self): @@ -35,22 +35,24 @@ "REST", "OCTAVE", "CHORD_TYPE", "PAREN", "SYNCOPATE", + "NODE", ) t_ignore = " |" - #t_BASENOTE = r"[A-Ga-g]" t_BASENOTE = r"I+V?|VI*|i+v?|vi*" t_ACCIDENTAL = r"\^{1,2}|_{1,2}|=" t_REST = r"z" t_OCTAVE = r"'+|,+" - t_CHORD_TYPE = r"m|7|m7|0|o|\+|mb5|sus|sus4|maj7|mmaj7|7sus4|dim|dim7|7b5|m7b5|6|b6|m6|mb6|46|maj9|9|add9|7b9|m9" + t_CHORD_TYPE = r"m|7|m7|0|o|mb5|sus|sus4|maj7|mmaj7|7sus4|dim|dim7|7b5|m7b5|6|b6|m6|mb6|46|maj9|9|add9|7b9|m9" t_PAREN = "\(|\)" t_SYNCOPATE = "\+|-" +# t_NODE = "\w*(?!(([Vv][Ii]{0,3})|([Ii][Vv]?)))\w+" + t_NODE = "\S+" def t_NOTE_LENGTH(t): r"/?\d+" multiplier = float(t.value.strip("/")) if t.value.startswith("/"): @@ -69,10 +71,11 @@ def p_note_list(p): '''score : score note | score chord | score rest + | score node ''' p[0] = p[1] + [p[2]] def p_score(p): '''score : note @@ -79,10 +82,16 @@ | chord | rest ''' p[0] = [p[1]] + + def p_node(p): + '''node : NODE + ''' + p[0] = p[1] + def p_chord_length(p): ''' chord : chord NOTE_LENGTH ''' new_note = p[1] @@ -103,18 +112,19 @@ | PAREN note CHORD_TYPE PAREN ''' pitch = p[2].value pitch = pitch.upper() p[0] = Chord(value=pitch, octave=default_octave) - if len(p) > 3: + if len(p) > 4: p[0].chord_type = p[3] def p_note_syncopate(p): ''' note : note SYNCOPATE ''' - note.syncopate = p[2] + p[1].syncopate = p[2] + p[0] = p[1] def p_accidental(p): '''note : ACCIDENTAL note '''