|
|
- /************************************************************************************
- Filename : OVRLipSyncMicInput.cs
- Content : Interface to microphone input
- Created : May 12, 2015
- Copyright : Copyright Facebook Technologies, LLC and its affiliates.
- All rights reserved.
-
- Licensed under the Oculus Audio SDK License Version 3.3 (the "License");
- you may not use the Oculus Audio SDK except in compliance with the License,
- which is provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
-
- You may obtain a copy of the License at
-
- https://developer.oculus.com/licenses/audio-3.3/
-
- Unless required by applicable law or agreed to in writing, the Oculus Audio SDK
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ************************************************************************************/
-
- using System;
- using UnityEngine;
- using System.Diagnostics;
- using Debug = UnityEngine.Debug;
- using System.Threading;
-
- [RequireComponent(typeof(AudioSource))]
-
- public class OVRLipSyncMicInput : MonoBehaviour
- {
- public enum micActivation
- {
- HoldToSpeak,
- PushToSpeak,
- ConstantSpeak
- }
-
- // PUBLIC MEMBERS
- [Tooltip("Manual specification of Audio Source - " +
- "by default will use any attached to the same object.")]
- public AudioSource audioSource = null;
-
-
- [Tooltip("Enable a keypress to toggle the microphone device selection GUI.")]
- public bool enableMicSelectionGUI = false;
- [Tooltip("Key to toggle the microphone selection GUI if enabled.")]
- public KeyCode micSelectionGUIKey = KeyCode.M;
-
- [SerializeField]
- [Range(0.0f, 100.0f)]
- [Tooltip("Microphone input volume control.")]
- private float micInputVolume = 100;
-
- [SerializeField]
- [Tooltip("Requested microphone input frequency")]
- private int micFrequency = 48000;
- public float MicFrequency
- {
- get { return micFrequency; }
- set { micFrequency = (int)Mathf.Clamp((float)value, 0, 96000); }
- }
-
- [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 MEMBERS
- private bool micSelected = false;
- private int minFreq, maxFreq;
- private bool focused = true;
- private bool initialized = false;
-
- //----------------------------------------------------
- // MONOBEHAVIOUR OVERRIDE FUNCTIONS
- //----------------------------------------------------
-
- /// <summary>
- /// Awake this instance.
- /// </summary>
- void Awake()
- {
- // First thing to do, cache the unity audio source (can be managed by the
- // user if audio source can change)
- if (!audioSource) audioSource = GetComponent<AudioSource>();
- if (!audioSource) return; // this should never happen
- }
-
- /// <summary>
- /// Start this instance.
- /// </summary>
- void Start()
- {
- audioSource.loop = true; // Set the AudioClip to loop
- audioSource.mute = false;
-
- InitializeMicrophone();
- }
-
- /// <summary>
- /// Initializes the microphone.
- /// </summary>
- private void InitializeMicrophone()
- {
- if (initialized)
- {
- return;
- }
- if (Microphone.devices.Length == 0)
- {
- return;
- }
- selectedDevice = Microphone.devices[0].ToString();
- micSelected = true;
- GetMicCaps();
- initialized = true;
- }
-
-
- /// <summary>
- /// Update this instance.
- /// </summary>
- void Update()
- {
- if (!focused)
- {
- if (Microphone.IsRecording(selectedDevice))
- {
- StopMicrophone();
- }
- return;
- }
-
- if (!Application.isPlaying)
- {
- StopMicrophone();
- return;
- }
-
- // Lazy Microphone initialization (needed on Android)
- if (!initialized)
- {
- InitializeMicrophone();
- }
-
- audioSource.volume = (micInputVolume / 100);
-
- //Hold To Speak
- if (micControl == micActivation.HoldToSpeak)
- {
- if (Input.GetKey(micActivationKey))
- {
- if (!Microphone.IsRecording(selectedDevice))
- {
- StartMicrophone();
- }
- }
- else
- {
- if (Microphone.IsRecording(selectedDevice))
- {
- StopMicrophone();
- }
- }
- }
-
- //Push To Talk
- if (micControl == micActivation.PushToSpeak)
- {
- if (Input.GetKeyDown(micActivationKey))
- {
- if (Microphone.IsRecording(selectedDevice))
- {
- StopMicrophone();
- }
- else if (!Microphone.IsRecording(selectedDevice))
- {
- StartMicrophone();
- }
- }
- }
-
- //Constant Speak
- if (micControl == micActivation.ConstantSpeak)
- {
- if (!Microphone.IsRecording(selectedDevice))
- {
- StartMicrophone();
- }
- }
-
-
- //Mic Selected = False
- if (enableMicSelectionGUI)
- {
- if (Input.GetKeyDown(micSelectionGUIKey))
- {
- micSelected = false;
- }
- }
- }
-
-
- /// <summary>
- /// Raises the application focus event.
- /// </summary>
- /// <param name="focus">If set to <c>true</c>: focused.</param>
- void OnApplicationFocus(bool focus)
- {
- focused = focus;
-
- if (!focused)
- StopMicrophone();
- }
-
- /// <summary>
- /// Raises the application pause event.
- /// </summary>
- /// <param name="pauseStatus">If set to <c>true</c>: paused.</param>
- void OnApplicationPause(bool pauseStatus)
- {
- focused = !pauseStatus;
-
- if (!focused)
- StopMicrophone();
- }
-
- void OnDisable()
- {
- StopMicrophone();
- }
-
- /// <summary>
- /// Raises the GU event.
- /// </summary>
- void OnGUI()
- {
- MicDeviceGUI((Screen.width / 2) - 150, (Screen.height / 2) - 75, 300, 50, 10, -300);
- }
-
- //----------------------------------------------------
- // PUBLIC FUNCTIONS
- //----------------------------------------------------
-
- /// <summary>
- /// Mics the device GU.
- /// </summary>
- /// <param name="left">Left.</param>
- /// <param name="top">Top.</param>
- /// <param name="width">Width.</param>
- /// <param name="height">Height.</param>
- /// <param name="buttonSpaceTop">Button space top.</param>
- /// <param name="buttonSpaceLeft">Button space left.</param>
- public void MicDeviceGUI(
- float left,
- float top,
- float width,
- float height,
- float buttonSpaceTop,
- float buttonSpaceLeft)
- {
- //If there is more than one device, choose one.
- if (Microphone.devices.Length >= 1 && enableMicSelectionGUI == true && micSelected == false)
- {
- for (int i = 0; i < Microphone.devices.Length; ++i)
- {
- if (GUI.Button(new Rect(left + ((width + buttonSpaceLeft) * i),
- top + ((height + buttonSpaceTop) * i), width, height),
- Microphone.devices[i].ToString()))
- {
- StopMicrophone();
- selectedDevice = Microphone.devices[i].ToString();
- micSelected = true;
- GetMicCaps();
- StartMicrophone();
- }
- }
- }
- }
-
- /// <summary>
- /// Gets the mic caps.
- /// </summary>
- public void GetMicCaps()
- {
- if (micSelected == false) return;
-
- //Gets the frequency of the device
- Microphone.GetDeviceCaps(selectedDevice, out minFreq, out maxFreq);
-
- if (minFreq == 0 && maxFreq == 0)
- {
- Debug.LogWarning("GetMicCaps warning:: min and max frequencies are 0");
- minFreq = 44100;
- maxFreq = 44100;
- }
-
- if (micFrequency > maxFreq)
- micFrequency = maxFreq;
- }
-
- /// <summary>
- /// Starts the microphone.
- /// </summary>
- public void StartMicrophone()
- {
- if (micSelected == false) return;
-
- //Starts recording
- audioSource.clip = Microphone.Start(selectedDevice, true, 1, micFrequency);
-
- Stopwatch timer = Stopwatch.StartNew();
-
- // Wait until the recording has started
- while (!(Microphone.GetPosition(selectedDevice) > 0) && timer.Elapsed.TotalMilliseconds < 1000) {
- Thread.Sleep(50);
- }
-
- if (Microphone.GetPosition(selectedDevice) <= 0)
- {
- throw new Exception("Timeout initializing microphone " + selectedDevice);
- }
- // Play the audio source
- audioSource.Play();
- }
-
- /// <summary>
- /// Stops the microphone.
- /// </summary>
- public void StopMicrophone()
- {
- if (micSelected == false) return;
-
- // Overriden with a clip to play? Don't stop the audio source
- if ((audioSource != null) &&
- (audioSource.clip != null) &&
- (audioSource.clip.name == "Microphone"))
- {
- audioSource.Stop();
- }
-
- // Reset to stop mouth movement
- OVRLipSyncContext context = GetComponent<OVRLipSyncContext>();
- context.ResetContext();
-
- Microphone.End(selectedDevice);
- }
-
-
- //----------------------------------------------------
- // PRIVATE FUNCTIONS
- //----------------------------------------------------
-
- /// <summary>
- /// Gets the averaged volume.
- /// </summary>
- /// <returns>The averaged volume.</returns>
- float GetAveragedVolume()
- {
- // We will use the SR to get average volume
- // return OVRSpeechRec.GetAverageVolume();
- return 0.0f;
- }
- }
|