using System;
using UnityEngine;

namespace XVI.AniLipSync
{
	public class LowLatencyLipSyncContext : OVRLipSyncContextBase
	{
		private OVRLipSync.VariableData m_Variable
		{
			get
			{
				return GameMain.Instance.LipSyncMgr.Variable;
			}
		}

		public override void Init()
		{
			base.Init();
			this.m_MicInput = base.GetComponent<OVRLipSyncMicInput>();
			this.processBuffer = new float[OVRLipSync.BuffSize];
			this.microphoneBuffer = new float[OVRLipSync.SamplingRate * 10];
		}

		private void Update()
		{
			if (!this.audioSource.clip)
			{
				return;
			}
			int position = Microphone.GetPosition(this.m_MicInput.selectedDevice);
			if (position < 0 || this.head == position)
			{
				return;
			}
			this.audioSource.clip.GetData(this.microphoneBuffer, 0);
			while (LowLatencyLipSyncContext.GetDataLength(this.microphoneBuffer.Length, this.head, position) > this.processBuffer.Length)
			{
				int num = this.microphoneBuffer.Length - this.head;
				if (num < this.processBuffer.Length)
				{
					Array.Copy(this.microphoneBuffer, this.head, this.processBuffer, 0, num);
					Array.Copy(this.microphoneBuffer, 0, this.processBuffer, num, this.processBuffer.Length - num);
				}
				else
				{
					Array.Copy(this.microphoneBuffer, this.head, this.processBuffer, 0, this.processBuffer.Length);
				}
				float[] array = new float[this.processBuffer.Length];
				Array.Copy(this.processBuffer, array, array.Length);
				for (int i = 0; i < array.Length; i++)
				{
					array[i] *= this.m_Variable.MicSensitivity;
				}
				OVRLipSync.ProcessFrame(base.Context, array, OVRLipSync.Flags.None, base.Frame);
				this.head += this.processBuffer.Length;
				if (this.head > this.microphoneBuffer.Length)
				{
					this.head -= this.microphoneBuffer.Length;
				}
			}
		}

		public float GetMicVolume()
		{
			float num = 0f;
			foreach (float f in this.processBuffer)
			{
				num += Mathf.Abs(f);
			}
			return num / (float)this.processBuffer.Length;
		}

		private static int GetDataLength(int bufferLength, int head, int tail)
		{
			if (head < tail)
			{
				return tail - head;
			}
			return bufferLength - head + tail;
		}

		private AudioClip clip;

		private int head;

		private float[] processBuffer = new float[512];

		private float[] microphoneBuffer = new float[441000];

		private OVRLipSyncMicInput m_MicInput;
	}
}
