任意のキーとメジャーorマイナーを指定して。
成果物
Python.Audio.Scale.201708031249
前回
- http://ytyaru.hatenablog.com/entry/2018/08/16/000000
- http://ytyaru.hatenablog.com/entry/2018/08/17/000000
音階(スケール)
任意のスケールをを算出したい。
たとえば、キーにC
、スケールにメジャー
を指定したら、C,D,E,F,G,A,B
を返して欲しい。
キー
CMajorの場合、C(ド)がキー。
メジャーとマイナー
- CMajor = C,D,E,F,G,A,B
- Cminor = C,D,D#,F,G,G#,A#
平行調
- CMajor, Aminor = [C,D,E,F,G,A,B], [A,B,C,D,E,F,G]
異なる調(スケール)なのに、使う音が同じなものを「平行調」というらしい。
音階(スケール)の算出
- メジャー・スケール=全,全,半,全,全,全,半
- マイナー・スケール=全,半,全,全,半,全,全
数値化すると以下。
- メジャー・スケール=2,2,1,2,2,2,1
- マイナー・スケール=2,1,2,2,1,2,2
全音と半音
以下の説明から、数値上では上記のように表現できると考えた。
全音
- ド-レ
- レ-ミ
- ファ-ソ
- ソ
- ファ-ソ
半音
- ミ-ファ
- シ-ド
数値化
- ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B']
- [0,1,2,3,4,5,6,7,8,9,10,11]
上記のように対応できると考えた。
C+全音=D 0+2=2 C=0 全音=2 2=D
- CMajor = C,D,E,F,G,A,B
- CMajor = 0,2,4,5,7,9,11
ソースコード
抜粋。
import EqualTemperament import Key class Scale: def __init__(self): self.__major = [2,2,1,2,2,2,1] self.__minor = [2,1,2,2,1,2,2] self.__scales = [] self.__et = EqualTemperament.EqualTemperament() @property def Scales(self): return self.__scales @property def Key(self): return self.__scales[0] def Major(self, key='C'): return self.__create_scales(self.__major, key) def Minor(self, key='C'): return self.__create_scales(self.__minor, key) def __create_scales(self, scales, key): self.__scales.clear() k = Key.Key() pitch = k.Get(key) self.__scales.append(pitch) for interval in scales: pitch += interval if pitch < 0: pitch = len(self.__et.Keys) - abs(pitch) elif len(self.__et.Keys)-1 < pitch: pitch %= len(self.__et.Keys) self.__scales.append(pitch) return self.__scales if __name__ == '__main__': s = Scale() print(s.Major(key='C')) print(','.join([Key.Key.ValueToName(k) for k in s.Scales])) print(s.Minor(key='A')) print(','.join([Key.Key.ValueToName(k) for k in s.Scales])) print(s.Minor(key='C')) print(','.join([Key.Key.ValueToName(k) for k in s.Scales])) print(s.Major(key='D')) print(','.join([Key.Key.ValueToName(k) for k in s.Scales]))
[0, 2, 4, 5, 7, 9, 11, 0] C,D,E,F,G,A,B,C [9, 11, 0, 2, 4, 5, 7, 9] A,B,C,D,E,F,G,A [0, 2, 3, 5, 7, 8, 10, 0] C,D,D+,F,G,G+,A+,C [2, 4, 6, 7, 9, 11, 1, 2] D,E,F+,G,A,B,C+,D
スケール | 正解 | 出力 |
---|---|---|
C Major | C,D,E,F,G,A,B | C,D,E,F,G,A,B |
A minor | A,B,C,D,E,F,G | A,B,C,D,E,F,G |
C minor | C,D,D#,F,G,G#,A# | C,D,D+,F,G,G+,A+ |
D Major | D,E,F#,G,A,B,C# | D,E,F+,G,A,B,C+ |
とりあえず、ネットで調べた正解と一致している。たぶん他のも大丈夫だろう。
print('---------- メジャー・スケール ----------') for key in ['C','C+','D','D+','E','F','F+','G','G+','A','A+','B']: print(key, 'メジャー・スケール') print(s.Major(key=key)) print(','.join([Key.Key.ValueToName(k) for k in s.Scales])) print('---------- マイナー・スケール ----------') for key in ['C','C+','D','D+','E','F','F+','G','G+','A','A+','B']: print(s.Minor(key=key)) print(','.join([Key.Key.ValueToName(k) for k in s.Scales]))
$ python Scale.py ---------- メジャー・スケール ---------- C メジャー・スケール [0, 2, 4, 5, 7, 9, 11, 0] C,D,E,F,G,A,B,C C+ メジャー・スケール [1, 3, 5, 6, 8, 10, 0, 1] C+,D+,F,F+,G+,A+,C,C+ D メジャー・スケール [2, 4, 6, 7, 9, 11, 1, 2] D,E,F+,G,A,B,C+,D D+ メジャー・スケール [3, 5, 7, 8, 10, 0, 2, 3] D+,F,G,G+,A+,C,D,D+ E メジャー・スケール [4, 6, 8, 9, 11, 1, 3, 4] E,F+,G+,A,B,C+,D+,E F メジャー・スケール [5, 7, 9, 10, 0, 2, 4, 5] F,G,A,A+,C,D,E,F F+ メジャー・スケール [6, 8, 10, 11, 1, 3, 5, 6] F+,G+,A+,B,C+,D+,F,F+ G メジャー・スケール [7, 9, 11, 0, 2, 4, 6, 7] G,A,B,C,D,E,F+,G G+ メジャー・スケール [8, 10, 0, 1, 3, 5, 7, 8] G+,A+,C,C+,D+,F,G,G+ A メジャー・スケール [9, 11, 1, 2, 4, 6, 8, 9] A,B,C+,D,E,F+,G+,A A+ メジャー・スケール [10, 0, 2, 3, 5, 7, 9, 10] A+,C,D,D+,F,G,A,A+ B メジャー・スケール [11, 1, 3, 4, 6, 8, 10, 11] B,C+,D+,E,F+,G+,A+,B ---------- マイナー・スケール ---------- [0, 2, 3, 5, 7, 8, 10, 0] C,D,D+,F,G,G+,A+,C [1, 3, 4, 6, 8, 9, 11, 1] C+,D+,E,F+,G+,A,B,C+ [2, 4, 5, 7, 9, 10, 0, 2] D,E,F,G,A,A+,C,D [3, 5, 6, 8, 10, 11, 1, 3] D+,F,F+,G+,A+,B,C+,D+ [4, 6, 7, 9, 11, 0, 2, 4] E,F+,G,A,B,C,D,E [5, 7, 8, 10, 0, 1, 3, 5] F,G,G+,A+,C,C+,D+,F [6, 8, 9, 11, 1, 2, 4, 6] F+,G+,A,B,C+,D,E,F+ [7, 9, 10, 0, 2, 3, 5, 7] G,A,A+,C,D,D+,F,G [8, 10, 11, 1, 3, 4, 6, 8] G+,A+,B,C+,D+,E,F+,G+ [9, 11, 0, 2, 4, 5, 7, 9] A,B,C,D,E,F,G,A [10, 0, 1, 3, 5, 6, 8, 10] A+,C,C+,D+,F,F+,G+,A+ [11, 1, 2, 4, 6, 7, 9, 11] B,C+,D,E,F+,G,A,B
所感
つぎは実際に音を鳴らして確認したい。
が、音の高さ(オクターブ)を考慮して周波数を算出せねばならないことに気づいた。面倒になりそう。