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

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

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51












52
53
54
55
56
57
58
59
60
61
62
63
64
65

66

67
68
69
70



71
72
73

74

75










76
77































78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import parse

import tree

random.seed(time.time())

def main():
    key = "A"
    bps = 60/60
    tempo = 1/bps
    max_duration = 1

    composition = {
        "verse1": {
            "melody": {  # Instrument 'melody'
                "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2",
                "octave": 8,
                "duration": 40,
                "grammars": {  # Notes for this instrument to use in this piece
                    "u": ["C G/2 G/2 G/2 C B, F' C F C B F (w)"],
                    "w": ['E/4 A/4 D/4 G/4 F/4 F/4 B2 (u)'],
                },
                "score": "u u",
            },
        },
        "verse2": {
            "melody": {  # Instrument 'melody'
                "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2",
                "octave": 8,
                "duration": 40,
                "grammars": {  # Notes for this instrument to use in this piece
                    "u": ["C C C C F/2 F/2 F/2 (u)"],
                },
                "score": "u u",
            },
        },
    }
    print '''f1  0  512  10  1
            f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
            f3 0 1025 10 1
            t 0 60
    '''

    movement_start = 0












    progression = "verse1 verse2"
    for comp_name in progression.split():
        # We need an arbitrary grammar from this instrument to start the score with
        max_instr =  0
        for instr_name, instr in composition[comp_name].iteritems():
            for grammar in instr["grammars"]:
                for g in range(len(instr["grammars"][grammar])):
                    instr["grammars"][grammar][g] = parse.parse(instr["grammars"][grammar][g], default_octave=instr["octave"])
            g = random.choice(instr["grammars"].keys())
            ins_score = random.choice(instr["grammars"][g])
#            ins_score = instr["grammars"][g]
            score_complete = False
            while score_complete is False:
                if score_len(ins_score) >= 10:

                    score_complete = True

                    break
                for i in range(len(ins_score)):
                    if isinstance(ins_score[i], tree.Tree):
                        unrolled_score = select_node(instr["grammars"][ins_score[i].name])



                        new_score = ins_score[:i-1] + unrolled_score + ins_score[i+i:]
                        ins_score = new_score
                    if i == len(ins_score):

                        score_complete = True

                        break










            
































            ins_score = [n for n in ins_score if not isinstance(n, tree.Tree)]
            composition[comp_name][instr_name]["score"] = ins_score

            if score_len(ins_score) > max_instr:
                max_instr = score_len(ins_score)
            for line in generate_csound_score(composition[comp_name][instr_name]["score"], instr["score_line"], movement_start):
                print line

        movement_start += max_instr


def score_len(score):
    total = 0
    for n in score:
        if not isinstance(n, tree.Tree):
            total += n.duration
    return total

def select_node(grammar):
    return random.choice(grammar)
            

def generate_score(score, grammars):
    pdb.set_trace()
    while 1:
        found_substitution = False
        for key,value in grammars.iteritems():
            if score.find(key) != -1:
                found_substitution = True
                while score.find(key) != -1:
                    score = score.replace(key, random.choice(grammars[key]), 1)







<
<
<
<
<





|


|

<






|

|

<








>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
<
|
|
>
|
>

|
|
|
>
>
>
|
|
|
>
|
>
|
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|














<







9
10
11
12
13
14
15





16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
import parse

import tree

random.seed(time.time())

def main():





    composition = {
        "verse1": {
            "melody": {  # Instrument 'melody'
                "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2",
                "octave": 8,
                "duration": 10,
                "grammars": {  # Notes for this instrument to use in this piece
                    "u": ["C G/2 G/2 G/2 C B, F' C F C B F (w)"],
                    "w": ["E/4 A/4 D/4 G/4 F/4 F/4 B2 (u)"],
                },

            },
        },
        "verse2": {
            "melody": {  # Instrument 'melody'
                "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2",
                "octave": 8,
                "duration": 10,
                "grammars": {  # Notes for this instrument to use in this piece
                    "u": ["C C C C F/2 F/2 F/2 (u)", "D D G/2 A/2 D D (u)"],
                },

            },
        },
    }
    print '''f1  0  512  10  1
            f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
            f3 0 1025 10 1
            t 0 60
    '''

    start = 0
    for section in composition.values():
#        for subsection in section
        instrs = []
        for instr in section.values():
            sync = None
            max_time = instr["duration"]
            instr_score = render_instr(instr, sync, max_time)
            instrs.append(instr_score)
            for line in generate_csound_score(instr_score, instr["score_line"], start):
                print line
        longest_score = max(instrs, key=lambda i: score_len(i))
        start = score_len(longest_score)
        


def render_instr(instr, sync, max_time):
    grammars = instr["grammars"]
    for g in instr["grammars"]:
        for i in range(len(grammars[g])):
            grammars[g][i] = parse.parse(grammars[g][i])
    init_node = random.choice(instr["grammars"].keys())
    init_score = random.choice(instr["grammars"][init_node])
    score = init_score

    while True:
        time_remaining = max_time - score_len(score)
        try:
            score = choose_node(score, grammars, time_remaining)
        except ValueError:
                    break
    return score


def choose_node(score, grammars, time_remaining):
    if time_remaining <= 0:
        raise ValueError("No time remaining in the score")
    node = None
    node_index = None
    for item in range(len(score)):
        if isinstance(score[item], tree.Tree):
            node = score[item].name
            node_index = item
    if node is None:
        raise ValueError("No more nodes to fill in")
    options = []
    for g in range(len(grammars[node])):
        if score_len(grammars[node][g]) <= time_remaining:
            options.append(grammars[node][g])
    if len(options) == 0:
        raise ValueError("No available grammars that will fit in the score")
    phrase = random.choice(options)
    score = score[:node_index-1] + phrase + score[node_index+1:]
    return score
            

            



#    movement_start = 0
#    progression = "verse1 verse2"
#    for comp_name in progression.split():
#        # We need an arbitrary grammar from this instrument to start the score with
#        max_instr =  0
#        for instr_name, instr in composition[comp_name].iteritems():
#            for grammar in instr["grammars"]:
#                for g in range(len(instr["grammars"][grammar])):
#                    instr["grammars"][grammar][g] = parse.parse(instr["grammars"][grammar][g], default_octave=instr["octave"])
#            g = random.choice(instr["grammars"].keys())
#            ins_score = random.choice(instr["grammars"][g])
##            ins_score = instr["grammars"][g]
#            score_complete = False
#            while score_complete is False:
#                if score_len(ins_score) >= instr["duration"]:
#                    score_complete = True
#                    break
#                for i in range(len(ins_score)):
#                    if isinstance(ins_score[i], tree.Tree):
#                        unrolled_score = select_node(instr["grammars"][ins_score[i].name])
#                        new_score = ins_score[:i-1] + unrolled_score + ins_score[i+1:]
#                        ins_score = new_score
#                    if i == len(ins_score):
#                        score_complete = True
#                        break
#            
#
#            ins_score = [n for n in ins_score if not isinstance(n, tree.Tree)]
#            composition[comp_name][instr_name]["score"] = ins_score
#
#            if score_len(ins_score) > max_instr:
#                max_instr = score_len(ins_score)
#            for line in generate_csound_score(composition[comp_name][instr_name]["score"], instr["score_line"], movement_start):
#                print line
#
#        movement_start += max_instr


def score_len(score):
    total = 0
    for n in score:
        if not isinstance(n, tree.Tree):
            total += n.duration
    return total

def select_node(grammar):
    return random.choice(grammar)
            

def generate_score(score, grammars):

    while 1:
        found_substitution = False
        for key,value in grammars.iteritems():
            if score.find(key) != -1:
                found_substitution = True
                while score.find(key) != -1:
                    score = score.replace(key, random.choice(grammars[key]), 1)
136
137
138
139
140
141
142


143
144
145
146
147
        if isinstance(token, parse.Chord):  # Chords
            for note in token.chord: 
                note = csound_note_values[note]
                csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration})
        elif isinstance(token, parse.Note):  # Individual notes
            note = csound_note_values[token.value]
            csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration})


        t += token.duration
    return csound_score


if __name__ == "__main__": main() 







>
>





188
189
190
191
192
193
194
195
196
197
198
199
200
201
        if isinstance(token, parse.Chord):  # Chords
            for note in token.chord: 
                note = csound_note_values[note]
                csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration})
        elif isinstance(token, parse.Note):  # Individual notes
            note = csound_note_values[token.value]
            csound_score.append(score_line % {"time": t, "octave": token.octave, "note": note, "duration": token.duration})
        elif isinstance(token, tree.Tree):
            continue
        t += token.duration
    return csound_score


if __name__ == "__main__": main() 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67


68



69
70
71
f1  0  512  10  1
            f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
            f3 0 1025 10 1
            t 0 60
    
i2 0.000000 0.250000 7000 8.04 2
i2 0.250000 0.250000 7000 8.09 2
i2 0.500000 0.250000 7000 8.02 2
i2 0.750000 0.250000 7000 8.07 2
i2 1.000000 0.250000 7000 8.05 2
i2 1.250000 0.250000 7000 8.05 2
i2 1.500000 0.250000 7000 8.00 2
i2 1.750000 0.500000 7000 8.07 2
i2 2.250000 0.500000 7000 8.07 2
i2 2.750000 0.500000 7000 8.07 2
i2 3.250000 0.250000 7000 8.00 2
i2 3.500000 0.250000 7000 7.11 2
i2 3.750000 0.250000 7000 9.05 2
i2 4.000000 0.250000 7000 8.00 2
i2 4.250000 0.250000 7000 8.05 2
i2 4.500000 0.250000 7000 8.00 2
i2 4.750000 0.250000 7000 8.11 2
i2 5.000000 0.250000 7000 8.04 2
i2 5.250000 0.250000 7000 8.09 2
i2 5.500000 0.250000 7000 8.02 2


i2 5.750000 0.250000 7000 8.07 2
i2 6.000000 0.250000 7000 8.05 2
i2 6.250000 0.250000 7000 8.05 2
i2 6.500000 0.250000 7000 8.00 2
i2 6.750000 0.500000 7000 8.07 2
i2 7.250000 0.500000 7000 8.07 2
i2 7.750000 0.500000 7000 8.07 2
i2 8.250000 0.250000 7000 8.00 2
i2 8.500000 0.250000 7000 7.11 2
i2 8.750000 0.250000 7000 9.05 2
i2 9.000000 0.250000 7000 8.00 2
i2 9.250000 0.250000 7000 8.05 2
i2 9.500000 0.250000 7000 8.00 2
i2 9.750000 0.250000 7000 8.11 2
i2 10.000000 0.250000 7000 8.05 2
i2 10.250000 0.250000 7000 8.00 2
i2 10.500000 0.250000 7000 8.00 2
i2 10.750000 0.250000 7000 8.00 2
i2 11.000000 0.250000 7000 8.00 2
i2 11.250000 0.500000 7000 8.05 2

i2 11.750000 0.500000 7000 8.05 2
i2 12.250000 0.250000 7000 8.00 2
i2 12.500000 0.250000 7000 8.00 2
i2 12.750000 0.250000 7000 8.00 2
i2 13.000000 0.250000 7000 8.00 2
i2 13.250000 0.500000 7000 8.05 2
i2 13.750000 0.500000 7000 8.05 2
i2 14.250000 0.250000 7000 8.00 2
i2 14.500000 0.250000 7000 8.00 2
i2 14.750000 0.250000 7000 8.00 2
i2 15.000000 0.250000 7000 8.00 2
i2 15.250000 0.500000 7000 8.05 2
i2 15.750000 0.500000 7000 8.05 2
i2 16.250000 0.250000 7000 8.00 2
i2 16.500000 0.250000 7000 8.00 2
i2 16.750000 0.250000 7000 8.00 2
i2 17.000000 0.250000 7000 8.00 2
i2 17.250000 0.500000 7000 8.05 2
i2 17.750000 0.500000 7000 8.05 2
i2 18.250000 0.250000 7000 8.00 2
i2 18.500000 0.250000 7000 8.00 2
i2 18.750000 0.250000 7000 8.00 2


i2 19.000000 0.250000 7000 8.00 2



i2 19.250000 0.500000 7000 8.05 2
i2 19.750000 0.500000 7000 8.05 2
i2 20.250000 0.500000 7000 8.05 2





|
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|



|
|
|



|
|
|



|
|
|



>
>
|
>
>
>
|
|
|
1
2
3
4
5
6






7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
f1  0  512  10  1
            f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
            f3 0 1025 10 1
            t 0 60
    
i2 0.000000 0.250000 7000 8.00 2






i2 0.250000 0.500000 7000 8.07 2
i2 0.750000 0.500000 7000 8.07 2
i2 1.250000 0.500000 7000 8.07 2
i2 1.750000 0.250000 7000 8.00 2
i2 2.000000 0.250000 7000 7.11 2
i2 2.250000 0.250000 7000 9.05 2
i2 2.500000 0.250000 7000 8.00 2
i2 2.750000 0.250000 7000 8.05 2
i2 3.000000 0.250000 7000 8.00 2
i2 3.250000 0.250000 7000 8.11 2
i2 3.500000 0.250000 7000 8.04 2
i2 3.750000 0.250000 7000 8.09 2
i2 4.000000 0.250000 7000 8.02 2
i2 4.250000 0.250000 7000 8.07 2
i2 4.500000 0.250000 7000 8.05 2


i2 4.750000 0.250000 7000 8.05 2
i2 5.000000 0.250000 7000 8.00 2
i2 5.250000 0.500000 7000 8.07 2
i2 5.750000 0.500000 7000 8.07 2
i2 6.250000 0.500000 7000 8.07 2
i2 6.750000 0.250000 7000 8.00 2
i2 7.000000 0.250000 7000 7.11 2
i2 7.250000 0.250000 7000 9.05 2
i2 7.500000 0.250000 7000 8.00 2
i2 7.750000 0.250000 7000 8.05 2
i2 8.000000 0.250000 7000 8.00 2
i2 8.250000 0.250000 7000 8.11 2
i2 8.500000 0.250000 7000 8.04 2
i2 8.750000 0.250000 7000 8.09 2
i2 9.000000 0.250000 7000 8.02 2
i2 9.250000 0.250000 7000 8.07 2
i2 9.500000 0.250000 7000 8.05 2
i2 9.750000 0.250000 7000 8.05 2
i2 10.000000 2.000000 7000 8.11 2
i2 12.000000 0.250000 7000 8.00 2
i2 12.250000 0.250000 7000 8.00 2
i2 12.500000 0.250000 7000 8.00 2
i2 12.750000 0.250000 7000 8.00 2
i2 13.000000 0.500000 7000 8.05 2
i2 13.500000 0.500000 7000 8.05 2
i2 14.000000 0.250000 7000 8.00 2
i2 14.250000 0.250000 7000 8.00 2
i2 14.500000 0.250000 7000 8.00 2
i2 14.750000 0.250000 7000 8.00 2
i2 15.000000 0.500000 7000 8.05 2
i2 15.500000 0.500000 7000 8.05 2
i2 16.000000 0.250000 7000 8.00 2
i2 16.250000 0.250000 7000 8.00 2
i2 16.500000 0.250000 7000 8.00 2
i2 16.750000 0.250000 7000 8.00 2
i2 17.000000 0.500000 7000 8.05 2
i2 17.500000 0.500000 7000 8.05 2
i2 18.000000 0.250000 7000 8.00 2
i2 18.250000 0.250000 7000 8.00 2
i2 18.500000 0.250000 7000 8.00 2
i2 18.750000 0.250000 7000 8.00 2
i2 19.000000 0.500000 7000 8.05 2
i2 19.500000 0.500000 7000 8.05 2
i2 20.000000 0.250000 7000 8.00 2
i2 20.250000 0.250000 7000 8.00 2
i2 20.500000 0.250000 7000 8.00 2
i2 20.750000 0.250000 7000 8.00 2
i2 21.000000 0.500000 7000 8.05 2
i2 21.500000 0.500000 7000 8.05 2
i2 22.000000 0.500000 7000 8.05 2