SpeechEvents.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * Copyright (c) Meta Platforms, Inc. and affiliates.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the license found in the
  6. * LICENSE file in the root directory of this source tree.
  7. */
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Reflection;
  12. using Meta.WitAi.Configuration;
  13. using UnityEngine;
  14. using UnityEngine.Events;
  15. using UnityEngine.Serialization;
  16. using Meta.WitAi.Interfaces;
  17. using Meta.WitAi.Requests;
  18. namespace Meta.WitAi.Events
  19. {
  20. // A class for tracking events used for speech
  21. [Serializable]
  22. public class SpeechEvents : EventRegistry, ISpeechEvents, ITranscriptionEvent, IAudioInputEvents
  23. {
  24. #region Activation - Setup Events
  25. protected const string EVENT_CATEGORY_ACTIVATION_SETUP = "Activation Setup Events";
  26. [EventCategory(EVENT_CATEGORY_ACTIVATION_SETUP)]
  27. [Tooltip("Called prior to initialization for WitRequestOption customization")]
  28. [FormerlySerializedAs("OnRequestOptionSetup")] [SerializeField]
  29. private WitRequestOptionsEvent _onRequestOptionSetup = new WitRequestOptionsEvent();
  30. public WitRequestOptionsEvent OnRequestOptionSetup => _onRequestOptionSetup;
  31. [EventCategory(EVENT_CATEGORY_ACTIVATION_SETUP)]
  32. [Tooltip("Called when a request is created. This occurs as soon as a activation is called successfully.")]
  33. [FormerlySerializedAs("OnRequestInitialized")] [SerializeField]
  34. private VoiceServiceRequestEvent _onRequestInitialized = new VoiceServiceRequestEvent();
  35. public VoiceServiceRequestEvent OnRequestInitialized => _onRequestInitialized;
  36. [EventCategory(EVENT_CATEGORY_ACTIVATION_SETUP)]
  37. [Tooltip("Called when a request is sent. This occurs immediately once data is being transmitted to the endpoint.")]
  38. [FormerlySerializedAs("OnRequestCreated")] [SerializeField] [HideInInspector]
  39. private WitRequestCreatedEvent _onRequestCreated = new WitRequestCreatedEvent();
  40. [Obsolete("Deprecated for 'OnSend' event")]
  41. public WitRequestCreatedEvent OnRequestCreated => _onRequestCreated;
  42. [EventCategory(EVENT_CATEGORY_ACTIVATION_SETUP)]
  43. [Tooltip("Called when a request is sent. This occurs immediately once data is being transmitted to the endpoint.")]
  44. [SerializeField]
  45. private VoiceServiceRequestEvent _onSend = new VoiceServiceRequestEvent();
  46. public VoiceServiceRequestEvent OnSend => _onSend;
  47. #endregion Activation - Setup Events
  48. #region Activation - Info Events
  49. protected const string EVENT_CATEGORY_ACTIVATION_INFO = "Activation Info Events";
  50. [EventCategory(EVENT_CATEGORY_ACTIVATION_INFO)]
  51. [Tooltip("Fired when the minimum wake threshold is hit after an activation. Not called for ActivateImmediately")]
  52. [FormerlySerializedAs("OnMinimumWakeThresholdHit")] [SerializeField]
  53. private UnityEvent _onMinimumWakeThresholdHit = new UnityEvent();
  54. public UnityEvent OnMinimumWakeThresholdHit => _onMinimumWakeThresholdHit;
  55. [EventCategory(EVENT_CATEGORY_ACTIVATION_INFO)]
  56. [Tooltip("Fired when recording stops, the minimum volume threshold was hit, and data is being sent to the server.")]
  57. [FormerlySerializedAs("OnMicDataSent")] [SerializeField]
  58. private UnityEvent _onMicDataSent = new UnityEvent();
  59. public UnityEvent OnMicDataSent => _onMicDataSent;
  60. [EventCategory(EVENT_CATEGORY_ACTIVATION_INFO)]
  61. [Tooltip("The Deactivate() method has been called ending the current activation.")]
  62. [FormerlySerializedAs("OnStoppedListeningDueToDeactivation")] [SerializeField]
  63. private UnityEvent _onStoppedListeningDueToDeactivation = new UnityEvent();
  64. public UnityEvent OnStoppedListeningDueToDeactivation => _onStoppedListeningDueToDeactivation;
  65. [EventCategory(EVENT_CATEGORY_ACTIVATION_INFO)]
  66. [Tooltip("Called when the microphone input volume has been below the volume threshold for the specified duration and microphone data is no longer being collected")]
  67. [FormerlySerializedAs("OnStoppedListeningDueToInactivity")] [SerializeField]
  68. private UnityEvent _onStoppedListeningDueToInactivity = new UnityEvent();
  69. public UnityEvent OnStoppedListeningDueToInactivity => _onStoppedListeningDueToInactivity;
  70. [EventCategory(EVENT_CATEGORY_ACTIVATION_INFO)]
  71. [Tooltip("The microphone has stopped recording because maximum recording time has been hit for this activation")]
  72. [FormerlySerializedAs("OnStoppedListeningDueToTimeout")] [SerializeField]
  73. private UnityEvent _onStoppedListeningDueToTimeout = new UnityEvent();
  74. public UnityEvent OnStoppedListeningDueToTimeout => _onStoppedListeningDueToTimeout;
  75. #endregion Activation - Info Events
  76. #region Activation - Cancelation Events
  77. protected const string EVENT_CATEGORY_ACTIVATION_CANCELATION = "Activation Cancelation Events";
  78. [EventCategory(EVENT_CATEGORY_ACTIVATION_CANCELATION)]
  79. [Tooltip("Called when the activation is about to be aborted by a direct user interaction via DeactivateAndAbort.")]
  80. [FormerlySerializedAs("OnAborting")] [SerializeField]
  81. private UnityEvent _onAborting = new UnityEvent();
  82. public UnityEvent OnAborting => _onAborting;
  83. [EventCategory(EVENT_CATEGORY_ACTIVATION_CANCELATION)]
  84. [Tooltip("Called when the activation stopped because the network request was aborted. This can be via a timeout or call to DeactivateAndAbort.")]
  85. [FormerlySerializedAs("OnAborted")] [SerializeField]
  86. private UnityEvent _onAborted = new UnityEvent();
  87. public UnityEvent OnAborted => _onAborted;
  88. [EventCategory(EVENT_CATEGORY_ACTIVATION_CANCELATION)]
  89. [Tooltip("Called when a request has been canceled either prior to or after a request has begun transmission. Returns the cancelation reason.")]
  90. [FormerlySerializedAs("OnCanceled")] [SerializeField]
  91. private WitTranscriptionEvent _onCanceled = new WitTranscriptionEvent();
  92. public WitTranscriptionEvent OnCanceled => _onCanceled;
  93. #endregion Activation - Cancelation Events
  94. #region Activation - Response Events
  95. protected const string EVENT_CATEGORY_ACTIVATION_RESPONSE = "Activation Response Events";
  96. [EventCategory(EVENT_CATEGORY_ACTIVATION_RESPONSE)]
  97. [Tooltip("Called when response from Wit.ai has been received from partial transcription")]
  98. [FormerlySerializedAs("OnPartialResponse")] [SerializeField] [HideInInspector]
  99. private WitResponseEvent _onPartialResponse = new WitResponseEvent();
  100. public WitResponseEvent OnPartialResponse => _onPartialResponse;
  101. [EventCategory(EVENT_CATEGORY_ACTIVATION_RESPONSE)]
  102. [Tooltip("Called when a response from Wit.ai has been received")]
  103. [FormerlySerializedAs("OnResponse")] [FormerlySerializedAs("onResponse")] [SerializeField]
  104. private WitResponseEvent _onResponse = new WitResponseEvent();
  105. public WitResponseEvent OnResponse => _onResponse;
  106. [EventCategory(EVENT_CATEGORY_ACTIVATION_RESPONSE)]
  107. [Tooltip("Called when there was an error with a WitRequest or the RuntimeConfiguration is not properly configured.")]
  108. [FormerlySerializedAs("OnError")] [FormerlySerializedAs("onError")] [SerializeField]
  109. private WitErrorEvent _onError = new WitErrorEvent();
  110. public WitErrorEvent OnError => _onError;
  111. [EventCategory(EVENT_CATEGORY_ACTIVATION_RESPONSE)]
  112. [Tooltip("Called when a request has completed and all response and error callbacks have fired. This is not called if the request was aborted.")]
  113. [FormerlySerializedAs("OnRequestCompleted")] [SerializeField]
  114. private UnityEvent _onRequestCompleted = new UnityEvent();
  115. public UnityEvent OnRequestCompleted => _onRequestCompleted;
  116. [EventCategory(EVENT_CATEGORY_ACTIVATION_RESPONSE)]
  117. [Tooltip("Called when a request has been canceled, failed, or successfully completed")]
  118. [FormerlySerializedAs("OnComplete")] [SerializeField]
  119. private VoiceServiceRequestEvent _onComplete = new VoiceServiceRequestEvent();
  120. public VoiceServiceRequestEvent OnComplete => _onComplete;
  121. #endregion Activation - Response Events
  122. #region Audio Events
  123. protected const string EVENT_CATEGORY_AUDIO_EVENTS = "Audio Events";
  124. [EventCategory(EVENT_CATEGORY_AUDIO_EVENTS)]
  125. [Tooltip("Called when the microphone has started collecting data collecting data to be sent to Wit.ai. There may be some buffering before data transmission starts.")]
  126. [FormerlySerializedAs("OnStartListening")] [FormerlySerializedAs("onStart")] [SerializeField]
  127. private UnityEvent _onStartListening = new UnityEvent();
  128. public UnityEvent OnStartListening => _onStartListening;
  129. public UnityEvent OnMicStartedListening => OnStartListening;
  130. [EventCategory(EVENT_CATEGORY_AUDIO_EVENTS)]
  131. [Tooltip("Called when the voice service is no longer collecting data from the microphone")]
  132. [FormerlySerializedAs("OnStoppedListening")] [FormerlySerializedAs("onStopped")] [SerializeField]
  133. private UnityEvent _onStoppedListening = new UnityEvent();
  134. public UnityEvent OnStoppedListening => _onStoppedListening;
  135. public UnityEvent OnMicStoppedListening => OnStoppedListening;
  136. [EventCategory(EVENT_CATEGORY_AUDIO_EVENTS)]
  137. [Tooltip("Called when the volume level of the mic input has changed")]
  138. [FormerlySerializedAs("OnMicLevelChanged")] [SerializeField]
  139. private WitMicLevelChangedEvent _onMicLevelChanged = new WitMicLevelChangedEvent();
  140. public WitMicLevelChangedEvent OnMicLevelChanged => _onMicLevelChanged;
  141. public WitMicLevelChangedEvent OnMicAudioLevelChanged => OnMicLevelChanged;
  142. #endregion Audio Events
  143. #region Transcription Events
  144. protected const string EVENT_CATEGORY_TRANSCRIPTION_EVENTS = "Transcription Events";
  145. [EventCategory(EVENT_CATEGORY_TRANSCRIPTION_EVENTS)]
  146. [Tooltip("Message fired when a partial transcription has been received.")]
  147. [FormerlySerializedAs("onPartialTranscription")] [FormerlySerializedAs("OnPartialTranscription")] [SerializeField]
  148. private WitTranscriptionEvent _onPartialTranscription = new WitTranscriptionEvent();
  149. public WitTranscriptionEvent OnPartialTranscription => _onPartialTranscription;
  150. [Obsolete("Deprecated for 'OnPartialTranscription' event")]
  151. public WitTranscriptionEvent onPartialTranscription => OnPartialTranscription;
  152. [FormerlySerializedAs("OnFullTranscription")]
  153. [EventCategory(EVENT_CATEGORY_TRANSCRIPTION_EVENTS)]
  154. [Tooltip("Message received when a complete transcription is received.")]
  155. [FormerlySerializedAs("onFullTranscription")] [FormerlySerializedAs("OnFullTranscription")] [SerializeField]
  156. private WitTranscriptionEvent _onFullTranscription = new WitTranscriptionEvent();
  157. public WitTranscriptionEvent OnFullTranscription => _onFullTranscription;
  158. [Obsolete("Deprecated for 'OnPartialTranscription' event")]
  159. public WitTranscriptionEvent onFullTranscription => OnFullTranscription;
  160. #endregion Transcription Events
  161. #region Listen Wrapping
  162. // Listeners
  163. private HashSet<SpeechEvents> _listeners = new HashSet<SpeechEvents>();
  164. // Adds all listener events
  165. public void AddListener(SpeechEvents listener)
  166. {
  167. // Ignore if null or already set
  168. if (listener == null || _listeners.Contains(listener))
  169. {
  170. return;
  171. }
  172. // Add all events
  173. if (_listeners.Count == 0)
  174. {
  175. SetEvents(true);
  176. }
  177. // Add listener
  178. _listeners.Add(listener);
  179. }
  180. // Removes all listener events
  181. public void RemoveListener(SpeechEvents listener)
  182. {
  183. // Ignore if null or not already set
  184. if (listener == null || !_listeners.Contains(listener))
  185. {
  186. return;
  187. }
  188. // Remove listener
  189. _listeners.Remove(listener);
  190. // Remove all events
  191. if (_listeners.Count == 0)
  192. {
  193. SetEvents(false);
  194. }
  195. }
  196. // Set events
  197. protected virtual void SetEvents(bool add)
  198. {
  199. SetEvent((events) => events?._onRequestOptionSetup, add);
  200. SetEvent((events) => events?._onRequestInitialized, add);
  201. SetEvent((events) => events?._onRequestCreated, add);
  202. SetEvent((events) => events?._onSend, add);
  203. SetEvent((events) => events?._onMinimumWakeThresholdHit, add);
  204. SetEvent((events) => events?._onMicDataSent, add);
  205. SetEvent((events) => events?._onStoppedListeningDueToDeactivation, add);
  206. SetEvent((events) => events?._onStoppedListeningDueToInactivity, add);
  207. SetEvent((events) => events?._onAborting, add);
  208. SetEvent((events) => events?._onAborted, add);
  209. SetEvent((events) => events?._onCanceled, add);
  210. SetEvent((events) => events?._onPartialResponse, add);
  211. SetEvent((events) => events?._onResponse, add);
  212. SetEvent((events) => events?._onError, add);
  213. SetEvent((events) => events?._onRequestCompleted, add);
  214. SetEvent((events) => events?._onComplete, add);
  215. SetEvent((events) => events?._onStartListening, add);
  216. SetEvent((events) => events?._onStoppedListening, add);
  217. SetEvent((events) => events?._onMicLevelChanged, add);
  218. SetEvent((events) => events?._onPartialTranscription, add);
  219. SetEvent((events) => events?._onFullTranscription, add);
  220. }
  221. // Set UnityEvent with no parameter
  222. protected void SetEvent(Func<SpeechEvents, UnityEvent> getEvent, bool add)
  223. {
  224. // Get source event
  225. UnityEvent sourceEvent = getEvent(this);
  226. // Add event
  227. if (!add)
  228. {
  229. sourceEvent?.RemoveAllListeners();
  230. return;
  231. }
  232. // Add listener
  233. sourceEvent?.AddListener(() =>
  234. {
  235. foreach (var listener in _listeners)
  236. {
  237. getEvent(listener)?.Invoke();
  238. }
  239. });
  240. }
  241. // Set UnityEvent with parameter
  242. protected void SetEvent<T>(Func<SpeechEvents, UnityEvent<T>> getEvent, bool add)
  243. {
  244. // Get source event
  245. UnityEvent<T> sourceEvent = getEvent(this);
  246. // Add event
  247. if (!add)
  248. {
  249. sourceEvent?.RemoveAllListeners();
  250. return;
  251. }
  252. // Add listener
  253. sourceEvent?.AddListener((param) =>
  254. {
  255. foreach (var listener in _listeners)
  256. {
  257. getEvent(listener)?.Invoke(param);
  258. }
  259. });
  260. }
  261. // Set UnityEvent with 2 parameters
  262. protected void SetEvent<T, U>(Func<SpeechEvents, UnityEvent<T, U>> getEvent, bool add)
  263. {
  264. // Get source event
  265. UnityEvent<T, U> sourceEvent = getEvent(this);
  266. // Add event
  267. if (!add)
  268. {
  269. sourceEvent?.RemoveAllListeners();
  270. return;
  271. }
  272. // Add listener
  273. sourceEvent?.AddListener((param1, param2) =>
  274. {
  275. foreach (var listener in _listeners)
  276. {
  277. getEvent(listener)?.Invoke(param1, param2);
  278. }
  279. });
  280. }
  281. #endregion Listen Wrapping
  282. }
  283. }