Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/OVRLipSyncMicInput.cs
2026-02-21 16:45:37 +08:00

251 lines
5.3 KiB
C#

using System;
using System.Diagnostics;
using System.Threading;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class OVRLipSyncMicInput : MonoBehaviour
{
public enum micActivation
{
HoldToSpeak = 0,
PushToSpeak = 1,
ConstantSpeak = 2
}
[Tooltip("Manual specification of Audio Source - by default will use any attached to the same object.")]
public AudioSource audioSource;
[Tooltip("Enable a keypress to toggle the microphone device selection GUI.")]
public bool enableMicSelectionGUI;
[Tooltip("Key to toggle the microphone selection GUI if enabled.")]
public KeyCode micSelectionGUIKey = KeyCode.M;
[Range(0f, 100f)]
[SerializeField]
[Tooltip("Microphone input volume control.")]
private float micInputVolume = 100f;
[Tooltip("Requested microphone input frequency")]
[SerializeField]
private int micFrequency = 48000;
[Tooltip("Microphone input control method. Hold To Speak and Push To Speak are driven with the Mic Activation Key.")]
public micActivation micControl = micActivation.ConstantSpeak;
[Tooltip("Key used to drive Hold To Speak and Push To Speak methods of microphone input control.")]
public KeyCode micActivationKey = KeyCode.Space;
[Tooltip("Will contain the string name of the selected microphone device - read only.")]
public string selectedDevice;
private bool micSelected;
private int minFreq;
private int maxFreq;
private bool focused = true;
private bool initialized;
public float MicFrequency
{
get
{
return micFrequency;
}
set
{
micFrequency = (int)Mathf.Clamp(value, 0f, 96000f);
}
}
private void Awake()
{
if (!audioSource)
{
audioSource = GetComponent<AudioSource>();
}
if ((bool)audioSource)
{
}
}
private void Start()
{
audioSource.loop = true;
audioSource.mute = false;
InitializeMicrophone();
}
private void InitializeMicrophone()
{
if (!initialized && Microphone.devices.Length != 0)
{
selectedDevice = Microphone.devices[0].ToString();
micSelected = true;
GetMicCaps();
initialized = true;
}
}
private void Update()
{
if (!focused)
{
if (Microphone.IsRecording(selectedDevice))
{
StopMicrophone();
}
return;
}
if (!Application.isPlaying)
{
StopMicrophone();
return;
}
if (!initialized)
{
InitializeMicrophone();
}
audioSource.volume = micInputVolume / 100f;
if (micControl == micActivation.HoldToSpeak)
{
if (Input.GetKey(micActivationKey))
{
if (!Microphone.IsRecording(selectedDevice))
{
StartMicrophone();
}
}
else if (Microphone.IsRecording(selectedDevice))
{
StopMicrophone();
}
}
if (micControl == micActivation.PushToSpeak && Input.GetKeyDown(micActivationKey))
{
if (Microphone.IsRecording(selectedDevice))
{
StopMicrophone();
}
else if (!Microphone.IsRecording(selectedDevice))
{
StartMicrophone();
}
}
if (micControl == micActivation.ConstantSpeak && !Microphone.IsRecording(selectedDevice))
{
StartMicrophone();
}
if (enableMicSelectionGUI && Input.GetKeyDown(micSelectionGUIKey))
{
micSelected = false;
}
}
private void OnApplicationFocus(bool focus)
{
focused = focus;
if (!focused)
{
StopMicrophone();
}
}
private void OnApplicationPause(bool pauseStatus)
{
focused = !pauseStatus;
if (!focused)
{
StopMicrophone();
}
}
private void OnDisable()
{
StopMicrophone();
}
private void OnGUI()
{
MicDeviceGUI(Screen.width / 2 - 150, Screen.height / 2 - 75, 300f, 50f, 10f, -300f);
}
public void MicDeviceGUI(float left, float top, float width, float height, float buttonSpaceTop, float buttonSpaceLeft)
{
if (Microphone.devices.Length < 1 || !enableMicSelectionGUI || micSelected)
{
return;
}
for (int i = 0; i < Microphone.devices.Length; i++)
{
if (GUI.Button(new Rect(left + (width + buttonSpaceLeft) * (float)i, top + (height + buttonSpaceTop) * (float)i, width, height), Microphone.devices[i].ToString()))
{
StopMicrophone();
selectedDevice = Microphone.devices[i].ToString();
micSelected = true;
GetMicCaps();
StartMicrophone();
}
}
}
public void GetMicCaps()
{
if (micSelected)
{
Microphone.GetDeviceCaps(selectedDevice, out minFreq, out maxFreq);
if (minFreq == 0 && maxFreq == 0)
{
UnityEngine.Debug.LogWarning("GetMicCaps warning:: min and max frequencies are 0");
minFreq = 44100;
maxFreq = 44100;
}
if (micFrequency > maxFreq)
{
micFrequency = maxFreq;
}
}
}
public void StartMicrophone()
{
if (micSelected)
{
audioSource.clip = Microphone.Start(selectedDevice, true, 1, micFrequency);
Stopwatch stopwatch = Stopwatch.StartNew();
while (Microphone.GetPosition(selectedDevice) <= 0 && stopwatch.Elapsed.TotalMilliseconds < 1000.0)
{
Thread.Sleep(50);
}
if (Microphone.GetPosition(selectedDevice) <= 0)
{
throw new Exception("Timeout initializing microphone " + selectedDevice);
}
audioSource.Play();
}
}
public void StopMicrophone()
{
if (micSelected)
{
if (audioSource != null && audioSource.clip != null && audioSource.clip.name == "Microphone")
{
audioSource.Stop();
}
OVRLipSyncContext component = GetComponent<OVRLipSyncContext>();
component.ResetContext();
Microphone.End(selectedDevice);
}
}
private float GetAveragedVolume()
{
return 0f;
}
}