トマシープが学ぶ

Unity/VR/AR/デザイン好きのミーハー 記事内容は自分用のメモです

VRMアバターをマイク音量から口パクさせる【リップシンク】

最初OVRLipSyncを使って実装したけど、iOSリリース出来ないらしいので別の手段を使う。

bibinbaleo.hatenablog.com

bibinbaleo.hatenablog.com

VRMをマイク音量から口パク

こちらの記事のスクリプトを少し変えて実装しました。こちらのLive2Dキャラを口パクさせている。

qiita.com

こんな感じになった

using UnityEngine;
using VRM;

/// <summary>
/// 口パクを行うクラス
/// </summary>
public class SimpleLipSyncer : MonoBehaviour
{
    [SerializeFieldprivate AudioSource audioSource = null;

    [SerializeFieldprivate VRMBlendShapeProxy blendShapeProxy;

    float velocity = 0.0f;
    float currentVolume = 0.0f;

    [SerializeFieldprivate float Power = 50f;
    [SerializeFieldRange(0f1f)] private float Threshold = 0.1f;

    void Start()
    {
        // Audio Source の Audio Clip をマイク入力に設定
        // 引数は、デバイス名(null ならデフォルト)、ループ、何秒取るか、サンプリング周波数
        audioSource.clip = Microphone.Start(nulltrue144100);
        // マイクが Ready になるまで待機(一瞬)
        while (Microphone.GetPosition(null) <= 0) { }
        // 再生開始(録った先から再生、スピーカーから出力するとハウリングします)
        audioSource.Play();
        audioSource.loop = true;
    }
    private void LateUpdate()
    {
        float targetVolume = GetAveragedVolume() * Power;
        //Threshold以下だったらtargetVolumeを0にする
        targetVolume = targetVolume < Threshold ? 0 : targetVolume;
        //currentVolumeからtargetVolumeへ緩やかに変化
        currentVolume = Mathf.SmoothDamp(currentVolumetargetVolumeref velocity0.05f);

        if (blendShapeProxy == null)
        {
            Debug.LogError("blendShapeProxyが設定されていません");
            return;
        }
        
        //音量の値をBlendShapeのAの口に入れている
        blendShapeProxy.ImmediatelySetValue(BlendShapePreset.AMathf.Clamp01(currentVolume));
    }

    float GetAveragedVolume()
    {
        float[] data = new float[256];
        float a = 0;
        audioSource.GetOutputData(data0);
        foreach (float s in data)
        {
            a += Mathf.Abs(s);
        }
        return a / 255.0f;
    }
}

音量(currentVolume)の数値をBlendShapePreset.Aの数字にセットしている

AudioSourceの音をもとに口パクするなら(Micを使わないなら)Start関数は要らない

設定

VRMアバターからBlendShapeProxyセット。AudioSourceもセット

f:id:bibinbaleo:20200729160221p:plain

数値

PowerThresholdの数値は環境によって変わりそう。実行しながら調整した。

Powerは音量に対する口パクの大きさ。

普通にしゃべった時に口がマックスに開いて、小さい声だとちょっと開くみたいになれば理想。

Thresholdは雑音や小さな音をどれくらい許容するか。

 

21、0.8にした。

でも最初にやった時は50、0.1とかがよかったんだけどなー。何が変化したんだろう

結果

実行したらこんな感じ

f:id:bibinbaleo:20200729160210g:plain

(比較)OVRLipSyncだとこんなかんじ

f:id:bibinbaleo:20200717084038g:plain

最後に

SALSAとか使ったほうが良いのかな