|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +# Copyright (c) 2019 Ludovic Drolez |
| 4 | + |
| 5 | +# Permission is hereby granted, free of charge, to any person obtaining a copy |
| 6 | +# of this software and associated documentation files (the "Software"), to deal |
| 7 | +# in the Software without restriction, including without limitation the rights |
| 8 | +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 9 | +# copies of the Software, and to permit persons to whom the Software is |
| 10 | +# furnished to do so, subject to the following conditions: |
| 11 | + |
| 12 | +# The above copyright notice and this permission notice shall be included in all |
| 13 | +# copies or substantial portions of the Software. |
| 14 | + |
| 15 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 18 | +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 | +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 21 | +# SOFTWARE. |
| 22 | + |
| 23 | +import os |
| 24 | +import mingus.core.scales as scales |
| 25 | + |
| 26 | +from src.chords2midi import c2m |
| 27 | + |
| 28 | +# output dir |
| 29 | +out = "output" |
| 30 | + |
| 31 | +# Basic keys |
| 32 | +keys = [ |
| 33 | + ('C', 'A'), # nothing |
| 34 | + #('C#', 'a#') # 7 # |
| 35 | + ('Db', 'Bb'), # 5 b |
| 36 | + ('D', 'B'), # 2 # |
| 37 | + ('Eb', 'C'), # 3 b |
| 38 | + ('E', 'C#'), # 4 # |
| 39 | + ('F', 'D'), # 1 b |
| 40 | + #('F#', 'd#'), # 6 # |
| 41 | + ('Gb', 'Eb'), # 6 b |
| 42 | + ('G', 'E'), # 1 # |
| 43 | + ('Ab', 'F'), # 4 b |
| 44 | + ('A', 'F#'), # 3 # |
| 45 | + ('Bb', 'G'), # 2 b |
| 46 | + ('B', 'G#'), # 5 # |
| 47 | + # ('Cb', 'ab'), # 7 b |
| 48 | +] |
| 49 | + |
| 50 | +deg_maj = ['I', 'ii', 'iii', 'IV', 'V', 'vi', 'vii'] |
| 51 | +deg_min = ['i', 'ii', 'III', 'iv', 'v', 'VI', 'VII'] |
| 52 | + |
| 53 | +# |
| 54 | +# Generate a single chord |
| 55 | +# |
| 56 | +def gen(dir, key, chords, prefix): |
| 57 | + if not os.path.exists(dir): |
| 58 | + os.makedirs(dir) |
| 59 | + c2m_obj = c2m.Chords2Midi() |
| 60 | + c2m_obj.handle([f"{chords}", "-t", "4", "-p", "long", "-d", "4", |
| 61 | + "-B", "--key", f"{key}", "-N", f"{prefix} - {chords}", "--output", |
| 62 | + f"{dir}/{prefix} - {chords}.mid"]) |
| 63 | + |
| 64 | +# |
| 65 | +# Generate a chord progression |
| 66 | +# |
| 67 | +def genprog(dir, key, chords, prefix): |
| 68 | + if not os.path.exists(dir): |
| 69 | + os.makedirs(dir) |
| 70 | + c2m_obj = c2m.Chords2Midi() |
| 71 | + args = chords.split(" ") |
| 72 | + args.extend(["-t", "4", "-p", "long", "-d", "4", "-B", |
| 73 | + "--key", f"{key}", "-N", f"{prefix} - {chords}", "--output", |
| 74 | + f"{dir}/{prefix} - {chords}.mid"]) |
| 75 | + c2m_obj.handle(args) |
| 76 | + |
| 77 | + |
| 78 | +num = 1 |
| 79 | +# Iterate for each key |
| 80 | +for key in keys: |
| 81 | + |
| 82 | + root_maj = key[0] |
| 83 | + root_min = key[1] |
| 84 | + scale_maj = scales.Major(root_maj).ascending() |
| 85 | + scale_min = scales.NaturalMinor(root_min).ascending() |
| 86 | + base = f'{out}/{num:02} - {root_maj} Major - {root_min} minor' |
| 87 | + |
| 88 | + # Major triads |
| 89 | + i = 0 |
| 90 | + for n in ['', 'm', 'm', '', '', 'm', 'dim']: |
| 91 | + chord = scale_maj[i] + n |
| 92 | + gen(f'{base}/1 Triad/Major', root_maj, chord, deg_maj[i]) |
| 93 | + i = i + 1 |
| 94 | + |
| 95 | + # Minor triads |
| 96 | + i = 0 |
| 97 | + for n in ['m', 'dim', '', 'm', 'm', '', '']: |
| 98 | + chord = scale_min[i] + n |
| 99 | + gen(f'{base}/1 Triad/Minor', root_min, chord, deg_min[i]) |
| 100 | + i = i + 1 |
| 101 | + |
| 102 | + # Major 7th |
| 103 | + i = 0 |
| 104 | + # bug: pychord cannot create a m7-5add9 |
| 105 | + for n in [['M7', 'M9'], ['m7', 'm9'], ['m7', 'm9'], |
| 106 | + ['M7', 'M9'], ['7', '9'], ['m7', 'm9'], |
| 107 | + ['m7-5']]: |
| 108 | + for c in n: |
| 109 | + chord = scale_maj[i] + c |
| 110 | + gen(f'{base}/2 7th and 9th/Major', root_maj, chord, deg_maj[i]) |
| 111 | + i = i + 1 |
| 112 | + |
| 113 | + # Minor 7th |
| 114 | + i = 0 |
| 115 | + for n in [['m7', 'm9'], ['m7-5'], ['M7', 'M9'], |
| 116 | + ['m7', 'm9'], ['m7', 'm9'], |
| 117 | + ['M7', 'M9'], ['7', '9']]: |
| 118 | + for c in n: |
| 119 | + chord = scale_min[i] + c |
| 120 | + gen(f'{base}/2 7th and 9th/Minor', root_min, chord, deg_min[i]) |
| 121 | + i = i + 1 |
| 122 | + |
| 123 | + # All Other chords |
| 124 | + i = 0 |
| 125 | + for c in [1, 2, 3, 4, 5, 6, 7]: |
| 126 | + for n in [ |
| 127 | + 'sus2', # 0, 2, 7 |
| 128 | + 'sus4', # 0, 5, 7 |
| 129 | + '6', # 0, 4, 7, 9 |
| 130 | + '7', # 0, 4, 7, 10 |
| 131 | + '7-5', # 0, 4, 6, 10 |
| 132 | + '7+5', # 0, 4, 8, 10 |
| 133 | + '7sus4', # 0, 5, 7, 10 |
| 134 | + 'm6', # 0, 3, 7, 9 |
| 135 | + 'm7', # 0, 3, 7, 10 |
| 136 | + 'm7-5', # 0, 3, 6, 10 |
| 137 | + 'dim6', # 0, 3, 6, 9 |
| 138 | + 'maj7', # 0, 4, 7, 11 |
| 139 | + 'M7+5', # 0, 4, 8, 11 |
| 140 | + 'mM7', # 0, 3, 7, 11 |
| 141 | + 'add9', # 0, 4, 7, 14 |
| 142 | + 'madd9', # 0, 3, 7, 14 |
| 143 | + '2', # 0, 4, 7, 14 |
| 144 | + 'add11', # 0, 4, 7, 17 |
| 145 | + 'm69', # 0, 3, 7, 9, 14 |
| 146 | + '69', # 0, 4, 7, 9, 14 |
| 147 | + '9', # 0, 4, 7, 10, 14 |
| 148 | + 'm9', # 0, 3, 7, 10, 14 |
| 149 | + 'maj9', # 0, 4, 7, 11, 14 |
| 150 | + '9sus4', # 0, 5, 7, 10, 14 |
| 151 | + '7-9', # 0, 4, 7, 10, 13 |
| 152 | + '7+11', # 0, 4, 7, 10, 18 |
| 153 | + ]: |
| 154 | + chord = scale_maj[i] + n |
| 155 | + gen(f'{base}/3 All chords/', root_maj, chord, deg_maj[i] |
| 156 | + + '-' + deg_min[(i+5) % 7]) |
| 157 | + i = i + 1 |
| 158 | + |
| 159 | + # Major progressions |
| 160 | + for n in [ |
| 161 | + "I iii vi IV", "I iii IV vi", "I bii I iii", "I bii biii bii", |
| 162 | + "I biii bvi bvii", "I bvi I bii", "I bvii bvi bii", "I IV ii V", |
| 163 | + "I IV vi V", "I IV V V", "I IV biii bvi", "I IV bvii IV", |
| 164 | + "I V vi ii", "I V vi IV", |
| 165 | + "I V vi iii IV", "I V vi V", "I V bvii IV", "I vi IV V", |
| 166 | + "I V vi iii IV I IV V", |
| 167 | + "ii bii I bvii", "ii IV V V", "ii V I I", "ii V I IV", |
| 168 | + "ii bVII7 I", "ii7 V9 I7 I7", "iim7 V7 iiim7 vi7 iim7 V7", |
| 169 | + "biii ii bii I", "iii vi IV I", |
| 170 | + "IV I ii vi", "IV I iii IV", "IV I V vi", |
| 171 | + "V I vi V", "V IV vi I", "V vi IV I", |
| 172 | + "vi IV I V", "vi bvi bvii I", "vi V IV V", |
| 173 | + ]: |
| 174 | + genprog(f'{base}/4 Progression/Major', root_maj, n, root_maj) |
| 175 | + |
| 176 | + # Minor progressions |
| 177 | + for n in [ |
| 178 | + "i ii v i", "i iv v iv", "i iv VI v", "i iv VII i", |
| 179 | + "i iv VII v i i ii V", "i v iv VII", |
| 180 | + "i VI III bii", "i VI iv ii", "i VI III VII", "i VI VII VII", |
| 181 | + "i bVII VI bii", "i VII VI VII", "i VII i v", |
| 182 | + "i VII i v III VII i v i", "i bVII bVI bVII", |
| 183 | + "ii v i i", "ii v i iv", "ii VI i iv", "ii7 v9 i7", |
| 184 | + "iv i v VI", "iv VI VII i", "iv III VII i", "iv v VI VII", |
| 185 | + "v i iv VII", "v iv i i", "v VI v i", "v VI III i", |
| 186 | + "VI i v v", "VI VI i VII", "VI VII i III", "VI VII v III", |
| 187 | + "VII iv VII i", "VII iv v i", |
| 188 | + ]: |
| 189 | + genprog(f'{base}/4 Progression/Minor', root_min.lower(), n, root_min) |
| 190 | + |
| 191 | + # next key |
| 192 | + num = num + 1 |
0 commit comments