Hereās a quick edit. Iāve been meaning to improve my Python skills a bit, so maybe this will help
import yaml
import numpy as np
# Open the (customizable) yaml file with the various song properties to randomize. Yaml file should be kept in the same folder as this code (unless you want to change appropriate details in the code below.)
with open('Songdata.yaml') as f:
data = yaml.load(f, Loader=yaml.FullLoader)
# Ask user to provide song structure, e.g. use ABCB for "verse-chorus-bridge-chorus"
struct = 'AABA' # input("input song structure, for example 'ABAB' or 'ABCBA' -> ")
# pick unique sections from the structure. e.g. if struct = ABAB, then the unique sections are 'A' and 'B'.
sez = set(struct)
# print the structure
print("----------")
print("*** Song Structure: " + struct + " ***")
print()
# pick keys and modes at random for each section, print them
for j in sez:
print("Section " + j + " tonal center: " + np.random.choice(data["tonal_centers"]) + " with chord progression " + np.random.choice(
data["progs"]) + " and time signature " + np.random.choice(data["time_sigs"]))
print("----------")
# pick random additional characteristics for each song section (including repeated sections), print them. You can freely edit these characteristics in the yaml file.
num = 1
for j in struct:
print("*** Section " + j + " (" + str(num) + ")" + " ***")
num = num + 1
for k in data["options"]:
print(k["cat"] + " : " + str(np.random.choice(k["values"])) + ' and ' + str(np.random.choice(k["values"])))
print("----------")
and the yaml file:
tonal_centers: [A, Bb, B, C, Db, D Eb, E, F, 'F#',G,'G#']
# common chord progressions:
progs:
- I-vi-IV-V
- I-IV-V-I
- i-iv-V
- i-bVI-bVII
- i-bVI-III-V
- i-bVI-iv-bVII
#time signatures:
time_sigs:
- '3/4'
- '4/4'
- '5/4'
- '6/8'
- '7/8'
- '11/16'
# here is a list of options that you can randomize for each section. Copy the syntax as shown below if you want to add more:
# - cat: name of the category (single word is probably best). Make sure it's preceeded by two spaces and "-"
# values: here you can put a list of the possible values for the category. do it like so: ['value1', 'value2'] etc. There should be no "-" but the word "values" should be aligned with "cat" (see below) by using 4 spaces.
options:
- cat: Texture
values: ['Arpeggiated chords', 'Strummed chords', 'Tremolo picked single note lines', 'Tremolo picked double/triple stops', 'Chugga Chugga']
- cat: Voicings
values: ['Shell chords', 'Cowboy chords', 'Root-5/root-6 chords', 'Power chords']
And finally, sample output:
----------
*** Song Structure: AABA ***
Section A tonal center: F# with chord progression I-vi-IV-V and time signature 4/4
Section B tonal center: Db with chord progression i-iv-V and time signature 3/4
----------
*** Section A (1) ***
Texture : Tremolo picked double/triple stops and Chugga Chugga
Voicings : Root-5/root-6 chords and Cowboy chords
----------
*** Section A (2) ***
Texture : Tremolo picked double/triple stops and Tremolo picked single note lines
Voicings : Cowboy chords and Power chords
----------
*** Section B (3) ***
Texture : Strummed chords and Strummed chords
Voicings : Root-5/root-6 chords and Cowboy chords
----------
*** Section A (4) ***
Texture : Tremolo picked single note lines and Strummed chords
Voicings : Root-5/root-6 chords and Shell chords
----------
This is really not optimal, but I might use something like this. Some of the combinations of texture and voicing are kind of wonky: trem picking cowboy chords is pretty lol.