-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaudiomisc.py
37 lines (29 loc) · 1.18 KB
/
audiomisc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import scipy.linalg
import scipy.stats
# https://gist.github.com/bmcfee/1f66825cef2eb34c839b42dddbad49fd
def ks_key(X):
'''Estimate the key from a pitch class distribution
Parameters
----------
X : np.ndarray, shape=(12,)
Pitch-class energy distribution. Need not be normalized
Returns
-------
major : np.ndarray, shape=(12,)
minor : np.ndarray, shape=(12,)
For each key (C:maj, ..., B:maj) and (C:min, ..., B:min),
the correlation score for `X` against that key.
'''
X = scipy.stats.zscore(X)
# Coefficients from Kumhansl and Schmuckler
# as reported here: http://rnhart.net/articles/key-finding/
# C, C#, D, D#, E, F, F#, G, G#, A, A#, B
major = np.asarray([6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88])
major = scipy.stats.zscore(major)
minor = np.asarray([6.33, 2.68, 3.52, 5.38, 2.60, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17])
minor = scipy.stats.zscore(minor)
# Generate all rotations of major
major = scipy.linalg.circulant(major)
minor = scipy.linalg.circulant(minor)
return major.T.dot(X), minor.T.dot(X)