Scripts/Runtime/VoiceService.cs (103 lines of code) (raw):

/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the license found in the * LICENSE file in the root directory of this source tree. */ using System; using Facebook.WitAi.Configuration; using Facebook.WitAi.Data.Intents; using Facebook.WitAi.Events; using Facebook.WitAi.Interfaces; using Facebook.WitAi.Lib; using UnityEngine; namespace Facebook.WitAi { public abstract class VoiceService : MonoBehaviour, IVoiceService { [Tooltip("Events that will fire before, during and after an activation")] [SerializeField] public VoiceEvents events = new VoiceEvents(); /// <summary> /// Returns true if this voice service is currently active and listening with the mic /// </summary> public abstract bool Active { get; } /// <summary> /// Returns true if the service is actively communicating with Wit.ai during an Activation. The mic may or may not still be active while this is true. /// </summary> public abstract bool IsRequestActive { get; } /// <summary> /// Gets/Sets a custom transcription provider. This can be used to replace any built in asr /// with an on device model or other provided source /// </summary> public abstract ITranscriptionProvider TranscriptionProvider { get; set; } /// <summary> /// Returns true if this voice service is currently reading data from the microphone /// </summary> public abstract bool MicActive { get; } public VoiceEvents VoiceEvents { get => events; set => events = value; } /// <summary> /// Returns true if the audio input should be read in an activation /// </summary> protected abstract bool ShouldSendMicData { get; } /// <summary> /// Start listening for sound or speech from the user and start sending data to Wit.ai once sound or speech has been detected. /// </summary> public abstract void Activate(); /// <summary> /// Activate the microphone and send data for NLU processing. Includes optional additional request parameters like dynamic entities and maximum results. /// </summary> /// <param name="requestOptions"></param> public abstract void Activate(WitRequestOptions requestOptions); /// <summary> /// Activate the microphone and send data for NLU processing immediately without waiting for sound/speech from the user to begin. /// </summary> public abstract void ActivateImmediately(); /// <summary> /// Activate the microphone and send data for NLU processing immediately without waiting for sound/speech from the user to begin. Includes optional additional request parameters like dynamic entities and maximum results. /// </summary> public abstract void ActivateImmediately(WitRequestOptions requestOptions); /// <summary> /// Stop listening and submit any remaining buffered microphone data for processing. /// </summary> public abstract void Deactivate(); /// <summary> /// Stop listening and abort any requests that may be active without waiting for a response. /// </summary> public abstract void DeactivateAndAbortRequest(); /// <summary> /// Send text data for NLU processing. Results will return the same way a voice based activation would. /// </summary> /// <param name="text"></param> public abstract void Activate(string text); /// <summary> /// Send text data for NLU processing with custom request options. /// </summary> /// <param name="text"></param> /// <param name="requestOptions"></param> public abstract void Activate(string text, WitRequestOptions requestOptions); protected virtual void Awake() { MatchIntentRegistry.Initialize(); } protected virtual void OnEnable() { events.OnResponse.AddListener(OnResponse); } protected virtual void OnDisable() { events.OnResponse.RemoveListener(OnResponse); } protected virtual void OnResponse(WitResponseNode response) { var intents = response.GetIntents(); foreach (var intent in intents) { HandleIntent(intent, response); } } private void HandleIntent(WitIntentData intent, WitResponseNode response) { var methods = MatchIntentRegistry.RegisteredMethods[intent.name]; foreach (var method in methods) { ExecuteRegisteredMatch(method, intent, response); } } private void ExecuteRegisteredMatch(RegisteredMatchIntent registeredMethod, WitIntentData intent, WitResponseNode response) { if (intent.confidence >= registeredMethod.matchIntent.MinConfidence && intent.confidence <= registeredMethod.matchIntent.MaxConfidence) { foreach (var obj in FindObjectsOfType(registeredMethod.type)) { var parameters = registeredMethod.method.GetParameters(); if (parameters.Length == 1) { registeredMethod.method.Invoke(obj, new object[] {response}); } else if (parameters.Length == 0) { registeredMethod.method.Invoke(obj, Array.Empty<object>()); } else { throw new ArgumentException( "Too many parameters on method tagged with MatchIntent. Match intent only supports methods with no parameters or with a WitResponseNode parameter."); } } } } } public interface IVoiceService { /// <summary> /// Returns true if this voice service is currently active and listening with the mic /// </summary> bool Active { get; } bool IsRequestActive { get; } bool MicActive { get; } VoiceEvents VoiceEvents { get; set; } ITranscriptionProvider TranscriptionProvider { get; set; } /// <summary> /// Activate the microphone and send data for NLU processing. /// </summary> void Activate(); /// <summary> /// Activate the microphone and send data for NLU processing with custom request options. /// </summary> /// <param name="requestOptions"></param> void Activate(WitRequestOptions requestOptions); void ActivateImmediately(); void ActivateImmediately(WitRequestOptions requestOptions); /// <summary> /// Stop listening and submit the collected microphone data for processing. /// </summary> void Deactivate(); /// <summary> /// Stop listening and abort any requests that may be active without waiting for a response. /// </summary> void DeactivateAndAbortRequest(); /// <summary> /// Send text data for NLU processing /// </summary> /// <param name="text"></param> void Activate(string transcription); /// <summary> /// Send text data for NLU processing with custom request options. /// </summary> /// <param name="text"></param> /// <param name="requestOptions"></param> void Activate(string text, WitRequestOptions requestOptions); } }