ドリクラエミュ音声問題

 さてと箱エミュ(ドリクラエミュ)の問題改善。
 まだやってるのかよと言われそうだけどまだ問題があるんですよ、ええ(苦笑)。
 描画問題は一度キリを付けてはいるんですが、次は音楽再生の問題。
 実のところこれも当初からずっとずっと抱え続けている問題で。こちらは回避策があるから優先度は下がるけれどもいい加減何とかしたい。

 問題点は2つ。
  • xenia(エミュ)の最新ffmpeg版で音楽再生が乱れる、途切れる
  • 音が0.5秒ほどずれる
 前者は曲によってはきちんと再生出来る。例えば(たまたま試した中では) “カンパイLOVE” や “素直になれない” とかは最後まで問題なかったけれど、 “コイヲシテイマス” や “TimeTraveler” は速攻で音が切れて声だけになってしまって、ゆくゆくは声すらも途切れる。そりゃあ絶許案件ってものでしょうよ。戦争だろうがと(笑)。

 おかしな物があれば直したくなる、放置したまま先に進みたくないのはエンジニアの性分だと思います。

 でまぁ根本的にはエミュ実装の不具合なんだけども、ゲーム側がエミュに不都合な実装を踏んでしまっているという可能性も勿論あるので(描画の時のように)。前から音声スレッド周りは見た目気になる所はあったので少し掘り下げてみた訳ですが。

 ただまぁ結論から言うと、現状はエミュ側のビルドで何とかするしかなさげ。
  • ffmpeg版のデグレ問題が大きいので、旧libav版に差し戻して再ビルド
  • 音ズレはcanary experimentalの改修がかなり有効(こちら

 出来ればオリジナルビルドのままで動かしたかったけど当分は自前ビルドしかなさそう。
 後者はかなり有効なのでそのうち本家にプルリクされるんじゃあないかな(後述)。

 以下は細かい話ですが、

●ffmpeg版の音声途切れ
 前者のffmpeg版。これはエミュの実装で使用しているライブラリを刷新した新バージョンが盛大にデグレを起こしておりまして。昨年リリースされてからあれもおかしいこれもおかしいと声は上がっていて、MANY gamesに影響する修正もマージされたけど少なくともドリクラエミュに関しては効果無し。
 そもそもまだ思う所あるみたいな感じだし、それなら強引に差し替えを強行しないで欲しいというか。グラフィックみたいに複数形式の切り替え実装には出来ないものだったんだろうか。如何せんffmpegとlibavは喧嘩別れのライブラリで同じ名前を使ってるから難しかったのかも。
 そもそもxeniaは公式で「音声関係はやる気ないよ!」発言までされてしまっているので(苦笑)、それで渋々更新した版がむしろデグレという困った状態。簡単な物じゃあないのは勿論分かってますが実に残念な話。
(というか丁度自分が使い始めてすぐに切り替わったので、ちょっと触るのが遅かったらlibav版に気付かないまま現状を受け入れて、音もマトモに鳴らないならとそこまで入れ込まずに終わってしまっていたかもしれない(苦笑)。)

 差し替えたライブラリの問題なのか、それに合わせて刷新した音声制御の実装問題なのか。旧libav版では全く問題ないので、デグレである以上は変更後の何処かの不具合なんだけども。これに関してはかなりのゲームに影響してる筈だし、それこそ他のプロフェッショナルな方々も見てるだろうとは思う。その上で直らないんならと思って先にドリクラ側を当たってみているというのもありましたけどね。何が不味いのかを調べないと始まらないし。

 それでまぁ元々気になっていたドリクラ側の実装を追ってはみたんですよ。音声用に複数スレッドが立っているのでその辺りで不整合が発生しているんじゃないかと。
 スレッド制御を強引に弄くる無茶もやらかしてみて、それで音は再生されるけどちょっとおかしな問題は出てきたり。憶測の範疇でしかないけれども何となくSDKの仕様に合わせた実装みたいなのも感じられてはきて、まぁそれならそれでこのやり方以外にもありそうとは思うけども、ただ今の実装で丁度良く収まってはいるという感じ。
 スレッド間の排他制御なんかも入っていて、それがパフォーマンスに影響していないかというのも調査要因の一つではあったけども流石にそれはなさそう。
 ignore_thread_affinities というスレッド周りのオプションをオフにすると動作が悪化して、それに関係する部分も見えてはきたんだけども、ちょっと根本的に弄るにはアセンブラの後付けでは荷が重すぎるところ。そもそもデフォルトのオンでエミュとしては問題無く回るので無理する所でもなさげ。(アイマスはこれをオフにしないと駄目だという話なので、そういう特定問題の回避用。ああいうのは作りもピーキーだろうしなぁ多分。)

 でもって弄っている最中にふと気付いたのが、一部カラオケの再生が途切れるという重大問題の前に、まず「普段のループ曲の切れ目がおかしくなっている」と。それこそ先に挙げたloop handlingのissueかと思ったけれどもまるでちっとも改善せず。
 それに当初は複数スレッド間の関係性ばかり気にしていたけれど、このループ不具合はそもそもタイトル画面で1スレッドしか立っていない状態でも発生していた問題。つまり今まで調べていたことなんて全然関係ないじゃないかと(苦笑)。なくはないかもしれないけどやっぱり別にクリティカルな所ではないと。

 という訳で流石に諦めも入って、これまで通り旧libav版を差し戻しビルドしていく方向で。
 ただ特定ファイルをrevertするだけではなく関連ファイルのconflictなんかも入ってくるので、全容を把握している訳でもないし避けたかったんですけどね。


●音ズレ
 でもって、後は音ズレの問題。
 これは録画なら後からずらせばいいけれど、リアルタイムの再生でずれるのはやはり非常にガッカリしてしまう。僅か0.5秒でも全然タイミングなんて変わってしまう訳ですよ。
 だから、ずれてしまうなら最初からずらせばいいじゃない理論で、カラオケ開始時にモーション側にダミーウェイトでもぶっこんでやろうかと画策していたのですが。

 そこで丁度気付いたのがこのissueでのコメント。canary 版の max_queued_frames オプションが効果あるよと。デフォルト64から数値を下げるとラグが減る模様。
 これを試してみたらめっちゃ物凄い効果。もうこれで問題ないじゃん!という。

 まぁqueueの数を減らすという事なのでどういう影響があるのかはまだ読めないけれど。ただ今のところドリクラでは問題なく動いている感じ。
 値を減らせば減らすほど早く再生されるようで、事実上3が最速って事らしいけれど、それで音合わせをしてみたら何だか逆に早くなりすぎた?のか何なのか。比較対象がtubeに上がっている実機の録画なので、up主の方で別途調整されているとかもあるのかもしれない。何だか曲によってもずれ具合が違うという。だから自分の体感としてまぁこれでいいんじゃないですかという所で、ひとまず16くらいにして様子見。2のべき乗を選びたくなるのはエンジニアの習性ですね。

 但し、如何せんcanary版はパス関係の修正が正常にマージされていないのか、ドリクラのDLCを読ませるとログも吐かずに強制クラッシュしてしまうので使えません。(追記:多分このissue
 ソースコードは何処よ?と探したらexperimental版のここで。めっちゃホットな更新でした。
 出来たばかりの実験版ということでまだ本家のプルリクにも行っていないけれど、びっくりするくらいに有効だったのでその内行くのではなかろうかと。


 そんなこんなでしばらく自前修正ビルドで凌いでいる状態ですが、音ズレ問題が解決に向かったのは大収穫。