経緯

会社の合宿で、何をつくろうかと考えたときに、最近、音楽ばっかりやってるから音楽系のツールを作ろうと思った。
コード進行のパターンの辞書を増やしていってるタイミングだったので、ベースのコード進行を作って、リハーモナイズ(メロディーはそのままにコード進行だけをアレンジしていくこと)をできるようにしたかった。

使ったもの

  • CoffeeScript
  • jQuery

オワコンとはわかりつつ、今回は判定のロジックのほうが難しそうだったので、あとでTypeScript + Reactとかに移行すればいいや、みたいな感覚で使い慣れているものを使ってプロトタイプを作ることにした。

前提

  • メロディーは基本的にピアノロールで入力できるようにする。
  • キーとコードチェンジのタイミングは1小節毎, 2拍毎, 1拍毎のいずれかをユーザーが選択できる。

ロジック

部分的なメロディーに合うコードにスコアを付ける

「ミーーレドーーー」のようなメロディーがあった場合、

[E,E,E,D,C,C,C,C] という長さ8の配列を作る。イメージとしては音符を8分音符に全部分割しているイメージ。

ここでスコアリングは以下のような方針でやった。

拍の重み付け

「1拍目、3拍目が一番重要、2拍目、4拍目は次に重要、その他の裏拍に入るところはあまり重要ではない」という思想。

例えば、

1拍目、3拍目: 100
2拍目、4拍目: 80
その他の裏拍: 50

と置くと、先ほどのメロディーは

E: 100 + 50 + 80 = 230
D: 50
C: 100 + 50 + 80 + 50 = 280

という音の重要度と捉える。

コードの判定

コードの構成音とメロディーが合致する音のスコアの和をとって、それをコードとメロディーの相性とする。

たとえば、

[CM7: {C, E, G, B}の場合]
230(E) + 280(C) = 510

[Dm7: {D, F, A, C}の場合]
50(D) + C(280) = 330

という形で、このメロディーにはDm7よりもCM7のほうがあうという形になる。

[Column]
本来であれば、7thの場合、ちょっとスコアを下げる重み付けをしたり、
9thや11thなどのテンションでもちゃんとスコアリングしてあげたりしたほうがいいとは思う。

とは言っても、テンションはそのコードがドミナントなのかトニックなのかによって、
使い方が変わってきたりするものなので、一旦、ざっくりとベースのコード進行を把握するという意味を込めて、
4和音の構成音ということで固定することにした。

キーにマッチするかどうかで重み付けする

キーをユーザーに選択できる形にしたが、ダイアトニックコードの判定を自動判定するのが面倒だったからにすぎない。
本来であれば、同様の手法でキーを自動判定することはできるとは思う。

ここでやりたかったのは

「ミーーレドーーー」というメロディーを判定させると

CM7でもC+5でも同じ510というスコアが着いてしまうことを避けるためだった。
ダイアトニックコードでない音が1音含まれるごとに1より小さな数字を掛けてのスコアリングに下げることにした。

こうすることによって、定数を0.9とすると、CM7: 510, C+5: 510×0.8 = 408というスコアリングになった。

今回できたところと今後やっていきたいこと

ひとまず、コード進行というよりはメロディーに合うコードを選択する機能を作った。
上位5件の候補を各メロディーの上部に表示することができた。

  • 一旦のベースのコード進行はできたので、ここからT,S,Dの概念を追加して、コード進行としてスムーズかどうかのスコアリング
  • ドッペルドミナント、II-Vや裏コードなどの定型句のスコアリング
  • 多少メロディーと不協和であったとしても、クリシェラインを含むコード進行を提案する

などの機能を追加していきたい。
要は、コードの提案ではなく、コード進行の提案にしていきたい。