続き tsv に自主変換したc1
, c2
(チャージノーツ定義)、tc
(BPM変更定義)、ln
(小節ごとの拍数定義)を、文字列から配列オブジェクトに変換する小処理を先に作る。通常ノーツを展開した辞書型オブジェクトに対して、チャージノーツと BSS / MSS を追加する処理を次に作る。
小処理の動作確認でよさそうな楽曲を探していたが、変拍子、BPM変動、チャージノーツがほどよく揃った「Scandal」がすごい
https://textage.cc/score/28/scandal.html?DAB00=32~91-92
配列には最大 4 要素を持つ。[0]はレーン番号(1~7: 鍵盤、0: ターンテーブル)を表す。[1]はその小節における描画開始位置(小節の先頭を0、単位は 4 分音符 1 つを32とする)を表す。[2]はその小節における描画の長さを表す(省略時は30)。[3]はこのチャージノーツがこの小節内に収まるか、複数小節にまたがるかを表現する値を表し、0は「前の小節から継続、次の小節に継続」、1は「この小節から開始、次の小節に継続」、2は「前の小節から継続、この小節で終端」、3は「この小節で開始して終端する」、7は MSS(Multi Spin Scratch)のいずれかを取る。[3]の省略時は3が採用される。
チャージノーツは、開始にプッシュ判定、終了にリリース判定がある。譜面検索でリリース判定は対象外としてよいだろう。そのため、[0] が 1~7 の場合は、[3] が 1 または 3 の場合(= [3] の値と1
との AND 演算の結果が1
である場合)に、[1] の位置にノーツを追加する。
一方 BSS/MSS は、開始および終了に判定がある。どちらもノーツを追加するため、[0] が 0 の場合は、[3] が 1, 3 または 7 の場合(= [3] の値と1
との AND 演算の結果が1
である場合)に、[1] の位置にノーツを追加する。そして、[3] が 2, 3 または 7 の場合(= [3] の値と2
との AND 演算の結果が2
である場合)に、[1] + [2] の位置にノーツを追加する。
[2] が省略されたときは 30 として扱うのだが、4 分音符 1 つぶんの長さは 32 なので微ズレが発生するかもしれない。round(30 / 4) * 4
のように「32 分音符」にクォンタイズしようか? round()
の結果が次の小節の頭である 0 に相当する場合の判定も要りそう。
現行譜面で調べてみると、だいたい [2] も [3] も 16 の倍数で定義されててクォンタイズ不要だが、29 CastHour の ALTERNATOR (ANOTHER譜面) に
c1[82]=[[0,32,15,7],[0,47,16,7],[0,63,16,7],[0,79,16,7],[0,95,16,7],[0,111,15,7]];
とあり、実際には以下のように描画されている。
https://textage.cc/score/29/altnator.html?2AC00=16~82-83
参考に動画を見てみると、
https://www.youtube.com/watch?v=upth99YjAaE&t=107s
本家も微ズレしてた。クォンタイズやらないでおくことにしよう。