Overview
Comment: | Now prints csound code, both notes and chords, replicating the functionality of the original Minimaly Functional Version |
---|---|
Timelines: | family | ancestors | descendants | both | ply |
Files: | files | file ages | folders |
SHA1: |
9bd31df856f40277a57e58faef14e0b9 |
User & Date: | spiffytech@gmail.com on 2010-11-16 18:37:14 |
Other Links: | branch diff | manifest | tags |
Context
2010-11-16
| ||
19:15 | Added todo list Leaf check-in: 3d4ddcbab5 user: spiffytech@gmail.com tags: ply | |
18:37 | Now prints csound code, both notes and chords, replicating the functionality of the original Minimaly Functional Version check-in: 9bd31df856 user: spiffytech@gmail.com tags: ply | |
16:36 | Now parses chord length check-in: 4aeb057ae0 user: spiffytech@gmail.com tags: ply | |
Changes
Modified cfg.py from [df0a6863be] to [8e359b2146].
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 .. 46 47 48 49 50 51 52 53 54 55 56 57 58 59 .. 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 .. 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
#!/usr/bin/env python import os import random import sys import time random.seed(time.time()) 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) compose_piece(key, chord_grammars, chords=True) def compose_piece(key, grammars, chords=False): score = "" while len(score.split()) < 200: score = "u u u" score = generate_score(score, grammars) 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 ................................................................................ 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 found_substitution is False: break return score def transliterate_score(score, key, chords=False): scale = make_scale(key) scale_conversion = { ................................................................................ "V": 5, "VI": 6, "VII": 7, "VIII": 8, } keyed_score = [] if chords is False: for token in score.split(): keyed_score.append(scale[scale_conversion[token]-1]) else: for token in score.split(): chord = [] root_note_index = scale.index(key) + scale_conversion[token] chord.append(scale[root_note_index]) chord.append(scale[(root_note_index+3) % 8]) chord.append(scale[(root_note_index+5) % 8]) keyed_score.append(chord) return keyed_score def generate_csound_score(score): csound_note_values = { "C": "00", "C#": "01", "D": "02", ................................................................................ "A": "09", "A#": "10", "B": "11", } t = 0 csound_score = [] for token in score: if isinstance(token, list): # Chords for note in token: note = csound_note_values[note] csound_score.append("i2 %(time)f 1 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6" % {"time": t, "octave": random.choice([7,8]), "note": note}) t += 1 else: # Individual notes note = csound_note_values[token] csound_score.append("i2 %(time)f 1 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6" % {"time": t, "octave": random.choice([8,9]), "note": note}) t += .25 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 .. 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 .. 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 ... 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
#!/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) 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 ................................................................................ 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: 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): scale = make_scale(key) scale_conversion = { ................................................................................ "V": 5, "VI": 6, "VII": 7, "VIII": 8, } keyed_score = [] if chords is False: for i in range(len(score)): score[i].value = scale[scale_conversion[score[i].value]-1] 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]) 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 = { "C": "00", "C#": "01", "D": "02", ................................................................................ "A": "09", "A#": "10", "B": "11", } t = 0 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("i2 %(time)f 1 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6" % {"time": t, "octave": random.choice([7,8]), "note": note}) t += 1 else: # Individual notes note = csound_note_values[token.value] csound_score.append("i2 %(time)f 1 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6" % {"time": t, "octave": random.choice([8,9]), "note": note}) t += .25 return csound_score if __name__ == "__main__": main() |
Modified parse.py from [8130e10658] to [503badc6f2].
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
..
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
|
#!/usr/bin/env python from ply import lex, yacc # Tokenize (lex) tokens = ( "NOTE_LENGTH", "BASENOTE", "ACCIDENTAL", "REST", "OCTAVE", "CHORD_TYPE", "QUOTE", ) 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_QUOTE = '"' def t_NOTE_LENGTH(t): r"/?\d+" multiplier = float(t.value.strip("/")) if t.value.startswith("/"): multiplier = 1/multiplier t.value = multiplier return t def t_error(t): raise TypeError("Unknown text '%s'" % (t.value,)) lex.lex() #lex.input("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") #s = "GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD" s = '''I IV V VI I "I" "ii"/2''' #s = "GF_G,/2" lex.input(s) for tok in iter(lex.token, None): print repr(tok.type), repr(tok.value) # Parse (yacc) class Note(): def __init__(self, value, duration=.25, octave=8): self.value = value self.duration = duration self.octave = octave self.accidental = None def __repr__(self): ................................................................................ self.value = value self.duration = duration self.chord_type = chord_type def __repr__(self): return "Chord %s %s %s" % (self.value, self.duration, self.chord_type) def p_pitch_list(p): '''score : score note score : score chord ''' p[0] = p[1] + [p[2]] def p_score(p): '''score : note score : chord ''' p[0] = [p[1]] def p_note(p): '''note : pitch ''' p[0] = p[1] def p_note_length(p): ''' note : note NOTE_LENGTH ''' new_note = p[1] new_note.duration = p[2] p[0] = new_note def p_chord_length(p): ''' chord : chord NOTE_LENGTH ''' new_note = p[1] new_note.duration = p[2] p[0] = new_note def p_chord(p): '''chord : QUOTE pitch QUOTE | QUOTE pitch CHORD_TYPE QUOTE ''' p[0] = Chord(value=p[2].value) if len(p) > 3: p[0].chord_type = p[3] def p_accidental(p): '''pitch : ACCIDENTAL pitch ''' p[2].accidental = p[1] p[0] = p[2] def p_octave(p): '''pitch : pitch OCTAVE ''' count = len(p[2]) increment_or_decrement = 1 if p[2][0] == "," else -1 octave = 8 + (count * increment_or_decrement) p[1].octave = octave p[0] = p[1] def p_pitch(p): '''pitch : BASENOTE ''' p[0] = Note(p[1]) def p_error(p): print "Syntax error at '%s' of element type %s" % (p.value, p.type) yacc.yacc() #print yacc.parse("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") print yacc.parse(s) |
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1
2
3
4
5
6
7
8
9
10
..
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
|
#!/usr/bin/env python from ply import lex, yacc class Note(): def __init__(self, value, duration=.25, octave=8): self.value = value self.duration = duration self.octave = octave self.accidental = None def __repr__(self): ................................................................................ self.value = value self.duration = duration self.chord_type = chord_type def __repr__(self): return "Chord %s %s %s" % (self.value, self.duration, self.chord_type) def parse(score): # Tokenize (lex) tokens = ( "NOTE_LENGTH", "BASENOTE", "ACCIDENTAL", "REST", "OCTAVE", "CHORD_TYPE", "QUOTE", ) 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_QUOTE = '"' def t_NOTE_LENGTH(t): r"/?\d+" multiplier = float(t.value.strip("/")) if t.value.startswith("/"): multiplier = 1/multiplier t.value = multiplier return t def t_error(t): raise TypeError("Unknown text '%s'" % (t.value,)) lex.lex() #lex.input("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") #s = "GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD" #s = '''I IV V VI I "I" "ii"/2''' #s = "GF_G,/2" lex.input(score) #for tok in iter(lex.token, None): # print repr(tok.type), repr(tok.value) # Parse (yacc) def p_pitch_list(p): '''score : score note score : score chord ''' p[0] = p[1] + [p[2]] def p_score(p): '''score : note score : chord ''' p[0] = [p[1]] def p_note(p): '''note : pitch ''' p[0] = p[1] def p_note_length(p): ''' note : note NOTE_LENGTH ''' new_note = p[1] new_note.duration = p[2] p[0] = new_note def p_chord_length(p): ''' chord : chord NOTE_LENGTH ''' new_note = p[1] new_note.duration = p[2] p[0] = new_note def p_chord(p): '''chord : QUOTE pitch QUOTE | QUOTE pitch CHORD_TYPE QUOTE ''' p[0] = Chord(value=p[2].value) if len(p) > 3: p[0].chord_type = p[3] def p_accidental(p): '''pitch : ACCIDENTAL pitch ''' p[2].accidental = p[1] p[0] = p[2] def p_octave(p): '''pitch : pitch OCTAVE ''' count = len(p[2]) increment_or_decrement = 1 if p[2][0] == "," else -1 octave = 8 + (count * increment_or_decrement) p[1].octave = octave p[0] = p[1] def p_pitch(p): '''pitch : BASENOTE ''' p[0] = Note(p[1]) def p_error(p): print "Syntax error at '%s' of element type %s" % (p.value, p.type) yacc.yacc() #print yacc.parse("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") return yacc.parse(score) |