00 / OVERVIEW
この作品について
僕が制作しているAI VTuber「Mira」です。音声での会話、3Dキャラクターの表情と身体動作、ゲーム内の行動をつなぐために、Windows上で動くコントローラーを作っています。現在は開発中・未公開です。
会話、声質変換、モーション生成には既存のモデルや基盤を使っています。僕が実装しているのは、それらをつなぎ、音声が途切れたり、返事より遅れて古い動作が届いたりする問題を扱う部分です。声と身体が同じ会話に参加しているように見せることを目指しています。
聞く・考える・動くを、ひとつの体験へ。
声と演技を並行して動かし、会話のタイミングを揃えています。
口の動きは実際の再生音声から推定。古い動作を捨て、声と演技のずれを抑える。
01 / DESIGN NOTES
一つの発話から、声と演技を動かす
Discord参加者の音声を混ぜて会話システムへ渡し、返ってきた音声をRVCでMiraの声に変換してDiscordへ送ります。RVCは音声の声質を変えるために使っています。字幕かローカルのWhisperによる認識結果から発話イベントを作り、演技やゲーム内の行動にも渡します。
演技の判断にはOllamaを使います。感情、仕草、視線、姿勢、強度、英語の動作プロンプトを決められた形式で受け取り、表情の選択やDiPによる全身モーション生成へつなげます。声と動きが別々の話をしないように、一つの発話を共通の起点にしています。
02 / DESIGN NOTES
不規則に届く音声を、一定の間隔で送る
音声変換の結果はまとまって届くことがありますが、Discordには一定の間隔で送り続ける必要があります。その差を埋めるため、再生前に少し蓄えるプリバッファと、途切れた後に蓄え直す再バッファを用意しています。短い欠落は減衰する音で補い、音声が溜まりすぎたら古い区間を捨てます。
無音も時間として残し、再バッファ中に変換前のマイク音声へ切り替わらないようにしています。また、ストリームが有効でも音声コールバックが止まっている場合は再接続を試みます。同じマイクを複数の経路で開かないように管理する処理も入れました。
届き方は不規則。聞こえ方はなめらかに。
03 / DESIGN NOTES
字幕の更新と、新しい指示を区別する
認識途中の字幕は何度も書き換わります。更新のたびに演技を生成しないよう、文字列が安定するまで待ってから推論へ渡します。字幕とWhisperが同じ発話を拾った場合は重複を除きますが、後から同じ指示をもう一度話した場合は、新しい発話として受け付けます。
明示的な動作指示は、自動の演技より優先します。受付後の一定時間は自動モーションで上書きせず、緊急の指示では再生待ちのフレームを捨てます。リクエストIDで結果を照合し、遅れて届いた過去の推論や動作も除外します。今の会話に、前の指示が割り込まないようにするためです。
04 / DESIGN NOTES
短い動作をつなぎ、転送の負荷を抑える
モーション生成のワーカーを常駐させ、前回の生成状態を次へ引き継ぎます。クリップの境界は複数フレームで補間し、生成のたびにニュートラル姿勢へ戻らないようにしています。必要なリセット時だけ導入フレームを挟みます。
生成した22関節の座標はMIDIでVRChat側へ送ります。生成と送信の周期を分け、送信は3フレームに1回にして、通信量と受信イベントの負荷を抑えています。座標の量子化と受信側の補間も使うため、動きがどう見えるかは実機に合わせて調整する必要があります。
動きの生成と転送を、別の時計で。
05 / DESIGN NOTES
再生される声から、口の形を求める
口パクは字幕の時刻だけに合わせず、実際の音声を分析して動かします。LPC分析で音声の特徴を取り出し、日本語の五母音を簡易的に推定します。値をなめらかにし、境界付近で口形が細かく切り替わらないようにする処理と、第二候補を少し混ぜる処理も入れています。
表情は、最初に決めた感情から小さな変化や仕草を展開し、毎回推論を追加せずに演技を続けます。ゲームとの連携では、セッションの開始、状態確認、停止、結果の回収を管理しています。会話・声・身体・行動で異なる時間の進み方を揃えることが、この開発で取り組んでいる課題です。
REFERENCE
関連リンク・公開情報
開発中の作品です。公開パッケージはありません。
