• #chord-rush
  • #demo
  • #vue
  • #web-audio
  • #vivid-writing
開発mdx-playground

ギターコードだけ降ってきても、何の曲かわからない

朝、Downloads フォルダに転がっていた chord-rhythm-game.html を開いた。ボタンを押すと「C」「G」「Am」「F」が降ってくる。叩くと音は鳴る。けれど、何の曲を弾いているのか自分でわからない。コードだけだと、頭の中で勝手にメロディーを補完できる人にしか通じない仕様だった。

Claude Code に投げた要望は雑だった。「ギターのコードだけだとわかんないんで、なんかメロディーをうまくつなげたい。つなぎの音をボタンで追加してほしい」。

返ってきた最初の手は、画面下に 1〜8 度のスケールボタンを並べる案だった。曲の最初のコードからキー(C major / F major / A minor など)を自動判定して、その調の音階を 8 つのボタンで鳴らせるようにする。Yesterday を選んだら F major、Am 始まりの曲を選んだら A minor が出るところまで Claude が chrome-devtools で開いて確認した。

ただ、画面のスクショを見比べても、見た目はほとんど変わらなかった。8 つのボタンが下に並んだだけ。

メロディータイルを降らせる

「リズム本体、そうだよね。メロディーも降ってきて、Let It Be がもうちょっとこう、弾いた感じにしてほしい」と返した。

ここで設計が動いた。各コードの「中間ビート」に、そのコードの 3 度(C なら E、G なら B、Am なら C、F なら A)を自動配置する。コードタイルの下に小さなメロディタイルが追従して降ってくる絵になった。3 度が届かない音域のときは根音→5 度にフォールバックするロジックも入った。

ここまでで「コードだけ叩くゲーム」から「コードを叩きながらメロディーも拾うゲーム」に化けた。Claude がスクショを送ってきて、コード「C」の下に小さなタイルがちゃんと降っているのを確認できた。

「これ単音じゃないですか」

ところが Let It Be を流して気付いた。メロディタイルを叩くと「ポーン」と単音が 1 つだけ鳴る。音叉を叩いているような硬さで、ギターを弾いている感じがしない。

「メロディーがキーが C で、それを散らしてる感じなんですか?単音になってるじゃないですか。複音にできないですか。もうちょっとギターっぽい感じに」と注文を追加した。

返ってきた実装は、ギターの指弾きを再現する設計だった。

  • メロディ音(主役の 1 音)
  • その下の補助弦(オクターブ下、5 度下)
  • 直近で鳴ったコードの薄ストラム(5 音)

これを pluckSingle に時間オフセットを持たせて、数十ミリ秒ずつズラして重ねる。コード文脈があるときは 8 音、フリー演奏時は 3 音がスケジュールされる。Claude が内部状態を JS で抜き出して「8音スケジュール(メロディ1+補助2+コード5)」と報告してきて、リロードして弾いたら、ポーンが「ジャラン」に変わっていた。Let It Be の F→C→Dm→Bb が、ちゃんとギターを弾いているように聞こえた。

ローカル html を Vue に移植してデモに置く

ここまで来てから「インデックスページのテストデモのところに変換して入れといて」と頼んだ。せっかく形になったので、Downloads に置きっぱなしではなく、apps/web/app/pages/ から開けるようにしたかった。

vue-pages スキルが適用され、既存の stereo-test デモを参照しながら chord-rush.vue として書き直された。気を付けたのは 2 点だけ。

  • 自己完結デモなので Breadcrumb と TOC は省く
  • CSS は動的生成要素があるので .chord-rush-page で前置した非 scoped で書く

それと、カスタムコード入力欄でユーザー文字列が p.sup 要素に流れる箇所があった。innerHTML のままだと XSS の口になるので、DOM 構築に置き換えてもらった。デモとはいえ後から踏むのは自分なので、ここは黙って直してもらってよかった。

index.vue の「サウンド」セクションに新しいカードを追加して、dev サーバーで開いて確認。タイトル、コードボタン C/G/Am/F、メロディボタン 1〜8、Key: C (major) が描画され、おてほん再生でスコア 1180・7 コンボ。動いている。

最後に feat(chord-rush): コード進行+メロディのリズムゲームをデモに追加 でステージング+コミット。差分は chord-rush.vue 新規追加と、index.vue のカード追加分だけに絞れた。

学びメモ

  • 「ギターのコードだけ降ってくる画面」だと、頭の中でメロディーを補完できる経験者にしか通じない。自分が「何の曲を弾いているかわからない」と感じた瞬間が、メロディー追加の根拠になった。
  • 単音と複音の差は、譜面上は 1 音 vs 8 音だけ。けれど鳴らした瞬間「ポーン」が「ジャラン」に化けて、Let It Be がギターの音色に聞こえた。スペック表に出ない差分は、自分の耳でしか判定できない。
  • ローカル html のまま遊んでいると、明日には Downloads の山に埋もれて二度と開かない。Vue に移植してデモインデックスに置くと、ブラウザのブックマークから 2 クリックで戻ってこられる。「動くものを家に連れて帰る」工程までやって初めて、作ったことになる。
  • 自分が判断する係(「単音じゃ物足りない」「ギターっぽくない」と耳で拾う)、Claude が実装する係(複音スケジューラを設計して音を重ねる)、という分担が今日は綺麗に決まった。耳で違和感を拾えるかどうかが、AI に投げる仕事の入口になる。

明日やること

  • Let It Be 以外の曲(Yesterday、Stand By Me 等)でもメロディの 3 度自動配置が破綻していないか、自分の耳で 3 曲ぶん確認する
  • スマホで開いたときメロディボタンが小さすぎないか、タップ領域を 44px 以上に広げる必要があるか確認する
  • デモインデックスの「サウンド」カテゴリに何が並んでいるか棚卸しして、説明文の体裁を揃える