spiffyscore
File Annotation
Not logged in
6bfc2449ff 2010-11-04 spiffytech@gm: #!/usr/bin/env python
6bfc2449ff 2010-11-04 spiffytech@gm: 
5a35ffdd27 2010-11-17 spiffytech@gm: from __future__ import division
6bfc2449ff 2010-11-04 spiffytech@gm: import os
6bfc2449ff 2010-11-04 spiffytech@gm: import random
6bfc2449ff 2010-11-04 spiffytech@gm: import sys
6bfc2449ff 2010-11-04 spiffytech@gm: import time
6bfc2449ff 2010-11-04 spiffytech@gm: random.seed(time.time())
9bd31df856 2010-11-16 spiffytech@gm: import parse
6a17d4d36a 2010-11-12 spiffytech@gm: 
6a17d4d36a 2010-11-12 spiffytech@gm: def main():
729263ecd0 2010-11-13 spiffytech@gm:     key = "A"
5a35ffdd27 2010-11-17 spiffytech@gm:     bps = 80/60
5a35ffdd27 2010-11-17 spiffytech@gm:     print bps
5a35ffdd27 2010-11-17 spiffytech@gm:     tempo = 1/bps
aa88358397 2010-11-17 spiffytech@gm:     max_duration = 1
7c7ce6adb8 2010-11-17 spiffytech@gm: 
7c7ce6adb8 2010-11-17 spiffytech@gm:     composition = {
7c7ce6adb8 2010-11-17 spiffytech@gm:         "a": {  # Movement block 'a' for reuse throughout the piece
db1df2f460 2010-11-17 spiffytech@gm:             "melody": {  # Instrument 'melody'
b8d35587a4 2010-11-17 spiffytech@gm:                 "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6",
db1df2f460 2010-11-17 spiffytech@gm:                 "grammars": {  # Notes for this instrument to use in this piece
db1df2f460 2010-11-17 spiffytech@gm:                     "u": ["I V V V I I IV u u", "I IV u u", "I VII IV u u"  , "e"],
db1df2f460 2010-11-17 spiffytech@gm:                     "e": [""],
db1df2f460 2010-11-17 spiffytech@gm:                 },
db1df2f460 2010-11-17 spiffytech@gm:                 "score": "u u u u u",
db1df2f460 2010-11-17 spiffytech@gm:             },
7c7ce6adb8 2010-11-17 spiffytech@gm:             "rhythm": {
b8d35587a4 2010-11-17 spiffytech@gm:                 "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6",
db1df2f460 2010-11-17 spiffytech@gm:                 "grammars": {
5a35ffdd27 2010-11-17 spiffytech@gm:                     "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"],
5a35ffdd27 2010-11-17 spiffytech@gm: #                    "u": ['"i" "I" "ii" "II" "v" "V" u', "e"],
db1df2f460 2010-11-17 spiffytech@gm:                     "e": [""]
db1df2f460 2010-11-17 spiffytech@gm:                 },
db1df2f460 2010-11-17 spiffytech@gm:                 "score": "u u u",
db1df2f460 2010-11-17 spiffytech@gm:             },
db1df2f460 2010-11-17 spiffytech@gm:         },
db1df2f460 2010-11-17 spiffytech@gm:         "b": {
db1df2f460 2010-11-17 spiffytech@gm:             "melody": {  # Instrument 'melody'
b8d35587a4 2010-11-17 spiffytech@gm:                 "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6",
db1df2f460 2010-11-17 spiffytech@gm:                 "grammars": {  # Notes for this instrument to use in this piece
db1df2f460 2010-11-17 spiffytech@gm:                     "u": ["I V I I/2 IV/2 u u", "I2 IV u u", "I IV IV VI V u u" , "e"],
db1df2f460 2010-11-17 spiffytech@gm:                     "e": [""],
7c7ce6adb8 2010-11-17 spiffytech@gm:                 },
db1df2f460 2010-11-17 spiffytech@gm:                 "score": "u u u",
db1df2f460 2010-11-17 spiffytech@gm:             },
db1df2f460 2010-11-17 spiffytech@gm:             "rhythm": {
b8d35587a4 2010-11-17 spiffytech@gm:                 "score_line": "i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6",
7c7ce6adb8 2010-11-17 spiffytech@gm:                 "grammars": {
db1df2f460 2010-11-17 spiffytech@gm:                     "u": ['"I" "IV"/2 "V"2 "IV" "I" u u', '"I" "VII" "IV" u u', '"I" "V" "IV" u u', "e"],
7c7ce6adb8 2010-11-17 spiffytech@gm:                     "e": [""]
7c7ce6adb8 2010-11-17 spiffytech@gm:                 },
7c7ce6adb8 2010-11-17 spiffytech@gm:                 "score": "u u u",
7c7ce6adb8 2010-11-17 spiffytech@gm:             },
7c7ce6adb8 2010-11-17 spiffytech@gm:         },
5aa14570f1 2010-11-13 spiffytech@gm:     }
7c7ce6adb8 2010-11-17 spiffytech@gm: 
db1df2f460 2010-11-17 spiffytech@gm:     max_t = 0  # max time encountered so far. Used for movement timing
db1df2f460 2010-11-17 spiffytech@gm:     progression = "a b"
db1df2f460 2010-11-17 spiffytech@gm:     for comp_name in progression.split():
db1df2f460 2010-11-17 spiffytech@gm:         instr_start_time = max_t
db1df2f460 2010-11-17 spiffytech@gm:         for instr_name, instr in composition[comp_name].iteritems():
7c7ce6adb8 2010-11-17 spiffytech@gm:             generated_score = generate_score(instr["score"], instr["grammars"])  # Fill in the scores by generating them based on the grammars
7c7ce6adb8 2010-11-17 spiffytech@gm:             score = parse.parse(generated_score)  # Return Node/Chord objects
5aa14570f1 2010-11-13 spiffytech@gm: 
7c7ce6adb8 2010-11-17 spiffytech@gm:             # Generate timestamps for the notes
db1df2f460 2010-11-17 spiffytech@gm:             t = instr_start_time
7c7ce6adb8 2010-11-17 spiffytech@gm:             for note in range(len(score)):
7c7ce6adb8 2010-11-17 spiffytech@gm:                 score[note].time = t
5a35ffdd27 2010-11-17 spiffytech@gm:                 score[note].duration *= tempo
7c7ce6adb8 2010-11-17 spiffytech@gm:                 t += score[note].duration
db1df2f460 2010-11-17 spiffytech@gm:                 max_t = t if t > max_t else max_t
7c7ce6adb8 2010-11-17 spiffytech@gm:             composition[comp_name][instr_name]["score"] = score
6a17d4d36a 2010-11-12 spiffytech@gm: 
db1df2f460 2010-11-17 spiffytech@gm:     # Must be done after all note times keyed in, else you can't coordinate melodies with the rhythm chords
db1df2f460 2010-11-17 spiffytech@gm:     for comp_name in progression.split():
db1df2f460 2010-11-17 spiffytech@gm:         for instr_name, instr in composition[comp_name].iteritems():
7c7ce6adb8 2010-11-17 spiffytech@gm:             composition[comp_name][instr_name]["score"] = transliterate_score(composition[comp_name][instr_name]["score"], key)
7c7ce6adb8 2010-11-17 spiffytech@gm: #            print "\nMovement %s instrument %s" % (comp_name, instr_name)
7c7ce6adb8 2010-11-17 spiffytech@gm: #            print composition[comp_name][instr_name]["score"]
7c7ce6adb8 2010-11-17 spiffytech@gm:             print "f1  0   256 10  1 0 3   ; sine wave function table"
b8d35587a4 2010-11-17 spiffytech@gm:             final_score = generate_csound_score(composition[comp_name][instr_name]["score"], composition[comp_name][instr_name]["score_line"])
7c7ce6adb8 2010-11-17 spiffytech@gm:             for line in final_score:
7c7ce6adb8 2010-11-17 spiffytech@gm:                 print line
7c7ce6adb8 2010-11-17 spiffytech@gm: 
338933c1a8 2010-11-12 spiffytech@gm: 
6a17d4d36a 2010-11-12 spiffytech@gm: def make_scale(key):
6a17d4d36a 2010-11-12 spiffytech@gm:     notes = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"]
6a17d4d36a 2010-11-12 spiffytech@gm:     scale = [key]
6a17d4d36a 2010-11-12 spiffytech@gm:     pos = notes.index(key)
6a17d4d36a 2010-11-12 spiffytech@gm:     progression = [2,2,1,2,2,2,1]
6a17d4d36a 2010-11-12 spiffytech@gm:     for p in progression:
6a17d4d36a 2010-11-12 spiffytech@gm:         pos = (pos + p) % 12
6a17d4d36a 2010-11-12 spiffytech@gm:         scale.append(notes[pos])
6a17d4d36a 2010-11-12 spiffytech@gm:     return scale
6a17d4d36a 2010-11-12 spiffytech@gm: 
338933c1a8 2010-11-12 spiffytech@gm: 
5aa14570f1 2010-11-13 spiffytech@gm: def generate_score(score, grammars):
6a17d4d36a 2010-11-12 spiffytech@gm:     while 1:
6a17d4d36a 2010-11-12 spiffytech@gm:         found_substitution = False
6a17d4d36a 2010-11-12 spiffytech@gm:         for key,value in grammars.iteritems():
6a17d4d36a 2010-11-12 spiffytech@gm:             if score.find(key) != -1:
6a17d4d36a 2010-11-12 spiffytech@gm:                 found_substitution = True
6a17d4d36a 2010-11-12 spiffytech@gm:                 while score.find(key) != -1:
6a17d4d36a 2010-11-12 spiffytech@gm:                     score = score.replace(key, random.choice(grammars[key]), 1)
aa88358397 2010-11-17 spiffytech@gm:                     if len(score.split()) > 200:
9bd31df856 2010-11-16 spiffytech@gm:                         score = score.replace("u", "")
9bd31df856 2010-11-16 spiffytech@gm:                         score = score.replace("e", "")
9bd31df856 2010-11-16 spiffytech@gm:                         return score
6a17d4d36a 2010-11-12 spiffytech@gm:         if found_substitution is False:
6a17d4d36a 2010-11-12 spiffytech@gm:             break
6a17d4d36a 2010-11-12 spiffytech@gm:     return score
6bfc2449ff 2010-11-04 spiffytech@gm: 
7c7ce6adb8 2010-11-17 spiffytech@gm: def transliterate_score(score, key):
6a17d4d36a 2010-11-12 spiffytech@gm:     scale = make_scale(key)
6a17d4d36a 2010-11-12 spiffytech@gm:     scale_conversion = {
6a17d4d36a 2010-11-12 spiffytech@gm:         "I": 1,
6a17d4d36a 2010-11-12 spiffytech@gm:         "II": 2,
6a17d4d36a 2010-11-12 spiffytech@gm:         "III": 3,
6a17d4d36a 2010-11-12 spiffytech@gm:         "IV": 4,
6a17d4d36a 2010-11-12 spiffytech@gm:         "V": 5,
6a17d4d36a 2010-11-12 spiffytech@gm:         "VI": 6,
6a17d4d36a 2010-11-12 spiffytech@gm:         "VII": 7,
6a17d4d36a 2010-11-12 spiffytech@gm:         "VIII": 8,
6a17d4d36a 2010-11-12 spiffytech@gm:     }
6a17d4d36a 2010-11-12 spiffytech@gm:     keyed_score = []
7c7ce6adb8 2010-11-17 spiffytech@gm:     for i in range(len(score)):
7c7ce6adb8 2010-11-17 spiffytech@gm:         if isinstance(score[i], parse.Note):
9bd31df856 2010-11-16 spiffytech@gm:             score[i].value = scale[scale_conversion[score[i].value]-1]
aa88358397 2010-11-17 spiffytech@gm:         elif isinstance(score[i], parse.Chord):
5aa14570f1 2010-11-13 spiffytech@gm:             chord = []
9bd31df856 2010-11-16 spiffytech@gm:             root_note_index = scale.index(key) + scale_conversion[score[i].value]
5aa14570f1 2010-11-13 spiffytech@gm:             chord.append(scale[root_note_index])
f02f66468f 2010-11-17 spiffytech@gm:             if score[i].chord_type == "m":  # Minor chords, flat the 3rd
f02f66468f 2010-11-17 spiffytech@gm:                 chord.append(scale[(root_note_index+2) % 8])
f02f66468f 2010-11-17 spiffytech@gm:             else:
f02f66468f 2010-11-17 spiffytech@gm:                 chord.append(scale[(root_note_index+3) % 8])
5aa14570f1 2010-11-13 spiffytech@gm:             chord.append(scale[(root_note_index+5) % 8])
9bd31df856 2010-11-16 spiffytech@gm:             score[i].chord = chord
aa88358397 2010-11-17 spiffytech@gm:         elif isinstance(score[i], parse.Rest):
aa88358397 2010-11-17 spiffytech@gm:             pass
9bd31df856 2010-11-16 spiffytech@gm:     return score
6a17d4d36a 2010-11-12 spiffytech@gm: 
6bfc2449ff 2010-11-04 spiffytech@gm: 
b8d35587a4 2010-11-17 spiffytech@gm: def generate_csound_score(score, score_line):
6a17d4d36a 2010-11-12 spiffytech@gm:     csound_note_values = {
6a17d4d36a 2010-11-12 spiffytech@gm:         "C": "00",
6a17d4d36a 2010-11-12 spiffytech@gm:         "C#": "01",
6a17d4d36a 2010-11-12 spiffytech@gm:         "D": "02",
6a17d4d36a 2010-11-12 spiffytech@gm:         "D#": "03",
6a17d4d36a 2010-11-12 spiffytech@gm:         "E": "04",
6a17d4d36a 2010-11-12 spiffytech@gm:         "F": "05",
6a17d4d36a 2010-11-12 spiffytech@gm:         "F#": "06",
6a17d4d36a 2010-11-12 spiffytech@gm:         "G": "07",
3cd7a5dcd0 2010-11-12 spiffytech@gm:         "G#": "08",
6a17d4d36a 2010-11-12 spiffytech@gm:         "A": "09",
6a17d4d36a 2010-11-12 spiffytech@gm:         "A#": "10",
6a17d4d36a 2010-11-12 spiffytech@gm:         "B": "11",
6a17d4d36a 2010-11-12 spiffytech@gm:     }
6a17d4d36a 2010-11-12 spiffytech@gm:     csound_score = []
6a17d4d36a 2010-11-12 spiffytech@gm:     for token in score:
9bd31df856 2010-11-16 spiffytech@gm:         if isinstance(token, parse.Chord):  # Chords
9bd31df856 2010-11-16 spiffytech@gm:             for note in token.chord:
5aa14570f1 2010-11-13 spiffytech@gm:                 note = csound_note_values[note]
b8d35587a4 2010-11-17 spiffytech@gm: #                csound_score.append("i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6" % {"time": token.time, "octave": random.choice([7,8]), "note": note, "duration": token.duration})
b8d35587a4 2010-11-17 spiffytech@gm:                 csound_score.append(score_line % {"time": token.time, "octave": random.choice([7,8]), "note": note, "duration": token.duration})
aa88358397 2010-11-17 spiffytech@gm:         elif isinstance(token, parse.Note):  # Individual notes
9bd31df856 2010-11-16 spiffytech@gm:             note = csound_note_values[token.value]
b8d35587a4 2010-11-17 spiffytech@gm:             csound_score.append(score_line % {"time": token.time, "octave": random.choice([8,9]), "note": note, "duration": token.duration})
b8d35587a4 2010-11-17 spiffytech@gm: #            csound_score.append("i2 %(time)f %(duration)f 7000 %(octave)d.%(note)s %(octave)d.%(note)s 0 6" % {"time": token.time, "octave": random.choice([8,9]), "note": note, "duration": token.duration})
6a17d4d36a 2010-11-12 spiffytech@gm:     return csound_score
338933c1a8 2010-11-12 spiffytech@gm: 
6bfc2449ff 2010-11-04 spiffytech@gm: 
6a17d4d36a 2010-11-12 spiffytech@gm: if __name__ == "__main__": main()