Skip to content

Instantly share code, notes, and snippets.

@bzamecnik
Created November 12, 2017 00:23
Show Gist options
  • Save bzamecnik/641edbe0585547e13dd4a333eb698bb8 to your computer and use it in GitHub Desktop.
Save bzamecnik/641edbe0585547e13dd4a333eb698bb8 to your computer and use it in GitHub Desktop.
Distance of pitch class to key tonic with respect to dissonance
# https://github.com/bzamecnik/ideas/blob/master/key_coloring.md
import numpy as np
def key_distance(pitch_class, key):
"""
Distance between a pitch class and tonic of a key
which roughly approximates dissonance.
Eg. in key of C the pitch classes sorted from most consonant
to most dissonant:
['C', 'G', 'D', 'A', 'E', 'B', 'F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb']
Note that first there is an inner pentatonic (C G D A E),
then border tones (B, F), then outer pentatonic (Bb Eb Ab Db Gb).
pitch_class - range: [0; 11]
key - range: [0; 11]
returns: distance in range [0; 11]
"""
i = ((pitch_class - key + 12) * 7) % 12
return i if i < 6 else 12 - 1 + 6 - i
def test_key_distance():
assert np.allclose(
[key_distance(tone, 0) for tone in range(12)],
[0, 10, 2, 8, 4, 6, 11, 1, 9, 3, 7, 5])
assert np.allclose(
[key_distance(tone, 1) for tone in range(12)],
[5, 0, 10, 2, 8, 4, 6, 11, 1, 9, 3, 7])
assert [name for pc, name in sorted(zip(
[key_distance(tone, 0) for tone in range(12)],
['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']
))] == ['C', 'G', 'D', 'A', 'E', 'B', 'F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment