spiffyscore

Changes On Branch 7c7ce6adb86ec332
Login

Changes On Branch 7c7ce6adb86ec332

Changes In Branch tld Through [7c7ce6adb8] Excluding Merge-Ins

This is equivalent to a diff from 3d4ddcbab5 to 7c7ce6adb8

2010-11-17
05:32
Now supports minor chords check-in: f02f66468f user: spiffytech@gmail.com tags: tld
00:07
Added support for top-down composition check-in: 7c7ce6adb8 user: spiffytech@gmail.com tags: tld
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

Modified cfg.py from [8e359b2146] to [f6edc4689f].

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
#!/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


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)
                    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 = {
        "I": 1,
        "II": 2,
        "III": 3,
        "IV": 4,
        "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











|
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
|
|
|
|
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
|
|
|
|
>
|
>
>
>
|
>
|
|
>
|
|
|




















|







|












<
|
>

|
<







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
#!/usr/bin/env python

import os
import random
import sys
import time
random.seed(time.time())
import parse

def main():
    key = "A"

    composition = {
        "a": {  # Movement block 'a' for reuse throughout the piece
            "melody": {  # Instrument 'melody'
                "csound_parameters": {
                    "instrument": 1,
                },
                "grammars": {  # Notes for this instrument to use in this piece
                    "u": ["I V V V I I IV u u", "I IV u u", "I VII IV u u"  , "e"],
                    "e": [""],
                },
                "score": "u u u",
            },
            "rhythm": {
                "csound_parameters": {
                    "instrument": 1,
                },
                "grammars": {
                    "u": ['"I" "IV"/2 "V"2 "IV" "I" u u', '"I" "VII" "IV" u u', '"I" "V" "IV" u u', "e"],
                    "e": [""]
                },
                "score": "u u u",
            },
        },
        "b": {
            "melody": {  # Instrument 'melody'
                "csound_parameters": {
                    "instrument": 1,
                },
                "grammars": {  # Notes for this instrument to use in this piece
                    "u": ["I V I I/2 IV/2 u u", "I4 IV u u", "I IV IV VI V u u"  , "e"],
                    "e": [""],
                },
                "score": "u u u",
            },
            "rhythm": {
                "csound_parameters": {
                    "instrument": 1,
                },
                "grammars": {
                    "u": ['"I" "IV"/2 "V"2 "IV" "I" u u', '"I" "VII" "IV" u u', '"I" "V" "IV" u u', "e"],
                    "e": [""]
                },
                "score": "u u u",
            },
        },
    }

    for comp_name, comp in composition.iteritems():
        for instr_name, instr in comp.iteritems():
            generated_score = generate_score(instr["score"], instr["grammars"])  # Fill in the scores by generating them based on the grammars
#                composition[comp_name][instr_name][grammar]["score"] = parse.parse(generate_score)  # Return Node/Chord objects
            score = parse.parse(generated_score)  # Return Node/Chord objects

            # Generate timestamps for the notes 
            t = 0
            for note in range(len(score)):
                score[note].time = t
                t += score[note].duration
            composition[comp_name][instr_name]["score"] = score

    # Must be done after all note times keyed in, else you c,an't coordinate melodies with the rhythm chords
    for comp_name, comp in composition.iteritems():
        for instr_name, instr in comp.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"] 
            print "f1  0   256 10  1 0 3   ; sine wave function table"
            final_score = generate_csound_score(composition[comp_name][instr_name]["score"])
            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)
                    if len(score.split()) > 200:
                        score = score.replace("u", "")
                        score = score.replace("e", "")
                        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]
        else:

            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

Modified todo.org from [9c9ed49773] to [9bec386f24].

1
2
3
4
5
6
7

* Features [0/5]
- [ ] Top-down composition
- [ ] Transition the melody between chords appropriately
- [ ] Set maximum song length

* Bugs [0/1]
- [ ] Doesn't handle minor chords








>
1
2
3
4
5
6
7
8
* Features [0/5]
- [ ] Top-down composition
- [ ] Transition the melody between chords appropriately
- [ ] Set maximum song length

* Bugs [0/1]
- [ ] Doesn't handle minor chords
- [ ] Duration syntax is absolute, not relative to BPM