やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

音階(スケール)を算出する

任意のキーとメジャーorマイナーを指定して。

成果物

GitHubPython.Audio.Scale.201708031249

前回

音階(スケール)

任意のスケールをを算出したい。

たとえば、キーに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

所感

つぎは実際に音を鳴らして確認したい。

が、音の高さ(オクターブ)を考慮して周波数を算出せねばならないことに気づいた。面倒になりそう。