spiffyscore

Check-in [7a6ab725ee]
Login
Overview
Comment:Program prints stuff out again
Timelines: family | ancestors | descendants | both | feature/abc
Files: files | file ages | folders
SHA1: 7a6ab725ee01d778ec16889b12b144f93629d769
User & Date: brian on 2011-09-15 19:09:43
Other Links: branch diff | manifest | tags
Context
2011-09-15
19:19
Movements work again check-in: a9b80ad75f user: brian tags: feature/abc
19:09
Program prints stuff out again check-in: 7a6ab725ee user: brian tags: feature/abc
15:28
Got the program to run through again. Now without the roman numerals check-in: 33ddc6fee4 user: brian tags: feature/abc
Changes

Modified cfg.py from [d386f64212] to [6f8ab10545].

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
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
#!/usr/bin/env python

from __future__ import division
import os

import random
import sys
import time

random.seed(time.time())
import parse



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

    composition = {
        "overview": {
            "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": ['E/4 A/4 D/4 G/4 F/4 F/4 B2'],
                },
                "score": "u u",
            },
        },
    }

    max_t = 0  # max time encountered so far. Used for movement timing
    progression = "overview"
#    progression = "zelda1"
    for comp_name in progression.split():
        comp_start_time = max_t
        for instr_name, instr in composition[comp_name].iteritems():
            generated_score = generate_score(instr["score"], instr["grammars"])  # Fill in the scores by generating them based on the grammars
#            print generated_score
            print generated_score
            score = parse.parse(generated_score, default_octave=instr["octave"])  # Return Node/Chord objects

            # Generate timestamps for the notes 
            t = comp_start_time
            for note in range(len(score)):
                score[note].time = t
                score[note].duration *= tempo
                t += score[note].duration
#                print "time difference =", t-comp_start_time
#                print "instrument duration =",composition[comp_name][instr_name]["duration"]
                if (t-comp_start_time) > float(composition[comp_name][instr_name]["duration"]):
#                    print "here"
                    score = score[:note]
                    break
                max_t = t if t > max_t else max_t
            composition[comp_name][instr_name]["score"] = score

    # Must be done after all note times keyed in, else you can't coordinate melodies with the rhythm chords
    print '''f1  0  512  10  1
            f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
            f3 0 1025 10 1
    '''





    for comp_name in progression.split():



        print "; Movement:", comp_name
        for instr_name, instr in composition[comp_name].iteritems():



















#            composition[comp_name][instr_name]["score"] = transliterate_score(composition[comp_name][instr_name]["score"], key)
#            print "\nMovement %s instrument %s" % (comp_name, instr_name)

#            print composition[comp_name][instr_name]["score"] 
            final_score = generate_csound_score(composition[comp_name][instr_name]["score"], composition[comp_name][instr_name]["score_line"])
            for line in final_score:
                print line
            






















def make_scale(key):

    notes = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"]

    scale = [key]

    pos = notes.index(key)
    progression = [2,2,1,2,2,2,1]
    for p in progression:

        pos = (pos + p) % 12

        scale.append(notes[pos])

    return scale





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)
#                    print scoe
                    if len(score.split()) > 2000:
                        for k in grammars.keys():
                            score = score.replace(k, "")
                        return score
        if found_substitution is False:
            break
    return score

def transliterate_score(score, key):
    scale = make_scale(key)
    scale_conversion = {
        "I": 1,
        "II": 2,
        "III": 3,
        "IV": 4,
        "V": 5,
        "VI": 6,
        "VII": 7,
        "VIII": 8,
    }
    keyed_score = []
    for i in range(len(score)):
        if isinstance(score[i], parse.Note):
            score[i].value = scale[scale_conversion[score[i].value]-1]
        elif isinstance(score[i], parse.Chord):
            chord = []
            root_note_index = scale.index(key) + scale_conversion[score[i].value]
            chord.append(scale[root_note_index])
            chord.append(scale[(root_note_index+3) % 8])
            if score[i].chord_type == "m":  # Minor chords, flat the 5th
                chord.append(scale[(root_note_index+4) % 8])
            else:
                chord.append(scale[(root_note_index+5) % 8])
            score[i].chord = chord
        elif isinstance(score[i], parse.Rest):
            pass
    return score


def generate_csound_score(score, score_line):
    csound_note_values = {
        "C": "00",
        "C#": "01",
        "D": "02",
        "D#": "03",
        "E": "04",
        "F": "05",
        "F#": "06",
        "G": "07",
        "G#": "08",
        "A": "09",
        "A#": "10",
        "B": "11",
    }
    csound_score = []

    for token in score:
        if isinstance(token, parse.Chord):  # Chords
            for note in token.chord: 
                note = csound_note_values[note]
                csound_score.append(score_line % {"time": token.time, "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": token.time, "octave": token.octave, "note": note, "duration": token.duration})

    return csound_score


if __name__ == "__main__": main() 




>



>
|
|

>
>













|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




>
>
>
>
>

>
>
>
|

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

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

>
>
>


>
















<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|















>




|


|
>




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
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
161
162
163
164
#!/usr/bin/env python

from __future__ import division
import os
import pdb
import random
import sys
import time
import parse

import tree

random.seed(time.time())

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

    composition = {
        "overview": {
            "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 (u)"],
#                    "w": ['E/4 A/4 D/4 G/4 F/4 F/4 B2'],
                },
                "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
    '''
    movement_start = 0


    max_t = 0  # max time encountered so far. Used for movement timing
    progression = "overview"
    for comp_name in progression.split():
        comp_start_time = max_t
        # We need an arbitrary grammar from this instrument to start the score with
        max_instr =  0
        movement_start += max_instr
        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) >= 50:
                    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




            # Generate timestamps for the notes 
#            t = comp_start_time
#            for note in range(len(ins_score)):
#                ins_score[note].time = t
#                ins_score[note].duration *= tempo
#                t += score[note].duration
##                print "time difference =", t-comp_start_time
##                print "instrument duration =",composition[comp_name][instr_name]["duration"]
#                if (t-comp_start_time) > float(composition[comp_name][instr_name]["duration"]):
##                    print "here"
#                    ins_score = ins_score[:note]
#                    break
#                max_t = t if t > max_t else max_t
#            composition[comp_name][instr_name]["score"] = ins_score

    # Must be done after all note times keyed in, else you can't coordinate melodies with the rhythm chords
#    for comp_name in progression.split():
#        print "; Movement:", comp_name
#        for instr_name, instr in composition[comp_name].iteritems():
##            print "\nMovement %s instrument %s" % (comp_name, instr_name)
##            print composition[comp_name][instr_name]["score"] 
#            final_score = generate_csound_score(composition[comp_name][instr_name]["score"], composition[comp_name][instr_name]["score_line"])
#            for line in final_score:
#                print line

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


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)
#                    print scoe
                    if len(score.split()) > 2000:
                        for k in grammars.keys():
                            score = score.replace(k, "")
                        return score
        if found_substitution is False:
            break
    return score
































def generate_csound_score(score, score_line, t):
    csound_note_values = {
        "C": "00",
        "C#": "01",
        "D": "02",
        "D#": "03",
        "E": "04",
        "F": "05",
        "F#": "06",
        "G": "07",
        "G#": "08",
        "A": "09",
        "A#": "10",
        "B": "11",
    }
    csound_score = []
    pdb.set_trace()
    for token in score:
        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()