Skip to content

Commit

Permalink
initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
ldrolez committed Oct 10, 2020
1 parent ed63dd5 commit 5730df7
Show file tree
Hide file tree
Showing 5 changed files with 720 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
DATE=$(shell date +'%Y%m%d')

dist:
rm -rf output/*
python3 gen.py
cp README.md LICENSE output
rm -f ../dist/free-midi-chords-${DATE}.zip
cd output; zip -r ../dist/free-midi-chords-${DATE}.zip *

.PHONY: dist
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Free MIDI Chords

This is a collaborative project to create a collection of all chords
and useful chord progressions in all keys, as MIDI files, usable
with your favorite DAW.

This collection is FREE and you can contribute to it using the issue tracker above.
Please use the bug tracker if you find incorrect chords!

All the files are licensed under the MIT license, and you can use in any project freely.

* More details in [my blog](https://drolez.com/blog/music/free-midi-chords-progressions.php)

## Installation

Just download and unzip one of the [release file](/ldrolez/free-midi-chords/releases).

## Contents

The chords collection is organized using 3 levels of directories:

* 1st level: All 12 Major and Minor keys
* 2nd level:
* 1/ Triads
* 2/ 7ths and 9ths chords
* 3/ All other chords
* 4/ And progressions
* 3rd level: Major and Minor scales

## Related

The script uses chords2midi from Rich Jones, and Python Mingus.

* [chords2midi](https://github.com/Miserlou/chords2midi) - Create MIDI files from numerical chord progressions.


Ludovic Drolez.

192 changes: 192 additions & 0 deletions gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#!/usr/bin/env python3

# Copyright (c) 2019 Ludovic Drolez

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os
import mingus.core.scales as scales

from src.chords2midi import c2m

# output dir
out = "output"

# Basic keys
keys = [
('C', 'A'), # nothing
#('C#', 'a#') # 7 #
('Db', 'Bb'), # 5 b
('D', 'B'), # 2 #
('Eb', 'C'), # 3 b
('E', 'C#'), # 4 #
('F', 'D'), # 1 b
#('F#', 'd#'), # 6 #
('Gb', 'Eb'), # 6 b
('G', 'E'), # 1 #
('Ab', 'F'), # 4 b
('A', 'F#'), # 3 #
('Bb', 'G'), # 2 b
('B', 'G#'), # 5 #
# ('Cb', 'ab'), # 7 b
]

deg_maj = ['I', 'ii', 'iii', 'IV', 'V', 'vi', 'vii']
deg_min = ['i', 'ii', 'III', 'iv', 'v', 'VI', 'VII']

#
# Generate a single chord
#
def gen(dir, key, chords, prefix):
if not os.path.exists(dir):
os.makedirs(dir)
c2m_obj = c2m.Chords2Midi()
c2m_obj.handle([f"{chords}", "-t", "4", "-p", "long", "-d", "4",
"-B", "--key", f"{key}", "-N", f"{prefix} - {chords}", "--output",
f"{dir}/{prefix} - {chords}.mid"])

#
# Generate a chord progression
#
def genprog(dir, key, chords, prefix):
if not os.path.exists(dir):
os.makedirs(dir)
c2m_obj = c2m.Chords2Midi()
args = chords.split(" ")
args.extend(["-t", "4", "-p", "long", "-d", "4", "-B",
"--key", f"{key}", "-N", f"{prefix} - {chords}", "--output",
f"{dir}/{prefix} - {chords}.mid"])
c2m_obj.handle(args)


num = 1
# Iterate for each key
for key in keys:

root_maj = key[0]
root_min = key[1]
scale_maj = scales.Major(root_maj).ascending()
scale_min = scales.NaturalMinor(root_min).ascending()
base = f'{out}/{num:02} - {root_maj} Major - {root_min} minor'

# Major triads
i = 0
for n in ['', 'm', 'm', '', '', 'm', 'dim']:
chord = scale_maj[i] + n
gen(f'{base}/1 Triad/Major', root_maj, chord, deg_maj[i])
i = i + 1

# Minor triads
i = 0
for n in ['m', 'dim', '', 'm', 'm', '', '']:
chord = scale_min[i] + n
gen(f'{base}/1 Triad/Minor', root_min, chord, deg_min[i])
i = i + 1

# Major 7th
i = 0
# bug: pychord cannot create a m7-5add9
for n in [['M7', 'M9'], ['m7', 'm9'], ['m7', 'm9'],
['M7', 'M9'], ['7', '9'], ['m7', 'm9'],
['m7-5']]:
for c in n:
chord = scale_maj[i] + c
gen(f'{base}/2 7th and 9th/Major', root_maj, chord, deg_maj[i])
i = i + 1

# Minor 7th
i = 0
for n in [['m7', 'm9'], ['m7-5'], ['M7', 'M9'],
['m7', 'm9'], ['m7', 'm9'],
['M7', 'M9'], ['7', '9']]:
for c in n:
chord = scale_min[i] + c
gen(f'{base}/2 7th and 9th/Minor', root_min, chord, deg_min[i])
i = i + 1

# All Other chords
i = 0
for c in [1, 2, 3, 4, 5, 6, 7]:
for n in [
'sus2', # 0, 2, 7
'sus4', # 0, 5, 7
'6', # 0, 4, 7, 9
'7', # 0, 4, 7, 10
'7-5', # 0, 4, 6, 10
'7+5', # 0, 4, 8, 10
'7sus4', # 0, 5, 7, 10
'm6', # 0, 3, 7, 9
'm7', # 0, 3, 7, 10
'm7-5', # 0, 3, 6, 10
'dim6', # 0, 3, 6, 9
'maj7', # 0, 4, 7, 11
'M7+5', # 0, 4, 8, 11
'mM7', # 0, 3, 7, 11
'add9', # 0, 4, 7, 14
'madd9', # 0, 3, 7, 14
'2', # 0, 4, 7, 14
'add11', # 0, 4, 7, 17
'm69', # 0, 3, 7, 9, 14
'69', # 0, 4, 7, 9, 14
'9', # 0, 4, 7, 10, 14
'm9', # 0, 3, 7, 10, 14
'maj9', # 0, 4, 7, 11, 14
'9sus4', # 0, 5, 7, 10, 14
'7-9', # 0, 4, 7, 10, 13
'7+11', # 0, 4, 7, 10, 18
]:
chord = scale_maj[i] + n
gen(f'{base}/3 All chords/', root_maj, chord, deg_maj[i]
+ '-' + deg_min[(i+5) % 7])
i = i + 1

# Major progressions
for n in [
"I iii vi IV", "I iii IV vi", "I bii I iii", "I bii biii bii",
"I biii bvi bvii", "I bvi I bii", "I bvii bvi bii", "I IV ii V",
"I IV vi V", "I IV V V", "I IV biii bvi", "I IV bvii IV",
"I V vi ii", "I V vi IV",
"I V vi iii IV", "I V vi V", "I V bvii IV", "I vi IV V",
"I V vi iii IV I IV V",
"ii bii I bvii", "ii IV V V", "ii V I I", "ii V I IV",
"ii bVII7 I", "ii7 V9 I7 I7", "iim7 V7 iiim7 vi7 iim7 V7",
"biii ii bii I", "iii vi IV I",
"IV I ii vi", "IV I iii IV", "IV I V vi",
"V I vi V", "V IV vi I", "V vi IV I",
"vi IV I V", "vi bvi bvii I", "vi V IV V",
]:
genprog(f'{base}/4 Progression/Major', root_maj, n, root_maj)

# Minor progressions
for n in [
"i ii v i", "i iv v iv", "i iv VI v", "i iv VII i",
"i iv VII v i i ii V", "i v iv VII",
"i VI III bii", "i VI iv ii", "i VI III VII", "i VI VII VII",
"i bVII VI bii", "i VII VI VII", "i VII i v",
"i VII i v III VII i v i", "i bVII bVI bVII",
"ii v i i", "ii v i iv", "ii VI i iv", "ii7 v9 i7",
"iv i v VI", "iv VI VII i", "iv III VII i", "iv v VI VII",
"v i iv VII", "v iv i i", "v VI v i", "v VI III i",
"VI i v v", "VI VI i VII", "VI VII i III", "VI VII v III",
"VII iv VII i", "VII iv v i",
]:
genprog(f'{base}/4 Progression/Minor', root_min.lower(), n, root_min)

# next key
num = num + 1
Empty file added src/chords2midi/__init__.py
Empty file.
Loading

0 comments on commit 5730df7

Please sign in to comment.