読者です 読者をやめる 読者になる 読者になる

BMSプレイヤー開発 for macOS: BMSパーサー編

開発近況

harpこと BMSプレイヤーfor macOS の開発ですが,忙しさを言い訳にしてしばらく手が止まっていました。 最近ようやく以前のようにモチベーションと時間を取り戻してきたので少しづつ進めています。 今はBMSパーサーを書いているところで,BMSの仕様のおさらいと,なにを取捨するのかをキッチリ決めることから始めました。

BMSの仕様は基本的にLR2に準ずる

BMSの仕様をしらべていくと,ものすごく詳細に歴史的経緯を踏まえた仕様を解説しているページを発見しました。

BMS command memo (JP)

このサイトを信じてLR2が実装しているBMS上の仕様をひとまずは模倣していくところから始めています。 というのもLR2がだいぶメジャーであり,(想像ですが)これを基準に譜面を作成されることも多いだろうし,このLR2の挙動を再現できればほとんどの譜面がサポートできるのではないかと思っているからです。

実装上簡単に追従できそうなものや,逆にこれ要らないんじゃない?というものは一部省いたりしています。

とにかく仕様が膨大で複雑なのでDone is better than perfectな精神で進めていくつもりです。

サポートする仕様はgitのwikiにまとめました。

サポートするBMS仕様 · gomachan7/harp Wiki · GitHub

実装メモ

仕様を眺めるとコマンドの意味的な分類と記述形式が Control flow, Header, Channel message の三種類に別れているので,それぞれこの優先度で単独で1行ごとにパースを試みる処理にかけて,正規表現で引っかかればパース成功として読み込む行を進めるという実装になりそう。

BPMの変更仕様がチャンネルメッセージに直接値を書く チャンネル3 と, ヘッダセクションで定義した BPM値を読みにいく チャンネル8 2つあるのがややこしい。ややこしいだけじゃなくて,内部的にこいつらをマージするのが結構面倒で泥臭かったりします。

あと気をつける点は チャンネル1 の音声再生命令は,同じ小節に命令が複数行に別れて複数定義されていても,マージせずに別物として読んでおく必要があります。普通のノートやその他チャンネルとはちょっとだけ扱い方が違うので注意しないと,なんで音が再生されないだ?と当てもなくデバッグし続けるはめになります(経験済み)

進捗共有

Done 譜面の読み込み,自動再生まで完了。

懸念 oggがデフォルトで読み込めないため,自前でデコードする処理を書いてあげるか事前にない場合はwavにでも変換してあげるプロセスを挟んであげる必要があります。 また,音声再生関連で一番簡単なAPI,AVFoundationのAVAudioPlayerだとだいぶ遅延が生じてしまう問題があるのでCoreAudioの資料を読み進めてどうすればいいのか考え中です。