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
|
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
|
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
+
+
-
+
|
#!/usr/bin/env python
import os
import random
import sys
import time
random.seed(time.time())
import parse
def main():
key = "A"
note_grammars = {
"u": ["I V V V I I IV u u", "I IV u u", "I VII IV u u" , "e"],
"e": [""],
}
chord_grammars = {
"u": ['"I" "IV" "V" "IV" "I" u u', '"I" "VII" "IV" u u', '"I" "V" "IV" u u', "e"],
"e": [""]
}
compose_piece(key, note_grammars)
composition = {
"a": { # Movement block 'a' for reuse throughout the piece
# "melody": { # Instrument 'melody'
# "csound_parameters": {
# "instrument": 1,
# },
# "grammars": { # Notes for this instrument to use in this piece
# "u": ["I V V V I I IV u u", "I IV u u", "I VII IV u u" , "e"],
# "e": [""],
# },
# "score": "u u u",
# },
"rhythm": {
"csound_parameters": {
"instrument": 1,
},
"grammars": {
# "u": ['"I" "ii"/4 "ii"/4 "IV"/2 "V"2 "IV" "I" u u', '"I" "vii" "IV" u u', '"I" "v" "IV" u u', "e"],
"u": ['"i" "I" "ii" "II" "v" "V" u', "e"],
"e": [""]
},
"score": "u u u",
},
},
# "b": {
# "melody": { # Instrument 'melody'
# "csound_parameters": {
# "instrument": 1,
# },
# "grammars": { # Notes for this instrument to use in this piece
compose_piece(key, chord_grammars, chords=True)
def compose_piece(key, grammars, chords=False):
score = ""
while len(score.split()) < 10:
score = "u u u"
score = generate_score(score, grammars)
score = parse.parse(score)
score = transliterate_score(score, key, chords)
score = generate_csound_score(score)
print "f1 0 256 10 1 0 3 ; sine wave function table"
for line in score:
print line
# "u": ["I V I I/2 IV/2 u u", "I4 IV u u", "I IV IV VI V u u" , "e"],
# "e": [""],
# },
# "score": "u u u",
# },
# "rhythm": {
# "csound_parameters": {
# "instrument": 1,
# },
# "grammars": {
# "u": ['"I" "IV"/2 "V"2 "IV" "I" u u', '"I" "VII" "IV" u u', '"I" "V" "IV" u u', "e"],
# "e": [""]
# },
# "score": "u u u",
# },
# },
}
for comp_name, comp in composition.iteritems():
for instr_name, instr in comp.iteritems():
generated_score = generate_score(instr["score"], instr["grammars"]) # Fill in the scores by generating them based on the grammars
# composition[comp_name][instr_name][grammar]["score"] = parse.parse(generate_score) # Return Node/Chord objects
score = parse.parse(generated_score) # Return Node/Chord objects
# Generate timestamps for the notes
t = 0
for note in range(len(score)):
score[note].time = t
t += score[note].duration
composition[comp_name][instr_name]["score"] = score
# Must be done after all note times keyed in, else you c,an't coordinate melodies with the rhythm chords
for comp_name, comp in composition.iteritems():
for instr_name, instr in comp.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"]
print "f1 0 256 10 1 0 3 ; sine wave function table"
final_score = generate_csound_score(composition[comp_name][instr_name]["score"])
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)
if len(score) > 200:
if len(score.split()) > 200:
score = score.replace("u", "")
score = score.replace("e", "")
return score
if found_substitution is False:
break
return score
def transliterate_score(score, key, chords=False):
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 = []
if chords is False:
for i in range(len(score)):
for i in range(len(score)):
if isinstance(score[i], parse.Note):
score[i].value = scale[scale_conversion[score[i].value]-1]
else:
else:
for i in range(len(score)):
chord = []
root_note_index = scale.index(key) + scale_conversion[score[i].value]
chord.append(scale[root_note_index])
if score[i].chord_type == "m": # Minor chords, flat the 3rd
chord.append(scale[(root_note_index+2) % 8])
else:
chord.append(scale[(root_note_index+3) % 8])
chord.append(scale[(root_note_index+3) % 8])
chord.append(scale[(root_note_index+5) % 8])
score[i].chord = chord
return score
def generate_csound_score(score):
csound_note_values = {
|