本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox) | GameBusiness.jp

本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)

エリック・サティ様式の自動生成機関を作りました。

その他 その他
本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)
  • 本物と偽物を混ぜた演奏も。エリック・サティ様式の自動生成アプリ「無限サティ機関」をClaude Codeで作って公開した(CloseBox)

無限音楽機関シリーズで、いちばん流し聞きしやすいのができました。家具の音楽こと、エリック・サティのピアノ楽曲。環境音楽の元祖といっていいでしょう。

1925年に死去したサティは日本では1975年にパブリックドメインになりました。それ以降はCM、BGMなどさまざまな取り上げ方をされ、筆者は大学生の頃、高橋悠治版サティ作品集を買って聞いていました。

サティの初体験は、矢野顕子さんのピアノの先生がサティを教えてくれたと話しながら弾いていたラジオ番組がそうだったという記憶があります。

無限音楽機関シリーズにサティを加える

バッハのトッカータやプレリュードを永久に生成し続ける「無限バッハ機関」、キース・エマーソン風のMoogインプロヴィゼーション、エリック・クラプトン風のブルースギターを生成するSLOWHAND∞。ここしばらく、特定の音楽家の様式を規則として記述し、ブラウザ上で無限に走らせるプログラムを作り続けてきました。

基本構造はどれも同じです。位相単位で楽譜を生成し、数秒先まで先読みしてスケジュールし、Tone.jsなどで鳴らす。この3層構造だけで、ジャンルを問わず「止めるまで終わらない音楽」が成立します。

エリック・サティはこの中でいちばん簡単そうに見えて、実際にはこれまでで最も厄介でした。

正反対な君と僕、じゃなくてバッハとサティ

無限バッハ機関の中核は機能和声の文法でした。トニック、サブドミナント、ドミナントの機能連鎖に五度圏の循環進行とセカンダリドミナントを足す。要するに「次にどこへ行くか」の規則を書けば、あとは勝手に音楽になります。進行こそがバッハの推進力なので、進行の規則がそのままエンジンになるわけです。

サティはこれが使えません。有名なジムノペディ第1番は、ざっくり言えばGM7とDM7を交互に往復するだけの曲です。属七の解決もなければ、盛り上がりに向かう構築もない。バッハで書いたのが「進行の規則」だとすれば、サティで書かねばならないのは「進行しないという規則」でした。

そして、進行しない音楽をアルゴリズムで無限に回すと、ほぼ確実に退屈になります。ここが今回のポイントです。

根音進行テーブルの重み付けだけで一気に寄る

最初に効いたのは、根音がどう動くかの確率テーブルでした。バッハ用のものを流用すると、どうしても五度下行が優勢になって解決感が出てしまう。そこで、3度関係の移動と同一和音の保続に重みを厚く振り、属七的な動きを薄くしました。

{ d: 0, w: 1.6 } // 動かない
{ d: 2, w: 5.0 } // 3度上
{ d: -2, w: 5.0 } // 3度下
{ d: 4, w: 1.0 } // 5度上(薄く)

このテーブルを差し替えただけで、出てくる音の質感がはっきりサティ側へ移りました。加えて、使う旋法を導音を持たないものに寄せています。ドリア、エオリア、フリギアが主軸で、グノシエンヌ用には二重和声音階を混ぜました。導音がなければ、そもそも解決したくなりようがありません。

5つの様式エンジン

作品ごとに骨格が違いすぎるので、単一のエンジンにまとめるのは諦めて、5本を並列に実装しました。

ジムノペディは3拍子。1拍目に低音、2拍目に和音という伴奏型を一切崩さず、その上で拍を跨ぐ長い旋律を歌わせます。伴奏が完全に不変であることが条件で、ここに変化を入れるとサティではなくなります。

グノシエンヌは小節線がない流儀です。左手は8分音符の定型を刻み続け、右手に装飾音とターンを載せ、フレーズ長を5拍から11拍まで不揃いにしました。

サラバンドは1887年の3曲を下敷きに、9の和音を解決させないまま平行に滑らせます。ドビュッシーより10年早く印象派の響きに到達していた様式です。

オジーヴはグレゴリオ聖歌を鍵盤に移した作品で、同じ旋律を単旋律→和声づけp→オクターヴ重ねff→単旋律pppと4回並べるだけ。展開部が存在しません。これは実装がいちばん楽でした。

ヴェクサシオンは13音の主題と2種の和声づけを交互に繰り返すだけの曲で、サティは楽譜に840回繰り返せと書き添えています。カウンタを付けて、いま何回目かを表示するようにしました。これを一人で演奏した人もいるそうで、人間ってすごいなと思います。ほぼ1日仕事で、トイレにも行けないのでオムツをしていたそうです。

「家具の音楽」モードをオンにすると、6フレーズごとに様式が漂流し、8フレーズごとに中心音と旋法がメディアント方向へずれていきます。

量子化されたサティは死ぬ

もうひとつ決定的だったのが人間化の処理です。フレーズ末に緩やかなリタルダンドをかけるのは他のプロジェクトでもやっていますが、今回いちばん効いたのは両手のタイミングをずらすことでした。左手を16ミリ秒早く、右手を13ミリ秒遅く出す。それだけで、サロンのピアノらしい沈み込みが出ます。

逆に言えば、ここを外すと全部が台無しになります。テンポが遅く、音数が少なく、和声が動かない音楽では、タイミングの機械らしさを隠す材料が他に何もないからです。ブルースやバッハなら音数の多さで誤魔化せていた部分が、サティでは全部さらけ出されてしまいます。

演奏指示も自動生成する

サティといえば楽譜に書き込まれた奇妙な演奏指示文です。「歯痛のナイチンゲールのように」の類ですね。実曲の指示をそのまま引用するのは芸がないので、動詞・目的語・様態の3パートを組み合わせて自動生成することにしました。「嘘をつくランプをよそ見をしながら撫でなさい」といった具合の、それらしい何かが出てきます。

面白いのは、生成した指示の3割ほどを実際にパラメータへ接続したことです。「Sans lumière(光なしで)」が出ればローパスフィルタを2.4kHzまで落とし、「Modulez, discrètement(ひそかに転調しなさい)」が出れば中心音を動かす。指示が飾りではなく制御になっているので、画面に赤いインクで文字が現れた数秒後に音が実際に変わります。

音源とスコア表示

ピアノ音源はこれまで何度も使ってきたサンプラー音源のSalamander Grand Piano(CC-BY、Alexander Holm氏)です。ただし以前のユーミン様式ジェネレータのときと同様、環境によってはCSPでCDNが弾かれることがあるので、9秒でタイムアウトさせてFM合成と三角波の2層によるフェルトピアノへフォールバックする経路を入れ、どちらで鳴っているかを画面に表示するようにしました。

画面中央には、羊皮紙色の帯に音符を楕円で流す簡易スコアを置いています。赤い縦線が現在位置で、その右側にはまだ鳴っていない、生成されたばかりの音が並びます。無限に書かれ続ける楽譜を先に見せるという趣向です。

右下には「サティ度」という参考値を出しました。長7度の含有率、導音の少なさ、強弱幅の狭さ、使用音組織の閉じ方の4項目から算出しています。あくまで自作の指標で、権威はまったくありません。SAN値とも違います。

1曲完奏に18時間

偽ヴェクサシオンのカウンターは実装しましたが、本家と同じ840回を回し切るとどうなるかはまだ試していません。演奏に18時間ほどかかる計算です。ブラウザのタブを18時間開いておくというのは、それ自体がサティ的な実験として悪くない気もしています。

Salamander を鳴らす

最初はピアノサンプラー音源の Salamander Grand Piano が鳴らず、9秒でタイムアウトして合成音に落ちる状態でした。

そこで30サンプル(約2MB)をプロジェクトに同梱し、オフラインでも確実に鳴るようにしました。ローダーも書き直しています。中核となる10音が揃った時点で先に演奏を始め、残りは鳴らしながら追加していく方式です。

このとき、指摘されていなかったバグも見つかりました。スケジューラが音源を事前にキャプチャしていたため、読み込みが完了しても古い音源で鳴り続けていたのです。発音の瞬間に音源を参照するよう修正しました。

録画をMP4に

録画形式が WebM だったので、MP4(H.264 + AAC)に変更しました。毎度のことなのでClaude Codeはいい加減覚えてほしいです。ブラウザの対応形式を実際に調べたうえで優先順位を決めています。

ここでもバグが見つかりました。録画停止時に音声の出力先を解除しておらず、録画のたびにマスターへ出力先が積み上がっていました。

五線譜のリアルタイム描画

画面は、シンプルなピアノロール表示から、本物の大譜表へと作り替えました。

ここで難しいのは音名の綴りです。MIDI番号だけでは五線のどこに置くか決まりません。G♯ と A♭ は同じ音ですが、五線上の位置が違うからです。旋法から臨時記号が最も少なくなる綴りを選ぶ仕組みを実装し、root 55~68 × 旋法8種の全112通りを総当たりで検証しました。破綻はゼロでした。

その後、「符幹が長すぎて低音部とつながっている」「♯と♭が大きすぎる」と分かったので原因を特定して修正。

臨時記号が一度も描かれていないことも判明。記号の要否を「生成時の調号」と比べていたため必ず一致してしまい、転調後も表示中の調号と矛盾したままだったのです。描画時に判定するよう直しました。

鍵盤と、落下する音符

画面に88鍵の鍵盤を追加しました。Salamander の収録範囲と同じ A0~C8 です。黒鍵の2つ組・3つ組は、実際のピアノどおりの割り付けにしています。

さらに「音符から鍵盤へ流れていくようにしたい」という要望を出して、譜面・落下レーン・鍵盤をひと続きのパネルに組み直し。音符は鳴る2秒前に譜面を離れ、カーブしながら落ちていき、鳴る瞬間にちょうど自分のキーに着きます。音ゲーのような下に向かってまっすぐ降り注いでくるのとは違う、面白いものになったのではないでしょうかl。

リズムのもたつきを直す

そのあとで気づいたのが、「リズムがもたる」こと。原因は3つ。

フレーズの継ぎ目ごとに必ず無音を挿入していたこと。全フレーズの末尾で減速し、さらに全長を3%伸ばしていたこと(引くばかりで押し返しがない)。そして演奏指示の速度変化が非対称で、鳴らし続けるほど遅い方へ流れていたことです。

書き出したMIDIから実測した結果は次のとおりです。

```
打鍵イベント 4秒超の空白 最大の空白
修正前 55 / 100秒 18回 (33.3%) 5.58秒
修正後 160 / 104秒 3回 (1.9%) 1.85秒
```

なおこの検証の過程で、同じタイミングで追加した新様式2つにも不具合が見つかりました。内声がなく、4.7秒に1打だけの静止画のような状態だったのです。もたつきを直しに行って、もたつく様式を足していたことになります。

様式はこの段階で5種類から9種類に増やしました。

本物の楽譜を演奏する

次に、実際のサティの楽譜を読み込めるようにしました。

権利関係は慎重に整理しています。楽曲そのものはパブリックドメインですが、譜面データには別の権利が乗ることがあるためです。CC0 と明示されている Mutopia Project 版の《3つのジムノペディ》を選びました。同サイトにあるグノシエンヌ群は CC BY-SA 4.0(継承義務あり)なので、あえて同梱していません。

標準MIDIファイルのリーダーを実装し、解析結果が実曲と一致することを確認しました。第1番の冒頭は、低音の G2 が1小節(3秒)続き、2拍目に B3・D4・F#4 の和音が入ります。これで G△7、次の小節が D。「長7度を解決させないまま交替する」という響きそのものです。

実譜の技法を生成側へ反映する

「本物の演奏ファイルの技法やアーティキュレーションを生成版にも反映してほしい」という要望も出しました。理由は、自動生成の演奏にはやはり不自然さがあったからです。

これには実譜と生成を同じ物差しで測り、差を数値で出して潰していく、という進め方で対応。

最大の発見はアーティキュレーション、演奏技法でした。実譜には「次の音に届かない音」が一つもないのです。サティはペダルを踏んだまま書いているので、音が切れる場所がありません。一方の生成側は、音価に 0.95 のような係数を掛けて必ず隙間を作っていました。全9様式を修正しています。

どうも本物っぽくないなと思っていたのはここでした。

逆に、真似なかったものもあります。強弱です。同梱データは浄書ソフトの書き出しでほぼ平坦な値で、サティの pp や nuancé とは無関係の機械的なものでした。ここから「本物のニュアンス」は学べないと判断しました。

本物と生成を混ぜる

本物の4~8小節と、生成の1~3フレーズを交互につなぐモードを作りました。継ぎ目で調と速さを実譜に合わせるので、どこで入れ替わったか分かりにくくなっています。

種明かしを伏せる切り替えも付けました。

ここで「テンポの揺れでバレてしまう」と指摘。これは、生成側だけがリタルダンドしていたためです。このモードでは生成側の速度変動を止め、両者に同じ微細なゆらぎだけを残しました。

なお、ばらつきの指標(CV)は使えませんでした。本物の楽譜自身のリズムが混ざってしまい、生成側の揺れと区別できないためです。最長値が決定的な指標になりました。

さらに、リアルタイムでは問題ないのに、録画されたものは音と楽譜がずれてしまう問題が発生。これも修正しました。

ときどき自分が知ってるフレーズが出てくるけどフェードアウトしてまた戻ってくるヘンテコな感覚を体験してみてください。

GitHub Pagesで公開

GitHub で公開し、GitHub Pages にデプロイしました。

公開URLを実際にブラウザで開いて、音源・実譜の再生・混在モード・鍵盤の点灯まで動作を確認しています。

ほぼ全ての工程で、目視や推測ではなく、書き出したMIDIや画面のピクセルを実測して判断しました。そのおかげで、指摘の裏にある本当の原因を突き止められましたし、ときには物差し自体の欠陥にも気づけました。指摘されていないバグを複数見つけられたのも、同じ理由だと思います。

というわけで、虚実まぜこぜにしてもいいし、さまざまなパターンをランダムに聞いてもいいし、お好きな環境音楽としてお愉しみください。24時間かけっぱなしでもOK。お店でかけてもまったくお金はかかりません。

- サイト: https://matsuo-koya.github.io/satie-infinity/
- リポジトリ: https://github.com/matsuo-koya/satie-infinity

ついでに、無限バッハ機関も改良しています。

減衰が早すぎてリアルさに欠けていたチェンバロのサウンドを改善しました。また、ポール・マッカートニーがBlackbirdを弾くときにインスパイアされたというリュート組曲を基にした生成を、リュートの物理モデリング音源で再生できるようにしました。

- サイト;https://matsuo-koya.github.io/bach-perpetuum/

- リポジトリ: https://github.com/matsuo-koya/bach-perpetuum

《松尾公也》

この記事の感想は?

  • いいね
  • 大好き
  • 驚いた
  • つまらない
  • かなしい
【注目の記事】[PR]

関連ニュース

特集

人気ニュースランキングや特集をお届け…メルマガ会員はこちら