using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Audio2LipScript : MonoBehaviour
{
[Tooltip("Which lip sync provider to use for viseme computation.")]
public OVRLipSync.ContextProviders provider = OVRLipSync.ContextProviders.Enhanced;
[Tooltip("Enable DSP offload on supported Android devices.")]
public bool enableAcceleration = true;
[SerializeField] private uint Context = 0;
[SerializeField] public float gain = 1.0f;
///
/// 音频
///
[SerializeField] private AudioSource m_AudioSource;
///
/// 模型的SkinnedMeshRenderer组件
///
[Header("设置带有口型的MeshRender")]
public SkinnedMeshRenderer meshRenderer;
///
/// blendshape权重倍数
///
public float blendWeightMultiplier = 100f;
///
/// 设置每个口型对应的blendershape的索引
///
[Header("设置元音对应的blendershape的索引值")]
public VisemeBlenderShapeIndexMap m_VisemeIndex;
///
/// 音素分析结果
///
private OVRLipSync.Frame frame = new OVRLipSync.Frame();
protected OVRLipSync.Frame Frame
{
get
{
return frame;
}
}
private void Awake()
{
m_AudioSource=this.GetComponent();
if (Context == 0)
{
if (OVRLipSync.CreateContext(ref Context, provider, 0, enableAcceleration)
!= OVRLipSync.Result.Success)
{
Debug.LogError("OVRLipSyncContextBase.Start ERROR: Could not create" +
" Phoneme context.");
return;
}
}
}
void OnAudioFilterRead(float[] data, int channels)
{
ProcessAudioSamplesRaw(data, channels);
}
///
/// Pass F32 PCM audio buffer to the lip sync module
///
/// Data.
/// Channels.
public void ProcessAudioSamplesRaw(float[] data, int channels)
{
// Send data into Phoneme context for processing (if context is not 0)
lock (this)
{
if (OVRLipSync.IsInitialized() != OVRLipSync.Result.Success)
{
return;
}
var frame = this.Frame;
OVRLipSync.ProcessFrame(Context, data, frame, channels == 2);
}
}
private void Update()
{
if (this.Frame != null)
{
SetBlenderShapes();
}
}
private void SetBlenderShapes()
{
for (int i = 0; i < this.Frame.Visemes.Length; i++)
{
string _name = ((OVRLipSync.Viseme)i).ToString();
int blendShapeIndex = GetBlenderShapeIndexByName(_name);
int blendWeight = (int)(blendWeightMultiplier * this.Frame.Visemes[i]);
if (blendShapeIndex == 999)
continue;
meshRenderer.SetBlendShapeWeight(blendShapeIndex, blendWeight);
}
}
///
/// 简单判断下,返回a i u e o 的索引
///
///
///
private int GetBlenderShapeIndexByName(string _name)
{
if (_name == "sil")
{
return 999;
}
if (_name == "aa")
{
return m_VisemeIndex.A;
}
if (_name == "ih")
{
return m_VisemeIndex.I;
}
if (_name == "E")
{
return m_VisemeIndex.E;
}
if (_name == "oh")
{
return m_VisemeIndex.O;
}
return m_VisemeIndex.U;
}
[System.Serializable]
public class VisemeBlenderShapeIndexMap
{
public int A;
public int I;
public int U;
public int E;
public int O;
}
}