TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

【バイブコーディング】ギターの音ゲーを作る(ピアノロール)

前回、ギターの音ゲータブ譜の描画まで実装した。

今回は、ピアノロールを実装する。

ピアノロール

ピアノロールは、音符(ノート)を、縦軸を音階(12音階)、横軸を時間として表したものである。
縦軸はラベルの代わりに、ピアノ鍵盤を縦に表示することで、音階をわかりやすくしている。

ギターに特化した表現

ギターのスライド、ベンド(チョーキング)、ビブラートといった奏法があるため、これらをピアノロール上で音程の変化として表現する。

検討事項

鍵盤の描画

ピアノロールの鍵盤部分は、白鍵はオクターブを7等分して、黒鍵はオクターブを12等分して黒鍵の位置に描画する。
白鍵は、7等分するため、実際の1音は12等分の範囲なので、音の幅と鍵盤が示す幅が不一致になる。
これを、正確に指示しないとAIがコードに落とし込めない。
単純に、ピアノロールの鍵盤を描くように指示しても、上手くいかない。
以前に、VST3プラグインで鍵盤を描いたときは、どのように指示してもうまくいかず手でコーディングした。
GPT-5.3 Codexだとできるかと思って、まずは単純な指示で試したが、うまくいかなかった。
そこで、以前に作ったコードをサンプルプログラムとして与えることにした。

タブ譜とピアノロールの時間軸のずれ

タブ譜は、小節の始めの音に臨時記号を描けるだけの余白をあけている。
ピアノロールにこの余白があると不自然になるため、ピアノロールはタブ譜の音符の位置とは独立に、音価に応じて小節の幅を分割するように実装する。

奏法

上述した通り、ギターの奏法を音程の変化として表現する。
ベンド(チョーキング)で、どれくらいの速度で目標の音程に達するかは、タブ譜上の矢印の表現とは異なる。
音程の変化は、alphaTabのMIDI再生のコントロールの制御に合わせるようにした。

実装

以下のようなプロンプトで生成した。
何度か試行して、条件をブラッシュアップしている。

読み込んだ.gp5からMIDIを生成し、ピアノロールとしてノートを描画する処理をGp5TablatureフォルダにあるC++/WinRT(WinUI3)のプロジェクトに実装してください。
.gp5の読み込み、タブ譜の描画処理は実装済みです。

### 条件
- ピアノロールはタブ譜と横スクロールを共有する
- タブ譜の下側の領域を全て使う
- ギター(6弦)の場合C2からE6、ベース(4弦)の場合C1からG4を表示する
- ピアノロールの領域内で縦スクロールする(タブ譜は常に上側に表示)
- タブ譜とピアノロールの間には少し余白を設ける
- 可視領域のみを描画する(可視範囲に収まらない場合はピアノロールの領域を縦にスクロールする)
- 左端に固定で縦にしたピアノ鍵盤を描画する(左側に黒鍵。白鍵はオクターブを7等分する。黒鍵はオクターブを12等分して黒鍵の位置に描く。)
- Cの白鍵の内側右寄りの位置にオクターブの数字を描く。
- オクターブを12等分する水平線を描く。Cの音階の下側の水平線(白鍵のCの鍵盤の下端と同じ位置)は少し太くする。1音分の高さは固定で五線譜の五線の間隔と同じとする。
- タブ譜の小節と同じ幅で小節の区切りを縦線で表示する
- 小節の幅から音価に応じたノートの幅を計算する(五線譜は小節の頭にマージンがあるが、ピアノロールではマージンは不要。マージンなしで音価に応じたノートの幅を計算する。五線譜の音符位置と少しずれるが問題ない。)
- ベンドやビブラートなどの奏法によるMIDIのコントロール信号による音程変化も可視化する(ノートを連続的に音程変化させる)

### 参考
- samples/gp5_to_midi.cpp: .gp5からMIDIに変換するプログラム
- samples/controller.cpp: ピアノロールを描画する音声解析プログラム


奏法は対応できていなかったので、スクリーンキャプチャを与えながら、修正を繰り返した。

数十回ほど修正を繰り返し、以下のように、正しく表示できるようになった。

ベンド → ベンドリリース → スライド → ベンド → ビブラートのように奏法が続くケースは修正するのに苦労した。


まとめ

前回実装したギター音ゲータブ譜描画に続き、今回はMIDIを基にしたピアノロール表示を実装した。
ギター特有の奏法(ベンド・スライド・ビブラート)を可視化できるようになった。

次は、音声入力とオーディオクロック基準のスクロール処理を実装したい。