spiffyscore

Check-in [9bd31df856]
Login
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:9bd31df856f40277a57e58faef14e0b9a5449a11
User & Date: spiffytech@gmail.com on 2010-11-16 18:37:14
Other Links: 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
Hide Diffs Unified Diffs Ignore Whitespace Patch

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)