spiffyscore
Check-in [9bd31df856]
Not logged in
Overview
SHA1 Hash:9bd31df856f40277a57e58faef14e0b9a5449a11
Date: 2010-11-16 18:37:14
User: spiffytech@gmail.com
Comment:Now prints csound code, both notes and chords, replicating the functionality of the original Minimaly Functional Version
Timelines: family | ancestors | descendants | both | ply
Other Links: files | file ages | manifest
Tags And Properties
Changes
hide diffs side-by-side diffs patch

Modified cfg.py from [df0a6863becf2cac] to [8e359b2146853023].

1 1 #!/usr/bin/env python 2 2 3 3 import os 4 4 import random 5 5 import sys 6 6 import time 7 7 random.seed(time.time()) 8 +import parse 8 9 9 10 def main(): 10 11 key = "A" 11 12 note_grammars = { 12 13 "u": ["I V V V I I IV u u", "I IV u u", "I VII IV u u" , "e"], 13 14 "e": [""], 14 15 } 15 16 chord_grammars = { 16 - "u": ["I IV V IV I u u", "I VII IV u u", "I V IV u u", "e"], 17 + "u": ['"I" "IV" "V" "IV" "I" u u', '"I" "VII" "IV" u u', '"I" "V" "IV" u u', "e"], 17 18 "e": [""] 18 19 } 19 20 compose_piece(key, note_grammars) 20 21 compose_piece(key, chord_grammars, chords=True) 21 22 22 23 def compose_piece(key, grammars, chords=False): 23 24 score = "" 24 - while len(score.split()) < 200: 25 + while len(score.split()) < 10: 25 26 score = "u u u" 26 27 score = generate_score(score, grammars) 28 + score = parse.parse(score) 27 29 score = transliterate_score(score, key, chords) 28 30 score = generate_csound_score(score) 29 31 print "f1 0 256 10 1 0 3 ; sine wave function table" 30 32 for line in score: 31 33 print line 32 34 33 35 ................................................................................ 46 48 while 1: 47 49 found_substitution = False 48 50 for key,value in grammars.iteritems(): 49 51 if score.find(key) != -1: 50 52 found_substitution = True 51 53 while score.find(key) != -1: 52 54 score = score.replace(key, random.choice(grammars[key]), 1) 55 + if len(score) > 200: 56 + score = score.replace("u", "") 57 + score = score.replace("e", "") 58 + return score 53 59 if found_substitution is False: 54 60 break 55 61 return score 56 62 57 63 def transliterate_score(score, key, chords=False): 58 64 scale = make_scale(key) 59 65 scale_conversion = { ................................................................................ 64 70 "V": 5, 65 71 "VI": 6, 66 72 "VII": 7, 67 73 "VIII": 8, 68 74 } 69 75 keyed_score = [] 70 76 if chords is False: 71 - for token in score.split(): 72 - keyed_score.append(scale[scale_conversion[token]-1]) 77 + for i in range(len(score)): 78 + score[i].value = scale[scale_conversion[score[i].value]-1] 73 79 else: 74 - for token in score.split(): 80 + for i in range(len(score)): 75 81 chord = [] 76 - root_note_index = scale.index(key) + scale_conversion[token] 82 + root_note_index = scale.index(key) + scale_conversion[score[i].value] 77 83 chord.append(scale[root_note_index]) 78 84 chord.append(scale[(root_note_index+3) % 8]) 79 85 chord.append(scale[(root_note_index+5) % 8]) 80 - keyed_score.append(chord) 81 - return keyed_score 86 + score[i].chord = chord 87 + return score 82 88 83 89 84 90 def generate_csound_score(score): 85 91 csound_note_values = { 86 92 "C": "00", 87 93 "C#": "01", 88 94 "D": "02", ................................................................................ 95 101 "A": "09", 96 102 "A#": "10", 97 103 "B": "11", 98 104 } 99 105 t = 0 100 106 csound_score = [] 101 107 for token in score: 102 - if isinstance(token, list): # Chords 103 - for note in token: 108 + if isinstance(token, parse.Chord): # Chords 109 + for note in token.chord: 104 110 note = csound_note_values[note] 105 111 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}) 106 112 t += 1 107 113 else: # Individual notes 108 - note = csound_note_values[token] 114 + note = csound_note_values[token.value] 109 115 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}) 110 116 t += .25 111 117 return csound_score 112 118 113 119 114 120 if __name__ == "__main__": main()

Modified parse.py from [8130e1065805498f] to [503badc6f216c7e4].

1 1 #!/usr/bin/env python 2 2 3 3 from ply import lex, yacc 4 - 5 -# Tokenize (lex) 6 -tokens = ( 7 - "NOTE_LENGTH", 8 - "BASENOTE", 9 - "ACCIDENTAL", 10 - "REST", 11 - "OCTAVE", 12 - "CHORD_TYPE", 13 - "QUOTE", 14 -) 15 - 16 -t_ignore = " |" 17 - 18 -#t_BASENOTE = r"[A-Ga-g]" 19 -t_BASENOTE = r"I+V?|VI*|i+v?|vi*" 20 -t_ACCIDENTAL = r"\^{1,2}|_{1,2}|=" 21 -t_REST = r"z" 22 -t_OCTAVE = r"'+|,+" 23 -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" 24 -t_QUOTE = '"' 25 - 26 -def t_NOTE_LENGTH(t): 27 - r"/?\d+" 28 - multiplier = float(t.value.strip("/")) 29 - if t.value.startswith("/"): 30 - multiplier = 1/multiplier 31 - t.value = multiplier 32 - return t 33 - 34 -def t_error(t): 35 - raise TypeError("Unknown text '%s'" % (t.value,)) 36 - 37 -lex.lex() 38 - 39 -#lex.input("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") 40 -#s = "GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD" 41 -s = '''I IV V VI I "I" "ii"/2''' 42 -#s = "GF_G,/2" 43 -lex.input(s) 44 -for tok in iter(lex.token, None): 45 - print repr(tok.type), repr(tok.value) 46 - 47 - 48 -# Parse (yacc) 49 - 50 4 class Note(): 51 5 def __init__(self, value, duration=.25, octave=8): 52 6 self.value = value 53 7 self.duration = duration 54 8 self.octave = octave 55 9 self.accidental = None 56 10 def __repr__(self): ................................................................................ 61 15 self.value = value 62 16 self.duration = duration 63 17 self.chord_type = chord_type 64 18 def __repr__(self): 65 19 return "Chord %s %s %s" % (self.value, self.duration, self.chord_type) 66 20 67 21 68 -def p_pitch_list(p): 69 - '''score : score note 70 - score : score chord 71 - ''' 72 - p[0] = p[1] + [p[2]] 22 +def parse(score): 23 + # Tokenize (lex) 24 + tokens = ( 25 + "NOTE_LENGTH", 26 + "BASENOTE", 27 + "ACCIDENTAL", 28 + "REST", 29 + "OCTAVE", 30 + "CHORD_TYPE", 31 + "QUOTE", 32 + ) 33 + 34 + t_ignore = " |" 35 + 36 + #t_BASENOTE = r"[A-Ga-g]" 37 + t_BASENOTE = r"I+V?|VI*|i+v?|vi*" 38 + t_ACCIDENTAL = r"\^{1,2}|_{1,2}|=" 39 + t_REST = r"z" 40 + t_OCTAVE = r"'+|,+" 41 + 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" 42 + t_QUOTE = '"' 43 + 44 + def t_NOTE_LENGTH(t): 45 + r"/?\d+" 46 + multiplier = float(t.value.strip("/")) 47 + if t.value.startswith("/"): 48 + multiplier = 1/multiplier 49 + t.value = multiplier 50 + return t 51 + 52 + def t_error(t): 53 + raise TypeError("Unknown text '%s'" % (t.value,)) 54 + 55 + lex.lex() 56 + 57 + #lex.input("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") 58 + #s = "GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD" 59 + #s = '''I IV V VI I "I" "ii"/2''' 60 + #s = "GF_G,/2" 61 + lex.input(score) 62 + #for tok in iter(lex.token, None): 63 + # print repr(tok.type), repr(tok.value) 64 + 65 + 66 + # Parse (yacc) 67 + 68 + 69 + def p_pitch_list(p): 70 + '''score : score note 71 + score : score chord 72 + ''' 73 + p[0] = p[1] + [p[2]] 74 + 75 + def p_score(p): 76 + '''score : note 77 + score : chord 78 + ''' 79 + p[0] = [p[1]] 80 + 81 + 82 + def p_note(p): 83 + '''note : pitch 84 + ''' 85 + p[0] = p[1] 86 + 87 + 88 + def p_note_length(p): 89 + ''' note : note NOTE_LENGTH 90 + ''' 91 + new_note = p[1] 92 + new_note.duration = p[2] 93 + p[0] = new_note 94 + 95 + def p_chord_length(p): 96 + ''' chord : chord NOTE_LENGTH 97 + ''' 98 + new_note = p[1] 99 + new_note.duration = p[2] 100 + p[0] = new_note 101 + 102 + 103 + def p_chord(p): 104 + '''chord : QUOTE pitch QUOTE 105 + | QUOTE pitch CHORD_TYPE QUOTE 106 + ''' 107 + p[0] = Chord(value=p[2].value) 108 + if len(p) > 3: 109 + p[0].chord_type = p[3] 110 + 73 111 74 -def p_score(p): 75 - '''score : note 76 - score : chord 77 - ''' 78 - p[0] = [p[1]] 112 + def p_accidental(p): 113 + '''pitch : ACCIDENTAL pitch 114 + ''' 115 + p[2].accidental = p[1] 116 + p[0] = p[2] 79 117 80 - 81 -def p_note(p): 82 - '''note : pitch 83 - ''' 84 - p[0] = p[1] 85 - 118 + def p_octave(p): 119 + '''pitch : pitch OCTAVE 120 + ''' 121 + count = len(p[2]) 122 + increment_or_decrement = 1 if p[2][0] == "," else -1 123 + octave = 8 + (count * increment_or_decrement) 124 + p[1].octave = octave 125 + p[0] = p[1] 86 126 87 -def p_note_length(p): 88 - ''' note : note NOTE_LENGTH 89 - ''' 90 - new_note = p[1] 91 - new_note.duration = p[2] 92 - p[0] = new_note 93 - 94 -def p_chord_length(p): 95 - ''' chord : chord NOTE_LENGTH 96 - ''' 97 - new_note = p[1] 98 - new_note.duration = p[2] 99 - p[0] = new_note 127 + def p_pitch(p): 128 + '''pitch : BASENOTE 129 + ''' 130 + p[0] = Note(p[1]) 100 131 101 - 102 -def p_chord(p): 103 - '''chord : QUOTE pitch QUOTE 104 - | QUOTE pitch CHORD_TYPE QUOTE 105 - ''' 106 - p[0] = Chord(value=p[2].value) 107 - if len(p) > 3: 108 - p[0].chord_type = p[3] 109 - 110 - 111 -def p_accidental(p): 112 - '''pitch : ACCIDENTAL pitch 113 - ''' 114 - p[2].accidental = p[1] 115 - p[0] = p[2] 116 - 117 -def p_octave(p): 118 - '''pitch : pitch OCTAVE 119 - ''' 120 - count = len(p[2]) 121 - increment_or_decrement = 1 if p[2][0] == "," else -1 122 - octave = 8 + (count * increment_or_decrement) 123 - p[1].octave = octave 124 - p[0] = p[1] 125 - 126 -def p_pitch(p): 127 - '''pitch : BASENOTE 128 - ''' 129 - p[0] = Note(p[1]) 130 - 131 -def p_error(p): 132 - print "Syntax error at '%s' of element type %s" % (p.value, p.type) 132 + def p_error(p): 133 + print "Syntax error at '%s' of element type %s" % (p.value, p.type) 133 134 134 -yacc.yacc() 135 + yacc.yacc() 135 136 136 -#print yacc.parse("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") 137 -print yacc.parse(s) 137 + #print yacc.parse("GFG B'AB,, | g/2fg gab | GFG BAB | d2A AFD") 138 + return yacc.parse(score)