FoxDotで丸の内サディスティック進行を再現する方法

2 min read読了の目安(約1900字

前提

FoxDot とは

Python で構築されたライブコーディング用環境です。
OSC プロトコルを用いて SuperCollider という音響合成ソフトと連携し、リアルタイムな音楽生成が可能なツールです。
最近勉強し始めたばかりですが、めちゃくちゃ楽しいです。
FoxDot 自体の詳細な解説や導入方法についてはわかりやすい記事が世の中にたくさんあるのでそちらをご参照いただければと思います。

スケールについて

FoxDot ではスケール(音階)を設定しており、そのスケール内の音が配列に定義されています。

>>> # Root 0 = C
... print(Root.default)
0
# Scale.major = メジャースケールをデフォルトのスケールとして設定
Scale.default = Scale.major
print(Scale.default)
>>> # C D E F G A B
... print(Scale.default)
P[0, 2, 4, 5, 7, 9, 11]

ド〜オクターブ上のドまでの 12 半音のうち、どの音を取り出すかという形でスケールの配列を定義しています。
P というのは FoxDot 内で定義されている Pattern オブジェクトを指しています。
そのため、以下コードを実行すると C メジャースケールとして再生されます。

p1 >> pluck([0,1,2,3,4,5,6,7]) #CDEFGABを順に再生
p2 >> pluck((0,2,4)) #CEGを同時に再生(Cメジャーコード)

ちなみにマイナースケールであれば以下の形になります。

>>> Scale.default = Scale.minor
... print(Scale.default)
... # C D Eb F G Ab Bb
P[0, 2, 3, 5, 7, 8, 10]

やりたかったこと

FoxDot で作られる音楽はその性質上ループミュージックが前提になります。
せっかくなら大好きな丸の内サディスティック進行で色々やりたいなと思いました。

丸の内サディスティック進行 Ⅳ△7 → Ⅲ7 → Ⅵm7 → Ⅰ7 の進行を指し、
Root = C とすると F△7 → E7 → Am7 → C7 となり、各コードの構成音は以下となります。

| コード | 構成音 |
| F△7 | F, A, C, E |
| E7 | E, Ab, A, D |
| Am7 | A, C, E, G |
| C7 | C, E, G, Bb |

太字で書いた音がスケール外の音になるのですが、前提でも記載した通り、
FoxDot ではスケールの音で配列が定義されるため、通常スケール外の音を使えません。
試した結果、以下の通りコード構成音を設定することで再現しています。
(わかりやすくするために各コードを変数にしています。)

Fmaj7 = (3,5,7,9) #F, A, C, E
E7 = (2,4.5,6,8) #E, Ab, B, D
Amin7 = (5,7,9,11) #A, C, E, G
C7 = (7,2,4,5.5) #C, E, G, Bb

p3 >> pluck([Fmaj7, E7, Amin7, C7], dur=2)

E7 の Ab は 4.5、C7 の Bb は 5.5 を設定することで再生されています。

わかっていないこと

何故小数を使うことでスケール外の音が利用できるのか

例えば Ab の音を利用するために 4.5 という値を使用しています。
Scale のインデックスと返り値を見ると[4]→7(G)、[5]→9(A)となります。

>>> print(Scale.major[4])
... print(Scale.major[5])
7
9

直感的にはインデックス[4.5]→8(Ab)となりそうですが、そもそも配列のインデックスに小数は使えないのでは…?となっています。
以下はエラーになるので、Pattern オブジェクトというよりも音を再生する Player オブジェクトの仕組みに依りそうです。

print(Scale.major[4.5])

最後に

まだまだ足を踏み入れたばかりなので、これからもっと色々動かしてみます。
最終的には Processing と連携させてビジュアライズするとこまでやれたらなと思っています。