Counterpoint
対位法という言葉を知っているエンジニアは、たぶん少ない。
和声学は縦の響きを扱う。コードを積み、ドミナントからトニックへ解決する。不協和音には厳格なルールがあり、いつ使えて、いつ解決しなければならないかが決まっている。対位法はそれとは別の軸だ。横の旋律を扱う。複数の独立した旋律が同時に流れるとき、それぞれが独立性を保ちながら、縦に重なったときに和声的にも破綻しないためのルールだ。
並行五度の禁止。声部の交差の制限。跳躍したあとの反行。不協和音は経過音や刺繍音や掛留音として、特定の条件でのみ許される。フックスの種別対位法では、1対1の単純な音符の対置から始まり、2対1、4対1、シンコペーション、そして自由対位法へと段階的に複雑さが増していく。一つひとつのルールは論理的で、エンジニアの脳にはむしろ馴染みやすい。条件分岐の集合だ。これならコードで書ける。そう思った。
そんなつもりでバッハの器楽作品を生成するOSSを書き始めた。ルールをひとつずつC++で実装し、制約を満たす旋律を生成する。並行五度は検出できる。声部の交差も防げる。掛留音の準備と解決も強制できる。
バッハの楽曲から音程変化と拍位置と音度の遷移確率を抽出し、マルコフ連鎖で旋律の癖を取り込んだ。バリデータを通せばコンプライアンス率が出る。テストは通る。ルールはすべて守られている。
だが出てくるものは、音楽と呼ぶにはまだ果てしなく遠い。
ルールをすべて満たしているのに、音楽として成立していない。仕様通りに動いているのにユーザーが使いたくないソフトウェアと同じだ。バグはない。でも何かが決定的に足りない。
バッハのフーガを聴くと、同じルールの上で何が起きているのかが嫌というほどわかる。制約を守りながら、旋律が歌い、応答が追いかけ、緊張が生まれ、解決する。そして彼は踏み外す。わかっていて踏み外す。並行五度を避けるルールを知り尽くした上で、あえてぎりぎりの跳躍を選ぶ。制約を壊さないように、制約の縁を歩く。それを創造という。
同じルールを使って、なぜこれほどの差が出るのか。276年前の人間に、完全に負けている。
音楽の難しさはここにある。ルールは教えられる。しかしルールの中で何を選ぶかは教えられない。プログラミングも似ている。文法は学べる。設計パターンも覚えられる。だが「良いコード」と「動くコード」の間にある何かは、結局のところ、書き続けて掴むしかない。
興味を持ったら一緒に遊んでほしい。C++だが。