-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtuning.py
52 lines (43 loc) · 1.39 KB
/
tuning.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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
"""
Tuning systems are a mess.
https://en.wikipedia.org/wiki/Musical_tuning#Tuning_systems
https://en.wikipedia.org/wiki/Concert_pitch
"""
class ET12(): # 12 tone equal temperament
twelth_root_of_2 = 1.05946309435929526455
relative_to_c = {
'c': 0,
'd': 2,
'e': 4,
'f': 5,
'g': 7,
'a': 9,
'b': 11,
}
def __init__(self, **kwargs):
if len(kwargs) > 1:
raise TypeError()
self.tones = dict()
self.base_tone, self.base_freq = list(kwargs.items())[0]
for octave in [2,3,4,5,6]:
for note in self.relative_to_c:
self.get('{}{}'.format(note, octave))
def get(self, tone):
if tone not in self.tones:
self.tones[tone] = self.base_freq * self.ratio(tone, self.base_tone)
return self.tones[tone]
def _modifier(self, note):
if len(note) < 3:
return 0
modifier = note[2]
if modifier in ['+', '#']:
return 1
if modifier in ['-', 'b']:
return -1
def ratio(self, a, b):
octaves = int(a[1]) - int(b[1])
mod_a = self._modifier(a)
mod_b = self._modifier(b)
semitones = self.relative_to_c[a[0]] + mod_a - (self.relative_to_c[b[0]] + mod_b)
exponent = octaves * 12 + semitones
return self.twelth_root_of_2 ** exponent