Changes In Branch develop
Through [0c3fb3e27f]
Excluding Merge-Ins
This is equivalent to a diff from
689adc054e
to 0c3fb3e27f
Modified cfg.orc
from [9f49be1cae]
to [db9c923851].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
sr=44100
ksmps=20
nchnls=1
nchnls=2
;isf sfload "samples/acoustic_grand_piano_ydp.sf2"
isf sfload "samples/default.sf2"
sfplist isf
sfpassign 0, isf
;gipre sfpreset 0, 0, isf, 0
;gienginenum1 fluidEngine
;isfnum1 fluidLoad "samples/default.sf2"
instr 1
; kcps = 220
; icps = 220
; ifn = 0
; imeth = p4
;; asig pluck 0.7, cpspch(p5), cpspch(p6), ifn, imeth, .1, 10
asound pluck p4, cpspch(p5), cpspch(p6), p7, p8 p9 p10
out asound
asig pluck p4, cpspch(p5), cpspch(p6), p7, p8 p9 p10
outs asig,asig
endin
instr 2
kenv linen p4, .1, p3, .2; envelope
asound oscili kenv, cpspch(p5), p6; oscillator
out asound
outs asound,asound
endin
instr 3
; pylassigni "note", p5
; pylruni "sample_file = 'samples/bass/%.2f.wav' % note"
; Ssample_file pylevali "sample_file"
Ssample_file sprintf "samples/bass/%.2f.wav", p5
asig diskin2 Ssample_file, 1
outs asig,asig
endin
instr 4
asound foscili p4, cpspch(p5), 5, 2, 3, p9
out asound
aFMinst foscili p4, cpspch(p5), p6, p7, p8, p9
endin
;instr 5
; Ssample_file sprintf "samples/violin/%.2f.wav", p5
; asig mp3in Ssample_file, 1
; outs asig,asig
;endin
instr 6
mididefault 60, p3
midinoteonkey p4, p5
inum init p4
ivel init p5
ivel init ivel/127
kamp linsegr 1, 1, 1, .1, 0
kamp = kamp/1000
kfreq init 1
a1,a2 sfplay3 ivel, inum, kamp*ivel, kfreq, 0
outs a1,a2
endin
;instr 7
;
;endin
|
Deleted cfg.py version [e9b556b4f3].
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
|
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
#!/usr/bin/env python
from __future__ import division
import os
import random
import sys
import time
random.seed(time.time())
import parse
import topsort
import yaml
def main():
key = "A"
bps = 60/60
tempo = 1/bps
max_duration = 1
composition = yaml.load(open("score.yaml"))
max_t = 0 # max time encountered so far. Used for movement timing
progression = "chorus"
for movement in progression.split():
for section in ["intro", "core", "outro"]:
if section in composition[movement].keys():
try:
render_order = topsort.topsort([[composition[movement][section][instrument]["sync"], instrument] if "sync" in composition[movement][section][instrument].keys() else [None, instrument] for instrument in composition[movement][section]])
except topsort.CycleError as ex:
print "Your instruments are synced in a circle! This makes no sense!"
print movement, section
print ex
sys.exit(1)
# 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
# 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()
|
Modified parse.py
from [3ec57c3fbe]
to [bcac1af73f].
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
|
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
|
+
+
-
+
-
-
+
-
+
+
-
-
-
+
+
+
+
|
#!/usr/bin/env python
import tree
from ply import lex, yacc
class Note():
def __init__(self, value, duration=.25, octave=8):
def __init__(self, value, duration=1, octave=8):
self.value = value
self.duration = duration
self.octave = octave
self.accidental = None
def __repr__(self):
return "Note %s %s %s" % (self.value, self.duration, self.octave)
class Chord():
def __init__(self, value, duration=.5, chord_type="major", octave=5):
def __init__(self, value, duration=1, chord_type="major", octave=5):
self.value = value
self.duration = duration
self.chord_type = chord_type
self.octave = octave
def __repr__(self):
return "Chord %s %s %s" % (self.value, self.duration, self.chord_type, self.octave)
class Rest():
def __init__(self, duration=.25):
def __init__(self, duration=1):
self.duration = duration
def __repr__(self):
return "Rest node %s" % self.duration
def parse(score, default_octave=8):
# Tokenize (lex)
tokens = (
"NOTE_LENGTH",
"BASENOTE",
"ACCIDENTAL",
"REST",
"OCTAVE",
"CHORD_TYPE",
"PAREN",
"SYNCOPATE",
"NODE",
)
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_BASENOTE = r"[A-Ga-g]"
# t_BASENOTE = r"I+V?|VI*|i+v?|vi*"
t_ACCIDENTAL = r"\^{1}|_{1}|="
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_PAREN = "\(|\)"
t_SYNCOPATE = "\+|-"
t_NODE = r"\([a-zA-Z0-9_-]+\)"
def t_NOTE_LENGTH(t):
r"/?\d+"
multiplier = float(t.value.strip("/"))
if t.value.startswith("/"):
multiplier = 1/multiplier
t.value = multiplier
|
︙ | | |
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
+
+
|
# Parse (yacc)
def p_note_list(p):
'''score : score note
| score chord
| score rest
| score node
'''
p[0] = p[1] + [p[2]]
def p_score(p):
'''score : note
| chord
| rest
| node
'''
p[0] = [p[1]]
def p_chord_length(p):
''' chord : chord NOTE_LENGTH
'''
|
︙ | | |
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
|
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
165
166
167
168
169
170
171
172
173
174
175
176
|
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
|
'''
note.syncopate = p[2]
def p_accidental(p):
'''note : ACCIDENTAL note
'''
p[2].accidental = p[1]
p[0] = p[2]
if p[1] == "^":
p[0] = p[2].value + 1
else:
p[0] = p[2].value - 1
def p_octave(p):
'''note : note OCTAVE
'''
count = len(p[2])
increment_or_decrement = 1 if p[2].startswith("'") else -1
p[1].octave += (count * increment_or_decrement)
p[0] = p[1]
def p_note(p):
'''note : BASENOTE
'''
notes = {
"C": 0,
"D": 2,
"E": 4,
"F": 5,
"G": 7,
"A": 9,
"B": 11
}
n = notes[p[1]]
p[0] = Note(p[1], octave=default_octave)
p[0] = Note(n, octave=default_octave)
def p_rest(p):
''' rest : REST
| REST NOTE_LENGTH
'''
p[0] = Rest()
if len(p) > 2:
p[0].duration = p[2]
def p_node(p):
'''node : NODE
'''
p[0] = tree.Tree(p[1].strip("(").strip(")"))
def p_error(p):
# import ipdb
# ipdb.set_trace()
print p
raise Exception("Syntax error at '%s' of element type %s" % (p.value, p.type))
yacc.yacc()
return yacc.parse(score)
|
Added samples/bass/1.05.wav version [e6f01c2d0c].
cannot compute difference between binary files
Added samples/bass/1.06.wav version [589b4c9c16].
cannot compute difference between binary files
Added samples/bass/1.07.wav version [b5bd0e0b28].
cannot compute difference between binary files
Added samples/bass/1.08.wav version [4e22c8e289].
cannot compute difference between binary files
Added samples/bass/1.09.wav version [8eafba8350].
cannot compute difference between binary files
Added samples/bass/1.10.wav version [6c9d557273].
cannot compute difference between binary files
Added samples/bass/1.11.wav version [d210644e57].
cannot compute difference between binary files
Added samples/bass/2.00.wav version [df0ad67bd3].
cannot compute difference between binary files
Added samples/bass/2.01.wav version [5e4bdb6301].
cannot compute difference between binary files
Added samples/bass/2.02.wav version [2787d975d6].
cannot compute difference between binary files
Added samples/bass/2.03.wav version [6ce7982e46].
cannot compute difference between binary files
Added samples/bass/2.04.wav version [3c3feb5b24].
cannot compute difference between binary files
Added samples/bass/2.05.wav version [569b7181fc].
cannot compute difference between binary files
Added samples/bass/2.06.wav version [297d4f860f].
cannot compute difference between binary files
Added samples/bass/2.07.wav version [1ac14e3cd2].
cannot compute difference between binary files
Added samples/bass/2.08.wav version [b92037909c].
cannot compute difference between binary files
Added samples/bass/2.09.wav version [760599b161].
cannot compute difference between binary files
Added samples/bass/2.10.wav version [3b900ab89f].
cannot compute difference between binary files
Added samples/bass/2.11.wav version [bcaf91186d].
cannot compute difference between binary files
Added samples/bass/3.00.wav version [5d028b32a1].
cannot compute difference between binary files
Added samples/bass/3.01.wav version [9d6dded4d3].
cannot compute difference between binary files
Added samples/bass/3.02.wav version [78dab72fb7].
cannot compute difference between binary files
Added samples/bass/3.03.wav version [9476ff14fb].
cannot compute difference between binary files
Added samples/bass/3.04.wav version [0822a77edf].
cannot compute difference between binary files
Added samples/bass/3.05.wav version [dc233966b5].
cannot compute difference between binary files
Added samples/bass/3.06.wav version [c254ae3482].
cannot compute difference between binary files
Added samples/bass/3.07-old1.wav version [7e77a9e339].
cannot compute difference between binary files
Added samples/bass/3.07.wav version [23ec2fdb73].
cannot compute difference between binary files
Added samples/bass/3.08.wav version [c799d64faf].
cannot compute difference between binary files
Added samples/bass/3.09.wav version [cedce4e5ea].
cannot compute difference between binary files
Added samples/bass/3.10.wav version [bbc1ef4a09].
cannot compute difference between binary files
Added samples/bass/3.11.wav version [f679f5a61b].
cannot compute difference between binary files
Added samples/bass/Bass.arco.mf.sulE.C2B2.aiff version [b705aee00e].
cannot compute difference between binary files
Added samples/bass/Bass.arco.mf.sulE.C3D3.aiff version [17eacace3a].
cannot compute difference between binary files
Added samples/bass/Bass.arco.mf.sulG.C3B3.aiff version [8b429011eb].
cannot compute difference between binary files
Added samples/bass/Bass.arco.mf.sulG.G2B2.aiff version [8c3a1d88c6].
cannot compute difference between binary files
Added samples/bass/test.orc version [2795c8cc70].
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
sr=44100
ksmps=20
nchnls=2
gifn ftgen 105, 0, 524288, -1, "8.05.wav", 0, 0, 1 ; Middle C
gifn ftgen 106, 0, 524288, -1, "8.06.wav", 0, 0, 1 ; Middle C
gifn ftgen 107, 0, 524288, -1, "8.07.wav", 0, 0, 1 ; Middle C
gifn ftgen 108, 0, 524288, -1, "8.08.wav", 0, 0, 1 ; Middle C
gifn ftgen 109, 0, 524288, -1, "8.09.wav", 0, 0, 1 ; Middle C
gifn ftgen 110, 0, 524288, -1, "8.10.wav", 0, 0, 1 ; Middle C
gifn ftgen 111, 0, 524288, -1, "8.18.wav", 0, 0, 1 ; Middle C
instr 1
; if p5=8.05 then
; asig diskin "8.05.wav"
; elseif p5=8.06 then
; asig diskin "8.06.wav"
; elseif p5=8.07 then
; asig diskin "8.07.wav"
; elseif p5=8.08 then
; asig diskin "8.08.wav"
; elseif p5=8.09 then
; asig diskin "8.09.wav"
; elseif p5=8.11 then
; asig diskin "8.10.wav"
; elseif p5=8.11 then
; asig diskin "8.18.wav"
; endif
inum = p5*100
asig loscil 1, 1, inum, 1
outs asig, asig
endin
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added samples/bass/test.sco version [f5f91e8863].
|
1
2
3
4
5
6
7
|
+
+
+
+
+
+
+
|
f1 0 512 10 1
f2 0 8192 10 .24 .64 .88 .76 .06 .5 .34 .08
f3 0 1025 10 1
t 0 100
i1 0.000000 0.50000 7000 1.05
i1 0.500000 1.0000 7000 1.11
|
| | | | | |
Added samples/bass/test.wav version [550291acb7].
cannot compute difference between binary files
Added samples/violin/3.07.wav version [91dadc3e2c].
cannot compute difference between binary files
Added samples/violin/3.08.wav version [be7c18dc74].
cannot compute difference between binary files
Added samples/violin/3.09.wav version [a329787b04].
cannot compute difference between binary files
Added samples/violin/3.10.wav version [9ec0cf45e5].
cannot compute difference between binary files
Added samples/violin/3.11.wav version [febad8547c].
cannot compute difference between binary files
Added samples/violin/4.00.wav version [99a0049e7f].
cannot compute difference between binary files
Added samples/violin/4.01.wav version [c6f6725f8f].
cannot compute difference between binary files
Added samples/violin/4.02.wav version [8facf1aa8c].
cannot compute difference between binary files
Added samples/violin/4.03.wav version [4a79f04135].
cannot compute difference between binary files
Added samples/violin/4.04.wav version [3784e3b4fd].
cannot compute difference between binary files
Added samples/violin/4.05.wav version [426e685d09].
cannot compute difference between binary files
Added samples/violin/4.06.wav version [4508912bc2].
cannot compute difference between binary files
Added samples/violin/4.07.wav version [a1545e9d26].
cannot compute difference between binary files
Added samples/violin/4.08.wav version [a9461ed31b].
cannot compute difference between binary files
Added samples/violin/4.09.wav version [82320d5d1a].
cannot compute difference between binary files
Added samples/violin/4.10.wav version [13c837dfa4].
cannot compute difference between binary files
Added samples/violin/4.11.wav version [cf5017f10d].
cannot compute difference between binary files
Added samples/violin/5.00.wav version [77cf68a157].
cannot compute difference between binary files
Added samples/violin/5.01.wav version [e062aa503b].
cannot compute difference between binary files
Added samples/violin/5.02.wav version [a2c349d8e6].
cannot compute difference between binary files
Added samples/violin/5.03.wav version [00a8ef8b10].
cannot compute difference between binary files
Added samples/violin/5.04.wav version [77dc78528a].
cannot compute difference between binary files
Added samples/violin/5.05.wav version [f392909f77].
cannot compute difference between binary files
Added samples/violin/5.06.wav version [bc6dc8f0c4].
cannot compute difference between binary files
Added samples/violin/5.07.wav version [9a3c68e5f3].
cannot compute difference between binary files
Added samples/violin/5.08.wav version [61c81ce45f].
cannot compute difference between binary files
Added samples/violin/5.09.wav version [9014c1e21a].
cannot compute difference between binary files
Added samples/violin/5.10.wav version [f1fa1241d2].
cannot compute difference between binary files
Added samples/violin/5.11.wav version [d4ed637350].
cannot compute difference between binary files
Added score.yaml version [29fd4ba47c].
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
---
chorus:
core:
rhythm:
csound_line: i1 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6
max_duration: 80
sync: timbre
octave: 7
sustain: 1
grammars:
u:
- (I) (ii)/4 (ii)/4 (IV)/2 (V)2 (IV) (ii) x u
- (I) (vii) (III) y u
- (I) (v) (IV) u u
w: (i) (VII)2 (VI)/4 (V)/4 (i)/4 (VII)2 (VI) (V) w u
x: (III/2) (VI)/2 (III)/2 (vii)2 (i)2 (V) u
y: (I) (vi)2 (IV) (V) y y u
timbre:
csound_line: i3 %(time)f %(duration)f 2000 %(octave)d.%(note)s 2 3 5 3
max_duration: 80
sync: melody
sustain: 1
octave: 6
grammars:
u:
- I2+ VII2 V2 VI2 I2 IV/2 V/2 III2 u
- I2- IV2 V2 IV I V2 III2 II2. u
melody:
csound_line: i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s 2
max_duration: 80
octave: 8
grammars:
u:
- I V/2 V/2 V/2 I VII
- IV' I IV I VII IV
w: III/4 VI/4 II/4 V/4 VI/4 IV/4 VII2
x: I/2 I/2 VI IV/2 V2 z I/2 I/2 VI IV/2 V
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Added spiffyscore.py version [caa7e9ffa7].