spiffyscore

Check-in [3cac4f013d]
Login
Overview
Comment:Finally broke the program out into functions. It's now much cleaner and easier to underntand.
Timelines: family | ancestors | descendants | both | feature/abc
Files: files | file ages | folders
SHA1: 3cac4f013df3b3a7be932583f18353a04078c6c5
User & Date: brian on 2011-09-22 17:04:24
Other Links: branch diff | manifest | tags
Context
2011-09-22
17:44
Added back in section ordering support check-in: 1560bc634c user: brian tags: feature/abc
17:04
Finally broke the program out into functions. It's now much cleaner and easier to underntand. check-in: 3cac4f013d user: brian tags: feature/abc
2011-09-15
19:19
Movements work again check-in: a9b80ad75f user: brian tags: feature/abc
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Modified cfg.py from [eefff49c8f] to [77ab4fec9b].

     9      9   import parse
    10     10   
    11     11   import tree
    12     12   
    13     13   random.seed(time.time())
    14     14   
    15     15   def main():
    16         -    key = "A"
    17         -    bps = 60/60
    18         -    tempo = 1/bps
    19         -    max_duration = 1
    20         -
    21     16       composition = {
    22     17           "verse1": {
    23     18               "melody": {  # Instrument 'melody'
    24     19                   "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2",
    25     20                   "octave": 8,
    26         -                "duration": 40,
           21  +                "duration": 10,
    27     22                   "grammars": {  # Notes for this instrument to use in this piece
    28     23                       "u": ["C G/2 G/2 G/2 C B, F' C F C B F (w)"],
    29         -                    "w": ['E/4 A/4 D/4 G/4 F/4 F/4 B2 (u)'],
           24  +                    "w": ["E/4 A/4 D/4 G/4 F/4 F/4 B2 (u)"],
    30     25                   },
    31         -                "score": "u u",
    32     26               },
    33     27           },
    34     28           "verse2": {
    35     29               "melody": {  # Instrument 'melody'
    36     30                   "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2",
    37     31                   "octave": 8,
    38         -                "duration": 40,
           32  +                "duration": 10,
    39     33                   "grammars": {  # Notes for this instrument to use in this piece
    40         -                    "u": ["C C C C F/2 F/2 F/2 (u)"],
           34  +                    "u": ["C C C C F/2 F/2 F/2 (u)", "D D G/2 A/2 D D (u)"],
    41     35                   },
    42         -                "score": "u u",
    43     36               },
    44     37           },
    45     38       }
    46         -    print '''f1  0  512  10  1
    47         -            f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
    48         -            f3 0 1025 10 1
    49         -            t 0 60
           39  +    print '''f1 0 512 10 1
           40  +f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
           41  +f3 0 1025 10 1
           42  +t 0 60
    50     43       '''
    51         -    movement_start = 0
    52         -    progression = "verse1 verse2"
    53         -    for comp_name in progression.split():
    54         -        # We need an arbitrary grammar from this instrument to start the score with
    55         -        max_instr =  0
    56         -        for instr_name, instr in composition[comp_name].iteritems():
    57         -            for grammar in instr["grammars"]:
    58         -                for g in range(len(instr["grammars"][grammar])):
    59         -                    instr["grammars"][grammar][g] = parse.parse(instr["grammars"][grammar][g], default_octave=instr["octave"])
    60         -            g = random.choice(instr["grammars"].keys())
    61         -            ins_score = random.choice(instr["grammars"][g])
    62         -#            ins_score = instr["grammars"][g]
    63         -            score_complete = False
    64         -            while score_complete is False:
    65         -                if score_len(ins_score) >= 10:
    66         -                    score_complete = True
    67         -                    break
    68         -                for i in range(len(ins_score)):
    69         -                    if isinstance(ins_score[i], tree.Tree):
    70         -                        unrolled_score = select_node(instr["grammars"][ins_score[i].name])
    71         -                        new_score = ins_score[:i-1] + unrolled_score + ins_score[i+i:]
    72         -                        ins_score = new_score
    73         -                    if i == len(ins_score):
    74         -                        score_complete = True
    75         -                        break
           44  +
           45  +    start = 0
           46  +    for section in composition.values():
           47  +#        for subsection in section
           48  +        instrs = []
           49  +        for instr in section.values():
           50  +            sync = None
           51  +            max_time = instr["duration"]
           52  +            instr_score = render_instr(instr, sync, max_time)
           53  +            instrs.append(instr_score)
           54  +            for line in generate_csound_score(instr_score, instr["score_line"], start):
           55  +                print line
           56  +        longest_score = max(instrs, key=lambda i: score_len(i))
           57  +        start = score_len(longest_score)
           58  +        
           59  +
           60  +
           61  +def render_instr(instr, sync, max_time):
           62  +    grammars = instr["grammars"]
           63  +    for g in instr["grammars"]:
           64  +        for i in range(len(grammars[g])):
           65  +            grammars[g][i] = parse.parse(grammars[g][i])
           66  +    init_node = random.choice(instr["grammars"].keys())
           67  +    init_score = random.choice(instr["grammars"][init_node])
           68  +    score = init_score
           69  +    while True:
           70  +        time_remaining = max_time - score_len(score)
           71  +        try:
           72  +            score = choose_node(score, grammars, time_remaining)
           73  +        except ValueError:
           74  +            break
           75  +    return score
           76  +
           77  +
           78  +def choose_node(score, grammars, time_remaining):
           79  +    if time_remaining <= 0:
           80  +        raise ValueError("No time remaining in the score")
           81  +    node = None
           82  +    node_index = None
           83  +    for item in range(len(score)):
           84  +        if isinstance(score[item], tree.Tree):
           85  +            node = score[item].name
           86  +            node_index = item
           87  +    if node is None:
           88  +        raise ValueError("No more nodes to fill in")
           89  +    options = []
           90  +    for g in range(len(grammars[node])):
           91  +        if score_len(grammars[node][g]) <= time_remaining:
           92  +            options.append(grammars[node][g])
           93  +    if len(options) == 0:
           94  +        raise ValueError("No available grammars that will fit in the score")
           95  +    phrase = random.choice(options)
           96  +    score = score[:node_index-1] + phrase + score[node_index+1:]
           97  +    return score
           98  +
           99  +            
    76    100               
    77    101   
    78         -            ins_score = [n for n in ins_score if not isinstance(n, tree.Tree)]
    79         -            composition[comp_name][instr_name]["score"] = ins_score
          102  +
    80    103   
    81         -            if score_len(ins_score) > max_instr:
    82         -                max_instr = score_len(ins_score)
    83         -            for line in generate_csound_score(composition[comp_name][instr_name]["score"], instr["score_line"], movement_start):
    84         -                print line
    85         -
    86         -        movement_start += max_instr
          104  +#    movement_start = 0
          105  +#    progression = "verse1 verse2"
          106  +#    for comp_name in progression.split():
          107  +#        # We need an arbitrary grammar from this instrument to start the score with
          108  +#        max_instr =  0
          109  +#        for instr_name, instr in composition[comp_name].iteritems():
          110  +#            for grammar in instr["grammars"]:
          111  +#                for g in range(len(instr["grammars"][grammar])):
          112  +#                    instr["grammars"][grammar][g] = parse.parse(instr["grammars"][grammar][g], default_octave=instr["octave"])
          113  +#            g = random.choice(instr["grammars"].keys())
          114  +#            ins_score = random.choice(instr["grammars"][g])
          115  +##            ins_score = instr["grammars"][g]
          116  +#            score_complete = False
          117  +#            while score_complete is False:
          118  +#                if score_len(ins_score) >= instr["duration"]:
          119  +#                    score_complete = True
          120  +#                    break
          121  +#                for i in range(len(ins_score)):
          122  +#                    if isinstance(ins_score[i], tree.Tree):
          123  +#                        unrolled_score = select_node(instr["grammars"][ins_score[i].name])
          124  +#                        new_score = ins_score[:i-1] + unrolled_score + ins_score[i+1:]
          125  +#                        ins_score = new_score
          126  +#                    if i == len(ins_score):
          127  +#                        score_complete = True
          128  +#                        break
          129  +#            
          130  +#
          131  +#            ins_score = [n for n in ins_score if not isinstance(n, tree.Tree)]
          132  +#            composition[comp_name][instr_name]["score"] = ins_score
          133  +#
          134  +#            if score_len(ins_score) > max_instr:
          135  +#                max_instr = score_len(ins_score)
          136  +#            for line in generate_csound_score(composition[comp_name][instr_name]["score"], instr["score_line"], movement_start):
          137  +#                print line
          138  +#
          139  +#        movement_start += max_instr
    87    140   
    88    141   
    89    142   def score_len(score):
    90    143       total = 0
    91    144       for n in score:
    92    145           if not isinstance(n, tree.Tree):
    93    146               total += n.duration
................................................................................
    94    147       return total
    95    148   
    96    149   def select_node(grammar):
    97    150       return random.choice(grammar)
    98    151               
    99    152   
   100    153   def generate_score(score, grammars):
   101         -    pdb.set_trace()
   102    154       while 1:
   103    155           found_substitution = False
   104    156           for key,value in grammars.iteritems():
   105    157               if score.find(key) != -1:
   106    158                   found_substitution = True
   107    159                   while score.find(key) != -1:
   108    160                       score = score.replace(key, random.choice(grammars[key]), 1)
................................................................................
   136    188           if isinstance(token, parse.Chord):  # Chords
   137    189               for note in token.chord: 
   138    190                   note = csound_note_values[note]
   139    191                   csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration})
   140    192           elif isinstance(token, parse.Note):  # Individual notes
   141    193               note = csound_note_values[token.value]
   142    194               csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration})
          195  +        elif isinstance(token, tree.Tree):
          196  +            continue
   143    197           t += token.duration
   144    198       return csound_score
   145    199   
   146    200   
   147    201   if __name__ == "__main__": main() 

Modified test.sco from [5e21d18eb0] to [4da964b4dc].

     1      1   f1  0  512  10  1
     2      2               f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
     3      3               f3 0 1025 10 1
     4      4               t 0 60
     5      5       
     6         -i2 0.000000 0.250000 7000 8.04 2
     7         -i2 0.250000 0.250000 7000 8.09 2
     8         -i2 0.500000 0.250000 7000 8.02 2
     9         -i2 0.750000 0.250000 7000 8.07 2
    10         -i2 1.000000 0.250000 7000 8.05 2
    11         -i2 1.250000 0.250000 7000 8.05 2
    12         -i2 1.500000 0.250000 7000 8.00 2
    13         -i2 1.750000 0.500000 7000 8.07 2
    14         -i2 2.250000 0.500000 7000 8.07 2
    15         -i2 2.750000 0.500000 7000 8.07 2
    16         -i2 3.250000 0.250000 7000 8.00 2
    17         -i2 3.500000 0.250000 7000 7.11 2
    18         -i2 3.750000 0.250000 7000 9.05 2
    19         -i2 4.000000 0.250000 7000 8.00 2
    20         -i2 4.250000 0.250000 7000 8.05 2
    21         -i2 4.500000 0.250000 7000 8.00 2
    22         -i2 4.750000 0.250000 7000 8.11 2
    23         -i2 5.000000 0.250000 7000 8.04 2
    24         -i2 5.250000 0.250000 7000 8.09 2
    25         -i2 5.500000 0.250000 7000 8.02 2
    26         -i2 5.750000 0.250000 7000 8.07 2
    27         -i2 6.000000 0.250000 7000 8.05 2
    28         -i2 6.250000 0.250000 7000 8.05 2
    29         -i2 6.500000 0.250000 7000 8.00 2
    30         -i2 6.750000 0.500000 7000 8.07 2
    31         -i2 7.250000 0.500000 7000 8.07 2
    32         -i2 7.750000 0.500000 7000 8.07 2
    33         -i2 8.250000 0.250000 7000 8.00 2
    34         -i2 8.500000 0.250000 7000 7.11 2
    35         -i2 8.750000 0.250000 7000 9.05 2
    36         -i2 9.000000 0.250000 7000 8.00 2
    37         -i2 9.250000 0.250000 7000 8.05 2
    38         -i2 9.500000 0.250000 7000 8.00 2
    39         -i2 9.750000 0.250000 7000 8.11 2
    40         -i2 10.000000 0.250000 7000 8.05 2
    41         -i2 10.250000 0.250000 7000 8.00 2
    42         -i2 10.500000 0.250000 7000 8.00 2
    43         -i2 10.750000 0.250000 7000 8.00 2
    44         -i2 11.000000 0.250000 7000 8.00 2
    45         -i2 11.250000 0.500000 7000 8.05 2
    46         -i2 11.750000 0.500000 7000 8.05 2
            6  +i2 0.000000 0.250000 7000 8.00 2
            7  +i2 0.250000 0.500000 7000 8.07 2
            8  +i2 0.750000 0.500000 7000 8.07 2
            9  +i2 1.250000 0.500000 7000 8.07 2
           10  +i2 1.750000 0.250000 7000 8.00 2
           11  +i2 2.000000 0.250000 7000 7.11 2
           12  +i2 2.250000 0.250000 7000 9.05 2
           13  +i2 2.500000 0.250000 7000 8.00 2
           14  +i2 2.750000 0.250000 7000 8.05 2
           15  +i2 3.000000 0.250000 7000 8.00 2
           16  +i2 3.250000 0.250000 7000 8.11 2
           17  +i2 3.500000 0.250000 7000 8.04 2
           18  +i2 3.750000 0.250000 7000 8.09 2
           19  +i2 4.000000 0.250000 7000 8.02 2
           20  +i2 4.250000 0.250000 7000 8.07 2
           21  +i2 4.500000 0.250000 7000 8.05 2
           22  +i2 4.750000 0.250000 7000 8.05 2
           23  +i2 5.000000 0.250000 7000 8.00 2
           24  +i2 5.250000 0.500000 7000 8.07 2
           25  +i2 5.750000 0.500000 7000 8.07 2
           26  +i2 6.250000 0.500000 7000 8.07 2
           27  +i2 6.750000 0.250000 7000 8.00 2
           28  +i2 7.000000 0.250000 7000 7.11 2
           29  +i2 7.250000 0.250000 7000 9.05 2
           30  +i2 7.500000 0.250000 7000 8.00 2
           31  +i2 7.750000 0.250000 7000 8.05 2
           32  +i2 8.000000 0.250000 7000 8.00 2
           33  +i2 8.250000 0.250000 7000 8.11 2
           34  +i2 8.500000 0.250000 7000 8.04 2
           35  +i2 8.750000 0.250000 7000 8.09 2
           36  +i2 9.000000 0.250000 7000 8.02 2
           37  +i2 9.250000 0.250000 7000 8.07 2
           38  +i2 9.500000 0.250000 7000 8.05 2
           39  +i2 9.750000 0.250000 7000 8.05 2
           40  +i2 10.000000 2.000000 7000 8.11 2
           41  +i2 12.000000 0.250000 7000 8.00 2
    47     42   i2 12.250000 0.250000 7000 8.00 2
    48     43   i2 12.500000 0.250000 7000 8.00 2
    49     44   i2 12.750000 0.250000 7000 8.00 2
    50         -i2 13.000000 0.250000 7000 8.00 2
    51         -i2 13.250000 0.500000 7000 8.05 2
    52         -i2 13.750000 0.500000 7000 8.05 2
           45  +i2 13.000000 0.500000 7000 8.05 2
           46  +i2 13.500000 0.500000 7000 8.05 2
           47  +i2 14.000000 0.250000 7000 8.00 2
    53     48   i2 14.250000 0.250000 7000 8.00 2
    54     49   i2 14.500000 0.250000 7000 8.00 2
    55     50   i2 14.750000 0.250000 7000 8.00 2
    56         -i2 15.000000 0.250000 7000 8.00 2
    57         -i2 15.250000 0.500000 7000 8.05 2
    58         -i2 15.750000 0.500000 7000 8.05 2
           51  +i2 15.000000 0.500000 7000 8.05 2
           52  +i2 15.500000 0.500000 7000 8.05 2
           53  +i2 16.000000 0.250000 7000 8.00 2
    59     54   i2 16.250000 0.250000 7000 8.00 2
    60     55   i2 16.500000 0.250000 7000 8.00 2
    61     56   i2 16.750000 0.250000 7000 8.00 2
    62         -i2 17.000000 0.250000 7000 8.00 2
    63         -i2 17.250000 0.500000 7000 8.05 2
    64         -i2 17.750000 0.500000 7000 8.05 2
           57  +i2 17.000000 0.500000 7000 8.05 2
           58  +i2 17.500000 0.500000 7000 8.05 2
           59  +i2 18.000000 0.250000 7000 8.00 2
    65     60   i2 18.250000 0.250000 7000 8.00 2
    66     61   i2 18.500000 0.250000 7000 8.00 2
    67     62   i2 18.750000 0.250000 7000 8.00 2
    68         -i2 19.000000 0.250000 7000 8.00 2
    69         -i2 19.250000 0.500000 7000 8.05 2
    70         -i2 19.750000 0.500000 7000 8.05 2
    71         -i2 20.250000 0.500000 7000 8.05 2
           63  +i2 19.000000 0.500000 7000 8.05 2
           64  +i2 19.500000 0.500000 7000 8.05 2
           65  +i2 20.000000 0.250000 7000 8.00 2
           66  +i2 20.250000 0.250000 7000 8.00 2
           67  +i2 20.500000 0.250000 7000 8.00 2
           68  +i2 20.750000 0.250000 7000 8.00 2
           69  +i2 21.000000 0.500000 7000 8.05 2
           70  +i2 21.500000 0.500000 7000 8.05 2
           71  +i2 22.000000 0.500000 7000 8.05 2