Skip to content

Commit 5730df7

Browse files
committed
initial version
1 parent ed63dd5 commit 5730df7

File tree

5 files changed

+720
-0
lines changed

5 files changed

+720
-0
lines changed

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
DATE=$(shell date +'%Y%m%d')
2+
3+
dist:
4+
rm -rf output/*
5+
python3 gen.py
6+
cp README.md LICENSE output
7+
rm -f ../dist/free-midi-chords-${DATE}.zip
8+
cd output; zip -r ../dist/free-midi-chords-${DATE}.zip *
9+
10+
.PHONY: dist

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Free MIDI Chords
2+
3+
This is a collaborative project to create a collection of all chords
4+
and useful chord progressions in all keys, as MIDI files, usable
5+
with your favorite DAW.
6+
7+
This collection is FREE and you can contribute to it using the issue tracker above.
8+
Please use the bug tracker if you find incorrect chords!
9+
10+
All the files are licensed under the MIT license, and you can use in any project freely.
11+
12+
* More details in [my blog](https://drolez.com/blog/music/free-midi-chords-progressions.php)
13+
14+
## Installation
15+
16+
Just download and unzip one of the [release file](/ldrolez/free-midi-chords/releases).
17+
18+
## Contents
19+
20+
The chords collection is organized using 3 levels of directories:
21+
22+
* 1st level: All 12 Major and Minor keys
23+
* 2nd level:
24+
* 1/ Triads
25+
* 2/ 7ths and 9ths chords
26+
* 3/ All other chords
27+
* 4/ And progressions
28+
* 3rd level: Major and Minor scales
29+
30+
## Related
31+
32+
The script uses chords2midi from Rich Jones, and Python Mingus.
33+
34+
* [chords2midi](https://github.com/Miserlou/chords2midi) - Create MIDI files from numerical chord progressions.
35+
36+
37+
Ludovic Drolez.
38+

gen.py

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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

src/chords2midi/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)