見出し画像

Topaz Chatを使用する際の音と動きの同期について

こんにちは。
今回の記事は、VRChatでTopazChatを利用して音楽の演奏、及びダンス等のパフォーマンスをする人向けの内容です。

普段VRCでパフォーマーとして活動している方々には当たり前の内容も多いかと思いますが、知っている部分は読み飛ばしてください。
また、こちらの記事では、それぞれの具体的な操作方法の解説等には一切触れず、あくまでノウハウの共有と、技術的ヒントの提供にとどめます。

もし、操作方法の解説記事について必要性を感じる方がいらっしゃいましたら、どうかご自身で執筆をしていただけますと助かります。


VRパフォーマー勢の共通の悩み…「音と動きが合わない…!!」

VRCでパフォーマンスをする方が一度は直面する問題として、「TopazChatから配信している音とアバターの動きのタイミングが合わない」というものがあります。

恐らくほとんどの場合、動きに対して音が遅れることとなり、またそのずれは時間経過とともに増大していくのではないかと思います。

まずは、なぜそういったズレが発生するのか、その原因と傾向について簡単に解説します。

ズレの原因は音の処理の遅延?

実は、TopazChatで配信する場合、配信ソフトやワールドの設定を適切に設定しないといくつかの箇所で遅延が発生します。
また、仮に適切に設定できたとしても、適時対策を講じないと段々と音声の遅れが増加していきます。

それぞれ遅延が発生する箇所について、簡単に紹介します。

①オーディオインターフェースのレイテンシー(遅延)

オーディオインターフェースに音声を入力してから、実際に信号として変換され配信されるまでに遅延が発生します。これを、通常音楽を制作してる人たちの間では「レイテンシ」等と呼びます。(英語で遅延といってるだけですが)

このレイテンシは、オーディオインターフェースの設定のサンプリング・バッファの数値を調整すれば減らすことが出来ますが、一方この数値を減らすとCPUの負荷が加速度的に増加していきます。場合によってはVRCがカクカクになったり、音がぷつぷつ途切れたりします。
個人的な体感ですが、マシンスペックにもよるものの64sampleまで詰められかなりいい方ではないかと思っています。(ちなみににこぱは普段512sampleでやってます。PCが弱弱なので……)

②OBSのエンコード時に発生する遅延

TopazChatに配信を送る際にOBSを利用している方も多いと思いますが、未検証な部分も多いものの、OBSで配信を行うと遅延が発生するようです。
以下は推測も多分に混ざる考察のため、もしより正確な知見をお持ちの方はご指摘いただきたいと思います。

OBSはストリームを配信する際、OBS内部で音と映像を合わせて一つのデータにする「エンコード」という処理をはさむのですが、どうやらここで遅延が発生しているようです。(後述しますが、このエンコードをはさまない配信方法では遅延が少ない様子)
この点については、OBS内にエンコードにCPUの処理の優先度をどの程度振り分けるかの設定があり、その設定やその他各データのビットレート、あるいはマシンスペックによっても遅延の程度は変わってくると思われます。

③ワールドのTopazChatPlayerの設定による遅延

通常ここが問題になることはないと思うのですが、unity上でワールドにTopazChatを設定する際、パラメータの一つに「Low Latency」という項目があります。
ここがオフになってしまっていると遅延が大きくなります。

④配信の時間経過による遅延

TopazChatにてインスタンスに配信を開始すると、そこから時間経過によって徐々に遅延が増加していきます。
詳しい原因についてはにこぱがエンジニアではないため解説が難しいのですが、恐らく処理が間に合わなかったストリームのデータがだんだんキャッシュされていくとか、そういった理由であると思われます。

この遅延は、各ユーザーがワールド内でリシンクをかけることで解消します。そのため、対処法を知っていればある程度対策が可能です。こちらについても後述します。

さて、以上がTopazChat使用時における遅延の主な原因です。
続いて、現状ある程度コンバットプルーフがとれている対処法を中心に、さらに「なぜできているかわからないけど効果がある」といった裏技的手法についても紹介します。

純正TopazChatStreamer+グローバルシンク連打方式

以下の二つの手法を組み合わせれば、ほぼアバターの動きと音のタイミングを合わせられることが、にこぱ自身の実地での検証にて判明しています。ただし、この検証時の演者はにこぱ自身ではないため、オーディオインターフェースの状況等については、本稿の考察では考慮しません。

①純正TopazChatStreamerの使用

TopazChatの制作者のよしたかさんより、ToazChatの配信のみに利用が可能な、簡便で軽量な配信アプリケーションが配布されています。
こちらはStreamKeyの設定とデバイス選択だけが可能な、非常にシンプルな内容のアプリです。

このアプリについては、OBSのように映像を配信する機能がないため、恐らく内部処理として映像にエンコードする過程がないのではないかと思っています(リバースエンジニアリングしたわけではないのであくまで予想ですが)
ただ、原因は不明なものの、実際このアプリ経由で音声を配信すると、少なくとも配信開始時点においてはアバターの動きと音がかなり正確に合います。

しかし、これだけでは前述の通り、時間経過によって遅延が徐々に発生していってしまいます。
そこで、以下の方法で対策します。

②グローバルシンク連打

グローバルシンクは、インスタンスにいる全ユーザーに対し強制的にリシンクをかけさせる操作です。

連打と大げさな書き方をしてしまいましたが、実際の運用は、曲間、出来れば次の曲が始まる直前にグローバルシンクをかけます。
それを毎曲間で行うことで、多少の揺らぎは発生してしまうもののライブを通して安定してアバターの動きと音を合わせることが出来ます。


ただし、グローバルシンク自体は各ユーザーにそれなりに負荷をかけるようで、特に大人数がいるインスタンスでは注意が必要です。(ワールド負荷の考慮など)
また、以下は未検証ではありますが、ライブが長時間になるとアバターの動きが不安定になる可能性があります。
というのも、インスタンスに誰かがジョインしてきたときや、またユーザーがアバターを変更するたびにアバターの読み込みが発生しますが、この読み込みの度にアバターの動きの表示が徐々に不安定になっていきます。
したがって、インスタンスが長時間になり、その間人の入れ替え等で読み込みがたくさん発生した場合、動きの表示に問題が出る可能性があります。
こちらは各ユーザーがリジョインすることで解消されます。

わき道にそれましたが、上記二つの手法を併用することでライブ中の音と動きはほぼぴったりタイミングが合います。

続いて、以下は未確定要素が多いものの実際に有効なことが確認されている手法です。

OBSマイナスオフセット

OBSはオーディオソースの詳細の画面で、ソースごとにオフセット(意図的な遅延)を設定することができます。こちらはms単位で設定することが可能です。
ここには通常正の値を設定するのですが、ここに負の値(-の値)を設定すると、なぜか実際にその値がストリームに反映されます。つまり、音が通常より早く会場に届きます。(OBS、お前時空ゆがめることができるんか……!)

ちなみに、このテクニックを発見したのは、ダンサーで3Dモデラーののりおさんなのですが、のりおさんはこの数値を-900msに設定しているそうです。ですが、その数値がどの程度実際に反映されているかは不明です。
この手法については、のりおさんのほかにも上手く動作したという報告があり、恐らく実際に動作します。

ただし、原理が全く分からないため、OBSのバージョンやその他条件によって動作しない可能性があります。

一応推測としては、OBSは明示しないだけで内部にバッファを持っててそれを切り詰めてるとか、あるいはエンコードの際の音声のタイミングを繰り上げているとかいろいろ考えられるのですが、実際のところは全く分かりません。

ですので、実際にこちらの手法を利用する際はご自身で検証の上でご利用ください。
また、こちらの現象について解説していただける方がいらっしゃいましたら、ご教示いただけますと大変に助かります。

ここまでは生演奏の際の音と動きのタイミングを合わせる手法について解説しました。
続いては、ダンスなど既存の音源を使用してパフォーマンスをする場合の各手法について解説します。
現状にこぱが把握している範囲では2つの手法があります。

①時差ストリーム方式

こちらはVRP Dance Studioのはりもくさんが編み出した手法で、動きと音のタイミングが合わないなら、動きの基準となるパフォーマーが聞く音のタイミングをずらしてしまえばいいのでは?という手法です。

パフォーマーの動きが観客に届くまでの流れとしては、音源から音が出る→それがパフォーマーに届く→それを受けてパフォーマーが体を動かす→それが観客に届くという流れなのですが、例えばTopazChatでワールドから流れる音を聞いてパフォーマーがパフォーマンスをすると、パフォーマーと観客にほぼ同時に音が届く上に、さらにそこからパフォーマーの動きが観客に届くまでの時間が必要なので、当然音と動きのタイミングは合いません。

そこで、パフォーマー自身が音を配信したり、また、パフォーマーが複数人いる場合は、パフォーマー同士がSyncroomで同じ部屋に入り、なるべく音のラグを減らす等の工夫が必要になります。
しかし、Syncroomでパフォーマー同士の動きのタイミングが揃ったとしても、その後観客に動きが届く段階では、よほど運よく諸条件がそろわないと音と動きのタイミングはそろいません。

そこでこの時差ストリーム方式では、パフォーマーとは別に音源の配信担当を置き、パフォーマーに流す音声と会場に流す音声にタイミングの差をつけ、最終的に観客が見たときにタイミングが合うように調整します。

この際、ルーティングとしては会場に流す音はOBS経由でTopazChatへ、パフォーマーへ送る音はSyncroomその他の方法で送ります。 (ちらっと話を聞いた限りでは、パフォーマーへの音送りにDiscordを利用した事例もあるとか。力技……!!)
このあたりの具体的なDAW上のルーティングは別記事にて解説できればと考えています。

ただ、こちらの手法を利用した場合だと、パフォーマーごとに発生するネットワークその他の要因による遅延の差に対応することができません。

続いて紹介する手法では、事前にyoutube等に音源を用意することができればかなりの精度ですべてのパフォーマーの音と動きのタイミングを合わせることが可能です。

②Iwasync音声オフセット方式

こちらも前述のVRP Dance Studioで実際に使用実績のある手法です。

VRCを普段遊んでいるユーザーであれば、恐らく一度は目にしたり使ったことがあるであろうIwasync Video Playerですが、このプレーヤーにはVRC内の設定をよく見ると動画の音声に対してオフセットをかけることのできる設定項目があります。
この項目が、マイナスの値も設定可能で、さらにユーザーごとにローカルで動作するため、これをうまく利用すれば観客から見たときにある程度は音と動きのタイミングを合わせることができます。

具体的な運用としては、事前にタイミング補正の基準となるユーザーを決め、そのユーザーから見て各パフォーマーの音と動きのタイミングが合うように各パフォーマーがオフセットの値を調整します。
この手法は事前の準備に時間がかかりますが、一方適切な値を設定できればある程度は観客から見たときに音と動きのタイミングが合い、さらにパフォーマーごとの環境要因にも対処が可能です。

しかしながら、この手法にも欠点はあります。それは、誰を基準にするかよって観客への見え方がだいぶ変わってしまう点です。
というのも、VRCにおいては音や動きのすべてがインターネット経由で相手に伝わりますが、ユーザーそれぞれのネットワーク環境、さらにはユーザー間の物理的な距離等によっても音や動きの伝わる速さが変わってきます。

ですので、最初に動きと音を合わせる際に誰を基準にするかが非常に重要になってきます。
極力、平均的な環境のユーザーを選ぶ必要があります。

ここまでは、既存の知られたツールや手法を使って音と動きのタイミングを合わせる手法について簡単に紹介しました。

つづいて、現在検証はできていないものの、遅延の低減に有効なのではないかと思われる手法について紹介します。
以下の手法については、理論上は遅延の低減に効果はあると思われますが、実機等での検証が一切できていません。

AppleシリコンMacをDAW・配信マシンに

発表当初はDAWやプラグインの対応が一向に進まず、音楽制作に関わる人からはあまり評判がよくなかったAppleシリコンですが、ここ最近はとある点で注目を集めています。

というのも、前述のオーディオインターフェースのバッファについて通常IntelやAMDのCPUでは値を大きくした方が安定するのですが、一方Appleシリコンではバッファの値は小さい方が安定するそうです。
こちらについては、Ableton Live公式からもアナウンスがありましたので、詳しくはそちらのドキュメントもご確認ください。

バッファ値が小さくても安定して動作するということは、当然前述のレイテンシが小さくなるということです。
各種SNS等の情報を見る限りでは、内部のサウンドデバイスで、DAWで数十トラックの重い音源を鳴らしても32sampleでもサクサク動くそうです。
とはいえ、オーディオインターフェースとの相性や、MacでのSyncroomやOBSの動作状況にもよって変わってくるため、もし検証可能な環境をお持ちの方がいらっしゃいましたら、検証してみていただけますと幸いです


以上駆け足ではありますが、VRCにおける音と動きのタイミングの合わせ方について解説しました。この記事が何かの一助になれば幸いです。


この記事が気に入ったらサポートをしてみませんか?