using System.Collections; using Convai.Scripts.Runtime.LoggerSystem; using UnityEngine; namespace Convai.Scripts.Runtime.Addons { public class MicrophoneInputChecker : MonoBehaviour { // Duration for microphone input check. private const float INPUT_CHECK_DURATION = 3f; // Microphone sensitivity, adjust as needed. private const float SENSITIVITY = 10f; // Threshold level to detect microphone issues. private const float THRESHOLD = 0.1f; // Reference to the TalkButtonDurationChecker script to check the talk button status. private TalkButtonDurationChecker _talkButtonDurationChecker; private void Awake() { // Find and assign the TalkButtonDurationChecker instance in the scene. _talkButtonDurationChecker = FindObjectOfType(); } /// /// Check if the microphone is working by analyzing the provided AudioClip. /// /// The audio clip to analyze. public void IsMicrophoneWorking(AudioClip audioClip) { // Stop any existing coroutines to ensure a clean start. StopAllCoroutines(); // Start the coroutine to check the microphone device. StartCoroutine(CheckMicrophoneDevice(audioClip)); } // Coroutine to check the microphone device after a specified duration. private IEnumerator CheckMicrophoneDevice(AudioClip audioClip) { // Check if the provided AudioClip is null. if (audioClip == null) { // Log an error and abort the microphone check. ConvaiLogger.Error("AudioClip is null!", ConvaiLogger.LogCategory.Character); yield break; } // Wait for the specified duration before analyzing microphone input. yield return new WaitForSeconds(INPUT_CHECK_DURATION); // If the talk button was released prematurely, abort the microphone check. if (_talkButtonDurationChecker.isTalkKeyReleasedEarly) yield break; // Calculate the range of audio samples to analyze based on the duration. int sampleStart = 0; int sampleEnd = (int)(INPUT_CHECK_DURATION * audioClip.frequency * audioClip.channels); // Initialize an array to store audio samples. float[] samples = new float[sampleEnd - sampleStart]; int samplesLength = samples.Length; // Attempt to retrieve audio data from the AudioClip. if (audioClip.GetData(samples, sampleStart) == false) { ConvaiLogger.Error("Failed to get audio data!", ConvaiLogger.LogCategory.Character); yield break; } // Initialize a variable to store the total absolute level of audio samples. float level = 0; // Calculate the total absolute level of audio samples. for (int i = 0; i < samplesLength; i++) level += Mathf.Abs(samples[i] * SENSITIVITY); // Normalize the calculated level by dividing it by the number of samples and then multiply by sensitivity. level = level / samplesLength * SENSITIVITY; // Check if the microphone level is below the threshold, indicating a potential issue. if (level < THRESHOLD) { ConvaiLogger.Warn("Microphone Issue Detected!", ConvaiLogger.LogCategory.Character); NotificationSystemHandler.Instance.NotificationRequest(NotificationType.MicrophoneIssue); } else { // Log that the microphone is working fine. ConvaiLogger.Info("Microphone is working fine.", ConvaiLogger.LogCategory.Character); } } } }