Giter VIP home page Giter VIP logo

harmony's Introduction

Harmony

Generate four-part harmony following idiomatic voice-leading procedures with DP!

>>> voiceProgression('B-', 'I I6 IV V43/ii ii V V7 I')

Four-part harmony

See the web interface at autoharmony.herokuapp.com. This was built with Music21.

Usage

First, install and activate dependencies managed by Pipenv.

$ pipenv install
$ pipenv shell

To generate a chorale:

$ python voicing.py

Then, create a fresh Postgres database. Tables will be created on first application run. To launch the development web server:

$ FLASK_APP=app.py FLASK_DEBUG=1 DATABASE_URL=<POSTGRES_URL> flask run

To launch the production web server:

$ DATABASE_URL=<POSTGRES_URL> WEB_CONCURRENCY=2 gunicorn app:app

License

Licensed under the BSD 3-Clause License.

harmony's People

Contributors

ekzhang avatar napulen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

harmony's Issues

Identical consecutive voicings should be penalized

It is common to find progressions where the same roman numeral repeats itself:

image

I think in these cases, a common procedure for "good" voice leading is to prefer a change of the voicing (e.g., change of position in the three upper voices), penalizing the algorithm for proposing the exact same voicing twice.

I wanted to make sure that the policy coincides with the practice in existing music.

I looked for repeated harmonies like these in 69 annotated Bach Chorales and found 192 instances.

Out of those 192 instances:

  • In 78% of them, the voicing changes
  • In 22% of them, the voicing remains the same

Here are a few of the instances I found. Red means different voicing and green means same voicing.

image

For completeness, here is the full table. Offsets are given in quarter notes from the beginning of the score (starting from 0.0). In all instances, chord1 and chord2 are contiguous and annotated by a human expert:

file chord1_offset chord1_notes chord2_offset chord2_notes same_voicing?
chor315.krn
5.0 ['B4', 'G4', 'D4', 'G2'] 8.0 ['B4', 'G4', 'D4', 'G2'] True
chor001.krn
0.0 ['G4', 'D4', 'B3', 'G2'] 1.0 ['G4', 'D4', 'B3', 'G3'] False
19.0 ['G4', 'D4', 'B3', 'G2'] 21.0 ['B4', 'G4', 'D4', 'G2'] False
21.0 ['B4', 'G4', 'D4', 'G2'] 22.0 ['B4', 'G4', 'D4', 'G2'] True
24.0 ['D5', 'G4', 'B3', 'B2'] 25.0 ['D5', 'G4', 'B3', 'B2'] True
30.0 ['G4', 'E4', 'B3', 'E3'] 31.0 ['B4', 'E4', 'G3', 'E3'] False
chor024.krn
0.0 ['D4', 'A3', 'F#3', 'D3'] 1.0 ['A4', 'D4', 'F#3', 'D3'] False
6.0 ['D5', 'F#4', 'A3', 'D3'] 7.0 ['D5', 'F#4', 'A3', 'D2'] False
7.0 ['D5', 'F#4', 'A3', 'D2'] 8.0 ['F#5', 'A4', 'A4', 'D4'] False
13.0 ['D5', 'A4', 'F#4', 'D3'] 16.0 ['D5', 'A4', 'F#4', 'D3'] True
16.0 ['D5', 'A4', 'F#4', 'D3'] 17.0 ['F#5', 'D5', 'A4', 'D4'] False
chor050.krn
7.0 ['A4', 'F4', 'C4', 'F3'] 8.0 ['A4', 'F4', 'C4', 'F3'] True
9.0 ['C5', 'F4', 'C4', 'A3'] 10.0 ['C5', 'F4', 'C4', 'A2'] False
33.0 ['C5', 'F4', 'C4', 'A3'] 34.0 ['C5', 'F4', 'C4', 'A3'] True
chor323.krn
31.0 ['A4', 'F4', 'C4', 'F2'] 33.0 ['A4', 'F4', 'C4', 'F2'] True
chor176.krn
0.0 ['F4', 'C4', 'A3', 'F2'] 1.0 ['F4', 'C4', 'A3', 'F3'] False
16.0 ['C5', 'G4', 'C4', 'E3'] 17.0 ['C5', 'E3', 'G4', 'E4'] False
19.0 ['A4', 'G4', 'D4', 'D3'] 20.0 ['A4', 'D3', 'F4', 'A3'] False
25.0 ['C5', 'E4', 'A3', 'A3'] 26.0 ['C5', 'E4', 'C4', 'A3'] False
34.0 ['F4', 'A3', 'F3', 'D3'] 36.0 ['F4', 'D4', 'A3', 'D3'] False
chor200.krn
12.0 ['G4', 'D4', 'B-3', 'G2'] 14.0 ['G4', 'D4', 'B-3', 'G3'] False
28.0 ['C5', 'A4', 'F4', 'F3'] 29.0 ['C5', 'A4', 'F4', 'F3'] True
48.0 ['D5', 'B-4', 'F4', 'B-2'] 50.0 ['D5', 'B-4', 'F4', 'B-3'] False
chor311.krn
7.0 ['A4', 'F4', 'C4', 'F3'] 8.0 ['A4', 'F4', 'C4', 'F3'] True
chor019.krn
0.0 ['G4', 'D4', 'B-3', 'G3'] 1.0 ['G4', 'D4', 'B-3', 'G3'] True
7.0 ['F#4', 'D4', 'A3', 'D3'] 8.0 ['F#4', 'D4', 'A3', 'D3'] True
16.0 ['A4', 'F4', 'C4', 'F3'] 17.0 ['A4', 'F4', 'C4', 'F3'] True
23.0 ['B-4', 'D4', 'B-3', 'G3'] 24.0 ['B-4', 'G4', 'D4', 'G2'] False
27.0 ['F#4', 'D4', 'A3', 'D3'] 28.0 ['F#4', 'D4', 'A3', 'D3'] True
33.0 ['F#4', 'D4', 'A3', 'D3'] 34.0 ['F#4', 'D4', 'A3', 'D2'] False
35.0 ['G4', 'D4', 'C4', 'G2'] 35.5 ['G4', 'D4', 'G2', 'B3'] False
chor136.krn
0.0 ['G4', 'D4', 'B3', 'G2'] 1.0 ['B4', 'G4', 'D4', 'G2'] False
chor303.krn
13.0 ['F4', 'C4', 'A3', 'F2'] 16.0 ['F4', 'C4', 'A3', 'F3'] False
chor248.krn
9.0 ['B4', 'G4', 'D4', 'G3'] 10.0 ['G3', 'G4', 'D4', 'B3'] False
chor028.krn
6.0 ['B4', 'D4', 'F#3', 'B2'] 8.0 ['B4', 'F#4', 'D4', 'B2'] False
8.0 ['B4', 'F#4', 'D4', 'B2'] 9.0 ['D5', 'F#4', 'B3', 'B3'] False
22.0 ['B4', 'F#4', 'D4', 'B2'] 24.0 ['B4', 'F#4', 'D4', 'B3'] False
chor101.krn
13.0 ['B-4', 'F4', 'D4', 'B-2'] 16.0 ['B-4', 'F4', 'D4', 'B-2'] True
16.0 ['B-4', 'F4', 'D4', 'B-2'] 17.0 ['D5', 'B-4', 'F4', 'B-3'] False
chor255.krn
1.0 ['F#4', 'D4', 'A3', 'D3'] 2.0 ['D4', 'F#4', 'A3', 'D3'] False
3.0 ['A4', 'D4', 'A3', 'F#3'] 4.0 ['A4', 'A4', 'D4', 'F#3'] False
5.0 ['B4', 'G4', 'D4', 'G3'] 8.0 ['B4', 'D4', 'G3', 'G2'] False
9.0 ['E4', 'C#4', 'G3', 'A2'] 10.0 ['G3', 'E4', 'C#4', 'A2'] False
13.0 ['F#4', 'D4', 'A3', 'D3'] 14.0 ['D4', 'A3', 'F#3', 'D3'] False
31.0 ['A4', 'E4', 'C#4', 'A2'] 32.0 ['A4', 'E4', 'C#4', 'A2'] True
33.0 ['A4', 'F#4', 'D4', 'D3'] 34.0 ['A4', 'F#4', 'D4', 'D3'] True
41.0 ['B4', 'E4', 'G#3', 'E3'] 42.0 ['B4', 'E4', 'G#3', 'E3'] True
59.0 ['E4', 'D4', 'A3', 'A3'] 60.0 ['E4', 'C#4', 'A3', 'A2'] False
chor110.krn
7.0 ['C4', 'G3', 'E-3', 'C3'] 8.0 ['G4', 'E-4', 'C4', 'C4'] False
chor153.krn
4.0 ['A4', 'D4', 'E3', 'A2'] 5.0 ['A4', 'C#4', 'E3', 'A2'] False
6.0 ['F#4', 'D4', 'D3', 'D2'] 7.0 ['F#4', 'D4', 'D3', 'D2'] True
7.0 ['F#4', 'D4', 'D3', 'D2'] 8.0 ['A4', 'D4', 'F#3', 'D3'] False
8.0 ['A4', 'D4', 'F#3', 'D3'] 9.0 ['A4', 'D4', 'F#3', 'D3'] True
16.0 ['E4', 'C#4', 'A3', 'A2'] 17.0 ['E4', 'C#4', 'A3', 'A2'] True
22.0 ['A4', 'C#4', 'A3', 'A2'] 23.0 ['A2', 'A4', 'C#4', 'A3'] False
30.0 ['B4', 'D4', 'B3', 'B2'] 31.0 ['B3', 'B2', 'B4', 'D4'] False
32.0 ['F#4', 'D4', 'A3', 'D3'] 33.0 ['F#4', 'D4', 'A3', 'D3'] True
chor336.krn
chor224.krn
0.0 ['F4', 'C4', 'A3', 'F3'] 1.0 ['A4', 'F4', 'C4', 'F3'] False
7.0 ['A4', 'C4', 'F3', 'F3'] 8.0 ['F4', 'C4', 'A3', 'F3'] False
8.0 ['F4', 'C4', 'A3', 'F3'] 9.0 ['C5', 'F4', 'A3', 'F3'] False
chor164.krn
chor191.krn
0.0 ['E4', 'C4', 'A3', 'A2'] 1.0 ['A4', 'E4', 'C4', 'A3'] False
13.0 ['E4', 'C4', 'A3', 'A2'] 16.0 ['E5', 'A4', 'C4', 'A3'] False
31.0 ['B4', 'D4', 'G3', 'G2'] 32.0 ['B4', 'G4', 'D4', 'G3'] False
chor040.krn
19.0 ['D5', 'G4', 'B3', 'G3'] 20.0 ['D5', 'G4', 'B3', 'G3'] True
chor361.krn
16.0 ['A4', 'F#4', 'D4', 'D3'] 17.0 ['A4', 'A4', 'F#4', 'D4'] False
chor213.krn
10.0 ['F4', 'C4', 'A3', 'F2'] 12.0 ['A4', 'F4', 'C4', 'F3'] False
chor282.krn
14.0 ['C5', 'G4', 'E4', 'C3'] 16.0 ['E5', 'G4', 'C4', 'C4'] False
32.0 ['E5', 'G4', 'C4', 'C4'] 33.0 ['G5', 'C5', 'E4', 'C3'] False
chor345.krn
7.0 ['E4', 'B3', 'G#3', 'E3'] 8.0 ['B4', 'E4', 'G#3', 'E3'] False
13.0 ['A4', 'E4', 'C4', 'A2'] 16.0 ['C5', 'A4', 'E4', 'A3'] False
22.0 ['C5', 'E4', 'G3', 'C3'] 23.0 ['C5', 'E4', 'G3', 'C3'] True
23.0 ['C5', 'E4', 'G3', 'C3'] 24.0 ['G4', 'E4', 'C4', 'C3'] False
33.0 ['B4', 'D4', 'G3', 'G3'] 34.0 ['D5', 'G4', 'B3', 'G3'] False
chor067.krn
14.0 ['G4', 'B3', 'D3', 'G2'] 16.0 ['B4', 'G4', 'D4', 'G2'] False
24.0 ['D5', 'D4', 'G3', 'B2'] 25.0 ['D5', 'G4', 'B3', 'G2'] False
32.0 ['B4', 'G4', 'D4', 'G3'] 33.0 ['D5', 'G4', 'B3', 'G2'] False
40.0 ['G4', 'E4', 'E3', 'E2'] 42.0 ['B4', 'E4', 'G3', 'E3'] False
chor366.krn
7.0 ['C#5', 'E4', 'A3', 'A2'] 8.0 ['C#5', 'A4', 'E4', 'A3'] False
9.0 ['E5', 'A4', 'E4', 'C#4'] 10.0 ['E5', 'A4', 'E4', 'C#3'] False
15.0 ['G#4', 'E4', 'B3', 'E3'] 16.0 ['E4', 'B3', 'G#3', 'E3'] False
27.0 ['C#5', 'E4', 'A3', 'A3'] 28.0 ['E5', 'C#4', 'A3', 'A3'] False
43.0 ['C#5', 'A3', 'E3', 'C#3'] 44.0 ['E3', 'E5', 'A4', 'C#3'] False
chor268.krn
7.0 ['E5', 'G4', 'C4', 'C3'] 8.0 ['E5', 'G4', 'C4', 'C3'] True
8.0 ['E5', 'G4', 'C4', 'C3'] 9.0 ['E5', 'G4', 'E4', 'C4'] False
15.0 ['C5', 'E4', 'G3', 'C3'] 16.0 ['C5', 'E4', 'G3', 'C3'] True
23.0 ['A4', 'E4', 'C4', 'A2'] 24.0 ['A4', 'E4', 'C4', 'A3'] False
29.0 ['G4', 'D4', 'B3', 'G2'] 30.0 ['G4', 'D4', 'B3', 'G3'] False
39.0 ['F5', 'F4', 'D4', 'D3'] 40.0 ['F5', 'A4', 'F4', 'D4'] False
57.0 ['G4', 'D4', 'B3', 'G2'] 58.0 ['G4', 'D4', 'B3', 'G2'] True
chor354.krn
9.0 ['B4', 'G4', 'D4', 'G3'] 10.0 ['G3', 'G4', 'D4', 'B3'] False
chor276.krn
3.0 ['D5', 'G4', 'B3', 'G3'] 4.0 ['D5', 'G4', 'G3', 'B3'] False
13.0 ['D5', 'D4', 'F#4', 'D3'] 16.0 ['D5', 'F#4', 'D4', 'D3'] False
chor339.krn
23.0 ['E5', 'C5', 'C4', 'E3'] 24.0 ['E5', 'C5', 'E4', 'C3'] False
27.0 ['C5', 'G4', 'E4', 'C3'] 28.0 ['E5', 'G4', 'C4', 'C3'] False
chor299.krn
4.0 ['D5', 'A-4', 'F4', 'B-3'] 5.0 ['D5', 'A-4', 'F4', 'B-2'] False
10.0 ['E-5', 'G4', 'D4', 'C3'] 11.0 ['G4', 'E-5', 'C4', 'E-3'] False
14.0 ['C5', 'F4', 'B-3', 'F3'] 15.0 ['C5', 'F4', 'A3', 'F2'] False
34.0 ['E-4', 'B-3', 'G3', 'E-3'] 36.0 ['B-4', 'G4', 'E-4', 'E-4'] False
41.0 ['D5', 'G4', 'D4', 'B2'] 41.5 ['G4', 'E-5', 'B3', 'G2'] False
chor048.krn
2.0 ['C5', 'E4', 'A3', 'A3'] 3.0 ['C5', 'E4', 'A3', 'A2'] False
3.0 ['C5', 'E4', 'A3', 'A2'] 4.0 ['C5', 'E4', 'A3', 'A3'] False
6.0 ['E5', 'G4', 'C4', 'C4'] 7.0 ['E5', 'G4', 'C4', 'C3'] False
7.0 ['E5', 'G4', 'C4', 'C3'] 8.0 ['E5', 'G4', 'C4', 'C4'] False
14.0 ['A4', 'E4', 'C#4', 'A2'] 16.0 ['E5', 'A4', 'C#4', 'A3'] False
22.0 ['E5', 'G4', 'D4', 'D3'] 23.0 ['D5', 'F#4', 'A3', 'D3'] False
30.0 ['C5', 'F4', 'C4', 'C3'] 31.0 ['C5', 'E4', 'G3', 'C3'] False
38.0 ['A4', 'D4', 'A3', 'A3'] 39.0 ['A4', 'C#4', 'E3', 'A2'] False
chor306.krn
4.0 ['D4', 'E-4', 'G3', 'C3'] 5.0 ['G4', 'E-4', 'C4', 'C3'] False
7.0 ['B-4', 'D4', 'G3', 'G2'] 8.0 ['B-4', 'G4', 'D4', 'G3'] False
12.0 ['E-4', 'C4', 'G3', 'C3'] 13.0 ['G4', 'E-4', 'C4', 'C3'] False
23.0 ['E-4', 'B-3', 'G3', 'E-2'] 24.0 ['E-5', 'B-4', 'G3', 'E-2'] False
40.0 ['G4', 'E-4', 'B-3', 'E-3'] 41.0 ['B-4', 'G4', 'E-4', 'E-3'] False
55.0 ['F4', 'E-4', 'B-3', 'B-2'] 56.0 ['B-4', 'F4', 'D4', 'B-3'] False
chor281.krn
0.0 ['G4', 'D4', 'B-3', 'G2'] 1.0 ['G4', 'D4', 'B-3', 'G3'] False
31.0 ['B-4', 'F4', 'D4', 'B-2'] 32.0 ['D5', 'B-4', 'F4', 'B-3'] False
chor273.krn
15.0 ['D4', 'A3', 'F#3', 'D3'] 16.0 ['D4', 'D4', 'F#3', 'D3'] False
chor305.krn
30.0 ['F#4', 'D4', 'A3', 'D3'] 32.0 ['F#4', 'D4', 'A3', 'D3'] True
34.0 ['E4', 'C#4', 'A3', 'A3'] 35.0 ['E4', 'C#4', 'A3', 'A3'] True
chor158.krn
15.0 ['G4', 'D4', 'B3', 'G2'] 16.0 ['G4', 'D4', 'B3', 'G3'] False
57.0 ['E4', 'C4', 'G3', 'C3'] 58.0 ['C3', 'C4', 'G3', 'E3'] False
chor054.krn
chor098.krn
11.0 ['C#5', 'F#4', 'B3', 'F#3'] 12.0 ['C#5', 'F#4', 'A#3', 'F#2'] False
13.0 ['B4', 'D4', 'B3', 'B2'] 16.0 ['D5', 'B4', 'F#4', 'B3'] False
22.0 ['D5', 'D3', 'F#4', 'A3'] 23.0 ['D5', 'F#4', 'A3', 'D3'] False
23.0 ['D5', 'F#4', 'A3', 'D3'] 24.0 ['A4', 'F#4', 'D4', 'D3'] False
chor368.krn
24.0 ['G4', 'E4', 'C4', 'C3'] 27.0 ['E5', 'G4', 'C4', 'C3'] False
45.0 ['G5', 'G4', 'C4', 'E3'] 46.0 ['C4', 'C5', 'G4', 'E3'] False
49.0 ['F3', 'D5', 'B-3', 'B-2'] 50.0 ['B-2', 'B-4', 'F4', 'D4'] False
51.0 ['G4', 'F4', 'G3', 'C3'] 52.0 ['G4', 'E4', 'C4', 'C3'] False
chor009.krn
16.0 ['A4', 'F#4', 'D4', 'D3'] 17.0 ['A4', 'A4', 'F#4', 'D4'] False
chor069.krn
19.0 ['G4', 'D4', 'B3', 'G2'] 20.0 ['G4', 'D4', 'B3', 'G3'] False
24.0 ['D5', 'F#4', 'A3', 'F#3'] 25.0 ['D5', 'F#4', 'A3', 'F#3'] True
35.0 ['B4', 'G4', 'D4', 'G2'] 36.0 ['G4', 'D5', 'B3', 'G3'] False
61.0 ['A4', 'E4', 'C4', 'A2'] 62.0 ['C5', 'E4', 'A3', 'A3'] False
chor258.krn
33.0 ['D5', 'G4', 'D4', 'B2'] 34.0 ['B2', 'D5', 'G4', 'B3'] False
chor157.krn
15.0 ['F4', 'C4', 'A3', 'F2'] 16.0 ['C5', 'F4', 'A3', 'F3'] False
chor223.krn
7.0 ['C4', 'G3', 'E3', 'C2'] 8.0 ['C4', 'G3', 'E3', 'C3'] False
41.0 ['E4', 'E4', 'G3', 'C#3'] 42.0 ['F#4', 'B3', 'A3', 'D#3'] False
chor177.krn
0.0 ['C#5', 'A4', 'E4', 'A2'] 1.0 ['C#5', 'A4', 'E4', 'A3'] False
15.0 ['B4', 'E4', 'A3', 'E3'] 16.0 ['E4', 'B4', 'G#3', 'E3'] False
17.0 ['A4', 'C#4', 'E3', 'A2'] 20.0 ['C#5', 'A4', 'E4', 'A2'] False
35.0 ['B4', 'E4', 'A3', 'E3'] 36.0 ['E4', 'B4', 'G#3', 'E3'] False
chor187.krn
13.0 ['E5', 'G4', 'D4', 'C3'] 14.0 ['E5', 'G4', 'C4', 'C2'] False
15.0 ['D5', 'G4', 'B3', 'G2'] 16.0 ['D5', 'G4', 'B3', 'G3'] False
31.0 ['G4', 'D4', 'C4', 'G2'] 31.5 ['G4', 'D4', 'G2', 'B3'] False
chor328.krn
0.0 ['B4', 'D4', 'G3', 'G2'] 1.0 ['A4', 'D4', 'B3', 'G3'] False
16.0 ['G4', 'D4', 'B3', 'G2'] 20.0 ['D4', 'B3', 'G3', 'G2'] False
26.0 ['F#4', 'D4', 'A3', 'D3'] 27.0 ['D4', 'A3', 'F#3', 'D3'] False
30.0 ['G4', 'E4', 'E3', 'C3'] 31.0 ['G4', 'E4', 'G3', 'C3'] False
chor002.krn
7.0 ['E4', 'B3', 'G#3', 'E2'] 8.0 ['B4', 'G#4', 'E4', 'E3'] False
chor290.krn
0.0 ['B4', 'G#4', 'E4', 'E3'] 1.0 ['B4', 'F#4', 'B3', 'E3'] False
9.0 ['G#4', 'E4', 'B3', 'E3'] 10.0 ['E3', 'E4', 'B3', 'G#3'] False
31.0 ['G#4', 'F#4', 'C#4', 'C#3'] 32.0 ['G#4', 'E#4', 'C#4', 'C#4'] False
chor088.krn
0.0 ['A4', 'E4', 'C4', 'A2'] 1.0 ['A4', 'E4', 'C4', 'A3'] False
13.0 ['A4', 'E4', 'C4', 'A2'] 16.0 ['E5', 'A4', 'C4', 'A2'] False
21.0 ['B4', 'E4', 'G#3', 'E3'] 24.0 ['B4', 'G#4', 'E4', 'E3'] False
chor030.krn
10.0 ['E4', 'B3', 'G3', 'E2'] 12.0 ['G4', 'E4', 'B3', 'E3'] False
22.0 ['E4', 'B3', 'G3', 'E3'] 24.0 ['G4', 'E4', 'B3', 'E3'] False
chor201.krn
4.0 ['E-4', 'D4', 'G3', 'C3'] 5.0 ['G4', 'E-4', 'C4', 'C3'] False
7.0 ['B-4', 'D4', 'G3', 'G2'] 8.0 ['B-4', 'G4', 'D4', 'G3'] False
12.0 ['E-4', 'C4', 'G3', 'C3'] 13.0 ['G4', 'E-4', 'C4', 'C3'] False
23.0 ['E-4', 'B-3', 'G3', 'E-2'] 24.0 ['E-5', 'B-4', 'G3', 'E-2'] False
40.0 ['G4', 'E-4', 'B-3', 'E-3'] 41.0 ['B-4', 'G4', 'E-4', 'E-3'] False
55.0 ['F4', 'E-4', 'B-3', 'B-2'] 56.0 ['B-4', 'F4', 'D4', 'B-3'] False
chor032.krn
0.0 ['E5', 'A4', 'C#4', 'A2'] 1.0 ['E5', 'A4', 'C#4', 'A3'] False
16.0 ['B4', 'G#4', 'B3', 'E3'] 17.0 ['B4', 'E4', 'G#3', 'E3'] False
chor272.krn
chor183.krn
15.0 ['G4', 'B3', 'D3', 'G2'] 16.0 ['G4', 'D4', 'B3', 'G3'] False
31.0 ['G4', 'E4', 'B3', 'E3'] 32.0 ['B4', 'E4', 'G3', 'E3'] False
chor090.krn
0.0 ['B-4', 'F4', 'D4', 'B-3'] 1.0 ['B-4', 'F4', 'D4', 'B-3'] True
14.0 ['B-4', 'F4', 'D4', 'B-2'] 15.0 ['F5', 'B-4', 'D4', 'B-2'] False
chor046.krn
7.0 ['D5', 'F#4', 'A3', 'D3'] 8.0 ['D5', 'F#4', 'A3', 'D3'] True
9.0 ['D5', 'A4', 'D4', 'F#3'] 10.0 ['A4', 'F#4', 'D4', 'F#3'] False
15.0 ['F#4', 'D4', 'A3', 'D3'] 16.0 ['F#4', 'D4', 'A3', 'D3'] True
chor217.krn
9.0 ['A4', 'F#4', 'D4', 'D3'] 12.0 ['A4', 'F#4', 'D4', 'D3'] True
chor117.krn
3.0 ['C5', 'A-4', 'E-4', 'A-3'] 4.0 ['A-3', 'E-5', 'C5', 'C4'] False
9.0 ['E-5', 'A-4', 'E-4', 'C3'] 10.0 ['E-5', 'A-4', 'E-4', 'C3'] True
chor165.krn
15.0 ['F4', 'C4', 'A3', 'F2'] 16.0 ['A4', 'F4', 'C4', 'F3'] False
16.0 ['A4', 'F4', 'C4', 'F3'] 17.0 ['A4', 'F4', 'C4', 'F3'] True
chor057.krn
7.0 ['G#4', 'E4', 'B3', 'E3'] 8.0 ['E5', 'G#4', 'B3', 'E3'] False
chor068.krn
chor230.krn
0.0 ['G4', 'D4', 'B-3', 'G2'] 1.0 ['G4', 'D4', 'B-3', 'G3'] False
7.0 ['D5', 'F4', 'B-3', 'B-2'] 8.0 ['D5', 'F4', 'B-3', 'B-2'] True
23.0 ['D5', 'F4', 'B-3', 'B-2'] 24.0 ['D5', 'F4', 'B-3', 'B-2'] True
24.0 ['D5', 'F4', 'B-3', 'B-2'] 25.0 ['D5', 'F4', 'B-3', 'B-2'] True
25.0 ['D5', 'F4', 'B-3', 'B-2'] 26.0 ['D5', 'F4', 'B-3', 'D3'] False
33.0 ['B-4', 'G4', 'D4', 'G2'] 34.0 ['D5', 'B-4', 'B-3', 'G3'] False
chor124.krn
0.0 ['B4', 'G4', 'D4', 'G3'] 1.0 ['B4', 'G4', 'D4', 'G3'] True
7.0 ['C5', 'A4', 'C4', 'A2'] 8.0 ['C5', 'E4', 'A3', 'A2'] False
9.0 ['B4', 'G4', 'D4', 'G2'] 10.0 ['G4', 'D4', 'B3', 'G3'] False
chor146.krn
7.0 ['G#4', 'E4', 'B3', 'E3'] 9.0 ['E4', 'B3', 'G#3', 'E3'] False
chor350.krn
6.0 ['C5', 'A4', 'F4', 'F3'] 7.0 ['C5', 'A4', 'F4', 'F3'] True
22.0 ['C5', 'E-4', 'G3', 'C3'] 24.0 ['E-5', 'G4', 'C4', 'C4'] False
38.0 ['C5', 'F4', 'A3', 'F3'] 39.0 ['C5', 'F4', 'A3', 'F3'] True
46.0 ['B-4', 'F4', 'D4', 'B-2'] 47.0 ['B-4', 'F4', 'D4', 'B-2'] True

Currently, the algorithm will always produce the same voicing twice.

Changing this should be a 2-line diff. PR coming soon.

LICENSE?

Hi @ekzhang,

I just made a fork of your repo. I think it is a pretty cool starting point!

However, I just noticed that there is no LICENSE indicated.

Can I assume that it is okay for me to use the code and modify it? If so, maybe adding a LICENSE would help others knowing this as well.

Cheers.

Seventh goes downward rule is missing on "viio" chords

In this example, the tritone (F and B) of a viio moves in parallel motion upwards. The parallel motion is probably allowed because the quality of the fifth is different diminished fifth != perfect fifth and it is not penalized as a parallel fifth.

However, the most important thing is that the F should preferably resolve to E instead of going up to G. This is already handled in V7 chords with the rule of Seventh should resolve downward or stay in unison, however, this does not mitigate the same problem in viio chords, because the F is the fifth of that triad, not the seventh. The code is looking for chord.seventh.

image

The example can be reproduced with this input:

parser.set_defaults(
        key="C",
        chord_progression="I IV6 V6 I V vi IV IV2 viio6 I V I V6 vi65 viio6 I6 ii65 V7 I",
        durations="1 1 1 1 1 1 1 1/2 1/2 1 2 1 1 1 1 1 1 1 2",
        time_signature="3/4",
)

In the same example, a melodic leap of a seventh is seen in the bass (D down a seventh to E). Some melodic motions in the same voice should be penalized. Sevenths are one of them. Augmented seconds are another one. Tritones are another one. Maybe more I can't remember now. This can be a separate issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.