Initial Commit
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly:InternalsVisibleTo("Meta.WitAi.Tests")]
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1e74ebbbf864e009ea70c1e3ac18477
|
||||
timeCreated: 1654203305
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4145be28f213451fbd89e767e85d9ba7
|
||||
timeCreated: 1680127664
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Attributes
|
||||
{
|
||||
public class TooltipBoxAttribute : PropertyAttribute
|
||||
{
|
||||
public string Text { get; private set; }
|
||||
|
||||
public TooltipBoxAttribute(string text)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef7ac601451d4e869a7f05b23c59c842
|
||||
timeCreated: 1680127686
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Data;
|
||||
|
||||
namespace Meta.WitAi
|
||||
{
|
||||
public class AudioDurationTracker
|
||||
{
|
||||
private readonly String _requestId;
|
||||
private double _bytesCaptured = 0.0;
|
||||
private readonly int _bytesPerSample;
|
||||
private readonly AudioEncoding _audioEncoding;
|
||||
private long _finalizeTimeStamp;
|
||||
private double _audioDurationMs;
|
||||
|
||||
|
||||
public AudioDurationTracker(string requestId, AudioEncoding audioEncoding)
|
||||
{
|
||||
_requestId = requestId;
|
||||
_audioEncoding = audioEncoding;
|
||||
_bytesPerSample = _audioEncoding.bits / 8;
|
||||
}
|
||||
|
||||
public void AddBytes(long bytes)
|
||||
{
|
||||
_bytesCaptured += bytes;
|
||||
}
|
||||
|
||||
public void FinalizeAudio()
|
||||
{
|
||||
_finalizeTimeStamp = (DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond);
|
||||
_audioDurationMs =
|
||||
(_bytesCaptured / (_audioEncoding.samplerate * _audioEncoding.numChannels * _bytesPerSample)) * 1000.0;
|
||||
}
|
||||
|
||||
public long GetFinalizeTimeStamp()
|
||||
{
|
||||
return _finalizeTimeStamp;
|
||||
}
|
||||
|
||||
public double GetAudioDuration()
|
||||
{
|
||||
return _audioDurationMs;
|
||||
}
|
||||
|
||||
public string GetRequestId()
|
||||
{
|
||||
return _requestId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a325b28834054db2a96b89ac4354c880
|
||||
timeCreated: 1670629377
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d054f5543f909634a88982d2b2dc8e55
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
[Serializable]
|
||||
public class ConfidenceRange
|
||||
{
|
||||
public float minConfidence;
|
||||
public float maxConfidence;
|
||||
public UnityEvent onWithinConfidenceRange = new UnityEvent();
|
||||
public UnityEvent onOutsideConfidenceRange = new UnityEvent();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a9a869d94ca2214fb1f2f5c3aeef455
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Attributes;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Utilities;
|
||||
using UnityEngine;
|
||||
using Utilities;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggers an event when no intents were recognized in an utterance.
|
||||
/// </summary>
|
||||
[AddComponentMenu("Wit.ai/Response Matchers/Out Of Domain")]
|
||||
public class OutOfScopeUtteranceHandler : WitResponseHandler
|
||||
{
|
||||
[Tooltip("If set to a value greater than zero, any intent that returns with a confidence lower than this value will be treated as out of domain/scope.")]
|
||||
[Range(0, 1f)]
|
||||
[SerializeField] private float confidenceThreshold = 0.0f;
|
||||
[Space(WitRuntimeStyles.HeaderPaddingTop)]
|
||||
[TooltipBox("Triggered when a activation on the associated AppVoiceExperience does not return any intents.")]
|
||||
[SerializeField] private StringEvent onOutOfDomain = new StringEvent();
|
||||
|
||||
protected override string OnValidateResponse(WitResponseNode response, bool isEarlyResponse)
|
||||
{
|
||||
if (response == null)
|
||||
{
|
||||
return "Response is null";
|
||||
}
|
||||
if (response["intents"].Count > 0)
|
||||
{
|
||||
if (response.GetFirstIntent()["confidence"].AsFloat < confidenceThreshold)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return "Intents found";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
protected override void OnResponseInvalid(WitResponseNode response, string error) {}
|
||||
protected override void OnResponseSuccess(WitResponseNode response)
|
||||
{
|
||||
onOutOfDomain?.Invoke(response.GetTranscription());
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 960c102c70216114fa5c3800d4172d67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
[AddComponentMenu("Wit.ai/Response Matchers/Simple Intent Handler")]
|
||||
public class SimpleIntentHandler : WitIntentMatcher
|
||||
{
|
||||
[SerializeField] private UnityEvent onIntentTriggered = new UnityEvent();
|
||||
|
||||
[Tooltip("Confidence ranges are executed in order. If checked, all confidence values will be checked instead of stopping on the first one that matches.")]
|
||||
[SerializeField] public bool allowConfidenceOverlap;
|
||||
#if UNITY_2021_3_2 || UNITY_2021_3_3 || UNITY_2021_3_4 || UNITY_2021_3_5
|
||||
[NonReorderable]
|
||||
#endif
|
||||
[SerializeField] public ConfidenceRange[] confidenceRanges;
|
||||
|
||||
public UnityEvent OnIntentTriggered => onIntentTriggered;
|
||||
|
||||
protected override void OnResponseSuccess(WitResponseNode response)
|
||||
{
|
||||
onIntentTriggered.Invoke();
|
||||
UpdateRanges(response);
|
||||
}
|
||||
protected override void OnResponseInvalid(WitResponseNode response, string error)
|
||||
{
|
||||
UpdateRanges(response);
|
||||
}
|
||||
|
||||
private void UpdateRanges(WitResponseNode response)
|
||||
{
|
||||
// Find intents if possible
|
||||
var intents = response?.GetIntents();
|
||||
if (intents == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate intents
|
||||
foreach (var intentData in intents)
|
||||
{
|
||||
if (string.Equals(intent, intentData.name, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
// Found intent
|
||||
RefreshConfidenceRange(intentData.confidence, confidenceRanges, allowConfidenceOverlap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Not matched
|
||||
RefreshConfidenceRange(0, confidenceRanges, allowConfidenceOverlap);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d2d3ff93ff48bd40ab5bca3cf4e6d2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
[AddComponentMenu("Wit.ai/Response Matchers/Simple String Entity Handler")]
|
||||
public class SimpleStringEntityHandler : WitIntentMatcher
|
||||
{
|
||||
[SerializeField] public string entity;
|
||||
[SerializeField] public string format;
|
||||
[SerializeField] private StringEntityMatchEvent onIntentEntityTriggered
|
||||
= new StringEntityMatchEvent();
|
||||
|
||||
public StringEntityMatchEvent OnIntentEntityTriggered => onIntentEntityTriggered;
|
||||
|
||||
protected override string OnValidateResponse(WitResponseNode response, bool isEarlyResponse)
|
||||
{
|
||||
// Return base
|
||||
string result = base.OnValidateResponse(response, isEarlyResponse);
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Not found
|
||||
var entityValue = response.GetFirstEntityValue(entity);
|
||||
if (string.IsNullOrEmpty(entityValue))
|
||||
{
|
||||
return $"Missing required entity: {entity}";
|
||||
}
|
||||
// Fail
|
||||
return string.Empty;
|
||||
}
|
||||
protected override void OnResponseInvalid(WitResponseNode response, string error) { }
|
||||
protected override void OnResponseSuccess(WitResponseNode response)
|
||||
{
|
||||
var entityValue = response.GetFirstEntityValue(entity);
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
{
|
||||
onIntentEntityTriggered.Invoke(format.Replace("{value}", entityValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
onIntentEntityTriggered.Invoke(entityValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class StringEntityMatchEvent : UnityEvent<string> {}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77dceeee73817ec4c844564714e05c77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.Conduit;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Data.Intents;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
// Abstract class to share confidence handling
|
||||
public abstract class WitIntentMatcher : WitResponseHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Intent name to be matched
|
||||
/// </summary>
|
||||
[Header("Intent Settings")]
|
||||
[SerializeField] public string intent;
|
||||
|
||||
/// <summary>
|
||||
/// Confidence threshold
|
||||
/// </summary>
|
||||
[FormerlySerializedAs("confidence")]
|
||||
[Range(0, 1f), SerializeField] public float confidenceThreshold = .6f;
|
||||
|
||||
// Handle simple intent validation
|
||||
protected override string OnValidateResponse(WitResponseNode response, bool isEarlyResponse)
|
||||
{
|
||||
// No response
|
||||
if (response == null)
|
||||
{
|
||||
return "No response";
|
||||
}
|
||||
// Check against all intents
|
||||
WitIntentData[] intents = response.GetIntents();
|
||||
if (intents == null || intents.Length == 0)
|
||||
{
|
||||
return "No intents found";
|
||||
}
|
||||
// Find intent
|
||||
WitIntentData found = null;
|
||||
foreach (var intentData in intents)
|
||||
{
|
||||
if (string.Equals(intent, intentData.name, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
found = intentData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == null)
|
||||
{
|
||||
return $"Missing required intent '{intent}'";
|
||||
}
|
||||
// Check confidence
|
||||
if (found.confidence < confidenceThreshold)
|
||||
{
|
||||
return $"Required intent '{intent}' confidence too low: {found.confidence:0.000}\nRequired: {confidenceThreshold:0.000}";
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
Manifest.WitResponseMatcherIntents.Add(intent);
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
Manifest.WitResponseMatcherIntents.Remove(intent);
|
||||
base.OnDisable();
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dca9f31f9df1bd4d9cda88e81bf3082
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Data;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Requests;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
[Serializable]
|
||||
public class WitResponseEvent : UnityEvent<WitResponseNode> {}
|
||||
[Serializable]
|
||||
public class WitResponseErrorEvent : UnityEvent<WitResponseNode, string> {}
|
||||
|
||||
public abstract class WitResponseHandler : MonoBehaviour
|
||||
{
|
||||
[FormerlySerializedAs("wit")]
|
||||
[SerializeField] public VoiceService Voice;
|
||||
[SerializeField] public bool ValidateEarly = false;
|
||||
|
||||
// Whether validated early
|
||||
private bool _validated = false;
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (!Voice) Voice = FindObjectOfType<VoiceService>();
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
if (!Voice) Voice = FindObjectOfType<VoiceService>();
|
||||
if (!Voice)
|
||||
{
|
||||
VLog.E($"VoiceService not found in scene.\nDisabling {GetType().Name} on {gameObject.name}");
|
||||
enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Voice.VoiceEvents.OnSend.AddListener(OnRequestSend);
|
||||
Voice.VoiceEvents.OnValidatePartialResponse.AddListener(HandleValidateEarlyResponse);
|
||||
Voice.VoiceEvents.OnResponse.AddListener(HandleFinalResponse);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
if (Voice)
|
||||
{
|
||||
Voice.VoiceEvents.OnSend.RemoveListener(OnRequestSend);
|
||||
Voice.VoiceEvents.OnValidatePartialResponse.RemoveListener(HandleValidateEarlyResponse);
|
||||
Voice.VoiceEvents.OnResponse.RemoveListener(HandleFinalResponse);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnRequestSend(VoiceServiceRequest request)
|
||||
{
|
||||
_validated = false;
|
||||
}
|
||||
|
||||
protected virtual void HandleValidateEarlyResponse(VoiceSession session)
|
||||
{
|
||||
if (ValidateEarly && !_validated)
|
||||
{
|
||||
string invalidReason = OnValidateResponse(session.response, true);
|
||||
if (string.IsNullOrEmpty(invalidReason))
|
||||
{
|
||||
_validated = true;
|
||||
OnResponseSuccess(session.response);
|
||||
session.validResponse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected virtual void HandleFinalResponse(WitResponseNode response)
|
||||
{
|
||||
// Not yet handled
|
||||
if (!_validated)
|
||||
{
|
||||
string invalidReason = OnValidateResponse(response, false);
|
||||
if (!string.IsNullOrEmpty(invalidReason))
|
||||
{
|
||||
OnResponseInvalid(response, invalidReason);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnResponseSuccess(response);
|
||||
}
|
||||
_validated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle validation
|
||||
protected abstract string OnValidateResponse(WitResponseNode response, bool isEarlyResponse);
|
||||
// Handle invalid
|
||||
protected abstract void OnResponseInvalid(WitResponseNode response, string error);
|
||||
// Handle valid
|
||||
protected abstract void OnResponseSuccess(WitResponseNode response);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// For tests
|
||||
public void HandleResponse(WitResponseNode response) => HandleFinalResponse(response);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Refresh confidence range
|
||||
/// </summary>
|
||||
/// <param name="confidence"></param>
|
||||
/// <param name="confidenceRanges"></param>
|
||||
/// <param name="allowConfidenceOverlap"></param>
|
||||
/// <returns></returns>
|
||||
public static bool RefreshConfidenceRange(float confidence, ConfidenceRange[] confidenceRanges, bool allowConfidenceOverlap)
|
||||
{
|
||||
// Whether found
|
||||
bool foundIn = false;
|
||||
bool foundOut = false;
|
||||
|
||||
// Iterate confidences
|
||||
for (int i = 0; null != confidenceRanges && i < confidenceRanges.Length; i++)
|
||||
{
|
||||
var range = confidenceRanges[i];
|
||||
|
||||
// Within Range
|
||||
if (confidence >= range.minConfidence &&
|
||||
confidence <= range.maxConfidence)
|
||||
{
|
||||
// Ignore overlap
|
||||
if (!allowConfidenceOverlap && foundIn)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Within delegate
|
||||
range.onWithinConfidenceRange?.Invoke();
|
||||
foundIn = true;
|
||||
}
|
||||
// Out of Range
|
||||
else
|
||||
{
|
||||
// Ignore overlap
|
||||
if (!allowConfidenceOverlap && foundOut)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Outside delegate
|
||||
range.onOutsideConfidenceRange?.Invoke();
|
||||
foundOut = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return if found within
|
||||
return foundIn;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 097381abbd7a3364f80ac4460551a2cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+358
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using Meta.WitAi.Attributes;
|
||||
using Meta.WitAi.Data;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Utilities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
[AddComponentMenu("Wit.ai/Response Matchers/Response Matcher")]
|
||||
public class WitResponseMatcher : WitIntentMatcher
|
||||
{
|
||||
[FormerlySerializedAs("valuePaths")]
|
||||
[Header("Value Matching")]
|
||||
#if UNITY_2021_3_2 || UNITY_2021_3_3 || UNITY_2021_3_4 || UNITY_2021_3_5
|
||||
[NonReorderable]
|
||||
#endif
|
||||
[SerializeField] public ValuePathMatcher[] valueMatchers;
|
||||
|
||||
[Header("Output")]
|
||||
#if UNITY_2021_3_2 || UNITY_2021_3_3 || UNITY_2021_3_4 || UNITY_2021_3_5
|
||||
[NonReorderable]
|
||||
#endif
|
||||
[SerializeField] private FormattedValueEvents[] formattedValueEvents;
|
||||
[SerializeField] private MultiValueEvent onMultiValueEvent = new MultiValueEvent();
|
||||
|
||||
[TooltipBox("Triggered if the matching conditions did not match. The parameter will be the transcription that was received. This will only trigger if there were values for intents or entities, but those values didn't match this matcher.")]
|
||||
[SerializeField] private StringEvent onDidNotMatch = new StringEvent();
|
||||
|
||||
[TooltipBox("Triggered if a request was checked and no intents were found. This will still trigger if entities match and only applies to intents. The parameter will be the transcription.")]
|
||||
[SerializeField] private StringEvent onOutOfDomain = new StringEvent();
|
||||
|
||||
private static Regex valueRegex = new Regex(Regex.Escape("{value}"), RegexOptions.Compiled);
|
||||
|
||||
// Handle validation
|
||||
protected override string OnValidateResponse(WitResponseNode response, bool isEarlyResponse)
|
||||
{
|
||||
// Return base
|
||||
string result = base.OnValidateResponse(response, isEarlyResponse);
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// Only check value matches on early
|
||||
if (isEarlyResponse && !ValueMatches(response))
|
||||
{
|
||||
return "No value matches";
|
||||
}
|
||||
// Success
|
||||
return string.Empty;
|
||||
}
|
||||
// Ignore for mismatched intent
|
||||
protected override void OnResponseInvalid(WitResponseNode response, string error)
|
||||
{
|
||||
if (response.GetIntents().Length > 0 || response.EntityCount() > 0)
|
||||
{
|
||||
onDidNotMatch?.Invoke(response.GetTranscription());
|
||||
}
|
||||
|
||||
if (response.GetIntents().Length == 0)
|
||||
{
|
||||
onOutOfDomain?.Invoke(response.GetTranscription());
|
||||
}
|
||||
}
|
||||
// Handle valid callback
|
||||
protected override void OnResponseSuccess(WitResponseNode response)
|
||||
{
|
||||
// Check value matches
|
||||
if (ValueMatches(response))
|
||||
{
|
||||
for (int j = 0; j < formattedValueEvents.Length; j++)
|
||||
{
|
||||
var formatEvent = formattedValueEvents[j];
|
||||
var result = formatEvent.format;
|
||||
for (int i = 0; i < valueMatchers.Length; i++)
|
||||
{
|
||||
var reference = valueMatchers[i].Reference;
|
||||
var value = reference.GetStringValue(response);
|
||||
if (!string.IsNullOrEmpty(formatEvent.format))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
result = valueRegex.Replace(result, value, 1);
|
||||
result = result.Replace("{" + i + "}", value);
|
||||
}
|
||||
else if (result.Contains("{" + i + "}"))
|
||||
{
|
||||
result = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
formatEvent.onFormattedValueEvent?.Invoke(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onDidNotMatch?.Invoke(response.GetTranscription());
|
||||
}
|
||||
|
||||
// Get all values & perform multi value event
|
||||
List<string> values = new List<string>();
|
||||
foreach (var matcher in valueMatchers)
|
||||
{
|
||||
// Add value
|
||||
var value = matcher.Reference.GetStringValue(response);
|
||||
values.Add(value);
|
||||
|
||||
// Refresh confidence
|
||||
if (matcher.ConfidenceReference != null)
|
||||
{
|
||||
float confidenceValue = ValueMatches(response, matcher)
|
||||
? matcher.ConfidenceReference.GetFloatValue(response)
|
||||
: 0f;
|
||||
RefreshConfidenceRange(confidenceValue, matcher.confidenceRanges, matcher.allowConfidenceOverlap);
|
||||
}
|
||||
}
|
||||
onMultiValueEvent.Invoke(values.ToArray());
|
||||
}
|
||||
|
||||
private bool ValueMatches(WitResponseNode response)
|
||||
{
|
||||
bool matches = true;
|
||||
for (int i = 0; i < valueMatchers.Length && matches; i++)
|
||||
{
|
||||
matches &= ValueMatches(response, valueMatchers[i]);
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
private bool ValueMatches(WitResponseNode response, ValuePathMatcher matcher)
|
||||
{
|
||||
var value = matcher.Reference.GetStringValue(response);
|
||||
bool result = !matcher.contentRequired || !string.IsNullOrEmpty(value);
|
||||
switch (matcher.matchMethod)
|
||||
{
|
||||
case MatchMethod.RegularExpression:
|
||||
result &= Regex.Match(value, matcher.matchValue).Success;
|
||||
break;
|
||||
case MatchMethod.Text:
|
||||
result &= value == matcher.matchValue;
|
||||
break;
|
||||
case MatchMethod.IntegerComparison:
|
||||
result &= CompareInt(value, matcher);
|
||||
break;
|
||||
case MatchMethod.FloatComparison:
|
||||
result &= CompareFloat(value, matcher);
|
||||
break;
|
||||
case MatchMethod.DoubleComparison:
|
||||
result &= CompareDouble(value, matcher);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool CompareDouble(string value, ValuePathMatcher matcher)
|
||||
{
|
||||
|
||||
// This one is freeform based on the input so we will retrun false if it is not parsable
|
||||
if (!double.TryParse(value, out double dValue)) return false;
|
||||
|
||||
// We will throw an exception if match value is not a numeric value. This is a developer
|
||||
// error.
|
||||
double dMatchValue = double.Parse(matcher.matchValue);
|
||||
|
||||
switch (matcher.comparisonMethod)
|
||||
{
|
||||
case ComparisonMethod.Equals:
|
||||
return Math.Abs(dValue - dMatchValue) < matcher.floatingPointComparisonTolerance;
|
||||
case ComparisonMethod.NotEquals:
|
||||
return Math.Abs(dValue - dMatchValue) > matcher.floatingPointComparisonTolerance;
|
||||
case ComparisonMethod.Greater:
|
||||
return dValue > dMatchValue;
|
||||
case ComparisonMethod.Less:
|
||||
return dValue < dMatchValue;
|
||||
case ComparisonMethod.GreaterThanOrEqualTo:
|
||||
return dValue >= dMatchValue;
|
||||
case ComparisonMethod.LessThanOrEqualTo:
|
||||
return dValue <= dMatchValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CompareFloat(string value, ValuePathMatcher matcher)
|
||||
{
|
||||
|
||||
// This one is freeform based on the input so we will retrun false if it is not parsable
|
||||
if (!float.TryParse(value, out float dValue)) return false;
|
||||
|
||||
// We will throw an exception if match value is not a numeric value. This is a developer
|
||||
// error.
|
||||
float dMatchValue = float.Parse(matcher.matchValue);
|
||||
|
||||
switch (matcher.comparisonMethod)
|
||||
{
|
||||
case ComparisonMethod.Equals:
|
||||
return Math.Abs(dValue - dMatchValue) <
|
||||
matcher.floatingPointComparisonTolerance;
|
||||
case ComparisonMethod.NotEquals:
|
||||
return Math.Abs(dValue - dMatchValue) >
|
||||
matcher.floatingPointComparisonTolerance;
|
||||
case ComparisonMethod.Greater:
|
||||
return dValue > dMatchValue;
|
||||
case ComparisonMethod.Less:
|
||||
return dValue < dMatchValue;
|
||||
case ComparisonMethod.GreaterThanOrEqualTo:
|
||||
return dValue >= dMatchValue;
|
||||
case ComparisonMethod.LessThanOrEqualTo:
|
||||
return dValue <= dMatchValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CompareInt(string value, ValuePathMatcher matcher)
|
||||
{
|
||||
|
||||
// This one is freeform based on the input so we will retrun false if it is not parsable
|
||||
if (!int.TryParse(value, out int dValue)) return false;
|
||||
|
||||
// We will throw an exception if match value is not a numeric value. This is a developer
|
||||
// error.
|
||||
int dMatchValue = int.Parse(matcher.matchValue);
|
||||
|
||||
switch (matcher.comparisonMethod)
|
||||
{
|
||||
case ComparisonMethod.Equals:
|
||||
return dValue == dMatchValue;
|
||||
case ComparisonMethod.NotEquals:
|
||||
return dValue != dMatchValue;
|
||||
case ComparisonMethod.Greater:
|
||||
return dValue > dMatchValue;
|
||||
case ComparisonMethod.Less:
|
||||
return dValue < dMatchValue;
|
||||
case ComparisonMethod.GreaterThanOrEqualTo:
|
||||
return dValue >= dMatchValue;
|
||||
case ComparisonMethod.LessThanOrEqualTo:
|
||||
return dValue <= dMatchValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MultiValueEvent : UnityEvent<string[]>
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ValueEvent : UnityEvent<string>
|
||||
{ }
|
||||
|
||||
[Serializable]
|
||||
public class FormattedValueEvents
|
||||
{
|
||||
[Tooltip("Modify the string output, values can be inserted with {value} or {0}, {1}, {2}")]
|
||||
public string format;
|
||||
public ValueEvent onFormattedValueEvent = new ValueEvent();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ValuePathMatcher
|
||||
{
|
||||
[Tooltip("The path to a value within a WitResponseNode")]
|
||||
public string path;
|
||||
[Tooltip("A reference to a wit value object")]
|
||||
public WitValue witValueReference;
|
||||
[Tooltip("Does this path need to have text in the value to be considered a match")]
|
||||
public bool contentRequired = true;
|
||||
[Tooltip("If set the match value will be treated as a regular expression.")]
|
||||
public MatchMethod matchMethod;
|
||||
[Tooltip("The operator used to compare the value with the match value. Ex: response.value > matchValue")]
|
||||
public ComparisonMethod comparisonMethod;
|
||||
[Tooltip("Value used to compare with the result when Match Required is set")]
|
||||
public string matchValue;
|
||||
|
||||
[Tooltip("The variance allowed when comparing two floating point values for equality")]
|
||||
public double floatingPointComparisonTolerance = .0001f;
|
||||
|
||||
[Tooltip("Confidence ranges are executed in order. If checked, all confidence values will be checked instead of stopping on the first one that matches.")]
|
||||
[SerializeField] public bool allowConfidenceOverlap;
|
||||
[Tooltip("The confidence levels to handle for this value.\nNOTE: The selected node must have a confidence sibling node.")]
|
||||
public ConfidenceRange[] confidenceRanges;
|
||||
|
||||
private WitResponseReference pathReference;
|
||||
private WitResponseReference confidencePathReference;
|
||||
|
||||
public WitResponseReference ConfidenceReference
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null != confidencePathReference) return confidencePathReference;
|
||||
|
||||
var confidencePath = Reference?.path;
|
||||
if (!string.IsNullOrEmpty(confidencePath))
|
||||
{
|
||||
confidencePath = confidencePath.Substring(0, confidencePath.LastIndexOf("."));
|
||||
confidencePath += ".confidence";
|
||||
confidencePathReference = WitResultUtilities.GetWitResponseReference(confidencePath);
|
||||
}
|
||||
|
||||
return confidencePathReference;
|
||||
}
|
||||
}
|
||||
public WitResponseReference Reference
|
||||
{
|
||||
get
|
||||
{
|
||||
if (witValueReference) return witValueReference.Reference;
|
||||
|
||||
if (null == pathReference || pathReference.path != path)
|
||||
{
|
||||
pathReference = WitResultUtilities.GetWitResponseReference(path);
|
||||
}
|
||||
|
||||
return pathReference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ComparisonMethod
|
||||
{
|
||||
Equals,
|
||||
NotEquals,
|
||||
Greater,
|
||||
GreaterThanOrEqualTo,
|
||||
Less,
|
||||
LessThanOrEqualTo
|
||||
}
|
||||
|
||||
public enum MatchMethod
|
||||
{
|
||||
None,
|
||||
Text,
|
||||
RegularExpression,
|
||||
IntegerComparison,
|
||||
FloatComparison,
|
||||
DoubleComparison
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 591c3d6f017c11b4faa41506d75635b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.CallbackHandlers
|
||||
{
|
||||
[AddComponentMenu("Wit.ai/Response Matchers/Utterance Matcher")]
|
||||
public class WitUtteranceMatcher : WitResponseHandler
|
||||
{
|
||||
[SerializeField] private string searchText;
|
||||
[SerializeField] private bool exactMatch = true;
|
||||
[SerializeField] private bool useRegex;
|
||||
|
||||
[SerializeField] private StringEvent onUtteranceMatched = new StringEvent();
|
||||
|
||||
private Regex regex;
|
||||
|
||||
protected override string OnValidateResponse(WitResponseNode response, bool isEarlyResponse)
|
||||
{
|
||||
var text = response["text"].Value;
|
||||
if (!IsMatch(text))
|
||||
{
|
||||
return "Required utterance does not match";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
protected override void OnResponseInvalid(WitResponseNode response, string error){}
|
||||
protected override void OnResponseSuccess(WitResponseNode response)
|
||||
{
|
||||
var text = response["text"].Value;
|
||||
onUtteranceMatched?.Invoke(text);
|
||||
}
|
||||
|
||||
private bool IsMatch(string text)
|
||||
{
|
||||
if (useRegex)
|
||||
{
|
||||
if (null == regex)
|
||||
{
|
||||
regex = new Regex(searchText, RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
var match = regex.Match(text);
|
||||
if (match.Success)
|
||||
{
|
||||
if (exactMatch && match.Value == text)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (exactMatch && text.ToLower() == searchText.ToLower())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (text.ToLower().Contains(searchText.ToLower()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0a93535f06eabe47bf93b4b504873c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c9bc9136c8441e48996d814209d4c2e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Meta.WitAi.Events;
|
||||
using Meta.WitAi.Interfaces;
|
||||
using Meta.WitAi.Lib;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
public class AudioBuffer : MonoBehaviour
|
||||
{
|
||||
#region Singleton
|
||||
private static AudioBuffer _instance;
|
||||
public static AudioBuffer Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_instance && Application.isPlaying)
|
||||
{
|
||||
_instance = FindObjectOfType<AudioBuffer>();
|
||||
if (!_instance)
|
||||
{
|
||||
var audioBufferObject = new GameObject("AudioBuffer");
|
||||
_instance = audioBufferObject.AddComponent<AudioBuffer>();
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
[SerializeField] private bool alwaysRecording;
|
||||
[SerializeField] private AudioBufferConfiguration audioBufferConfiguration = new AudioBufferConfiguration();
|
||||
[SerializeField] private AudioBufferEvents events = new AudioBufferEvents();
|
||||
|
||||
public AudioBufferEvents Events => events;
|
||||
|
||||
public IAudioInputSource MicInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_micInput == null && Application.isPlaying)
|
||||
{
|
||||
// Check this gameobject & it's children for audio input
|
||||
_micInput = gameObject.GetComponentInChildren<IAudioInputSource>();
|
||||
// Check all roots for Mic Input JIC
|
||||
if (_micInput == null)
|
||||
{
|
||||
foreach (var root in gameObject.scene.GetRootGameObjects())
|
||||
{
|
||||
_micInput = root.GetComponentInChildren<IAudioInputSource>();
|
||||
if (_micInput != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use default mic script
|
||||
if (_micInput == null)
|
||||
{
|
||||
_micInput = gameObject.AddComponent<Mic>();
|
||||
}
|
||||
}
|
||||
|
||||
return _micInput;
|
||||
}
|
||||
}
|
||||
private IAudioInputSource _micInput;
|
||||
private RingBuffer<byte> _micDataBuffer;
|
||||
|
||||
private byte[] _byteDataBuffer;
|
||||
|
||||
private HashSet<Component> _waitingRecorders = new HashSet<Component>();
|
||||
private HashSet<Component> _activeRecorders = new HashSet<Component>();
|
||||
|
||||
public bool IsRecording(Component component) => _waitingRecorders.Contains(component) || _activeRecorders.Contains(component);
|
||||
public bool IsInputAvailable => MicInput != null && MicInput.IsInputAvailable;
|
||||
public void CheckForInput() => MicInput.CheckForInput();
|
||||
public AudioEncoding AudioEncoding => MicInput.AudioEncoding;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
InitializeMicDataBuffer();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
MicInput.OnSampleReady += OnMicSampleReady;
|
||||
|
||||
if (alwaysRecording) StartRecording(this);
|
||||
}
|
||||
|
||||
// Remove mic delegates
|
||||
private void OnDisable()
|
||||
{
|
||||
MicInput.OnSampleReady -= OnMicSampleReady;
|
||||
|
||||
if (alwaysRecording) StopRecording(this);
|
||||
}
|
||||
|
||||
// Callback for mic sample ready
|
||||
private void OnMicSampleReady(int sampleCount, float[] sample, float levelMax)
|
||||
{
|
||||
events.OnMicLevelChanged.Invoke(levelMax);
|
||||
|
||||
var marker = CreateMarker();
|
||||
Convert(sample);
|
||||
if (null != events.OnByteDataReady)
|
||||
{
|
||||
marker.Clone().ReadIntoWriters(events.OnByteDataReady.Invoke);
|
||||
}
|
||||
events.OnSampleReady?.Invoke(marker, levelMax);
|
||||
}
|
||||
|
||||
// Generate mic data buffer if needed
|
||||
private void InitializeMicDataBuffer()
|
||||
{
|
||||
if (null == _micDataBuffer && audioBufferConfiguration.micBufferLengthInSeconds > 0)
|
||||
{
|
||||
var bufferSize = (int) Mathf.Ceil(2 *
|
||||
audioBufferConfiguration
|
||||
.micBufferLengthInSeconds * 1000 *
|
||||
audioBufferConfiguration.sampleLengthInMs);
|
||||
if (bufferSize <= 0)
|
||||
{
|
||||
bufferSize = 1024;
|
||||
}
|
||||
_micDataBuffer = new RingBuffer<byte>(bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert
|
||||
private void Convert(float[] samples)
|
||||
{
|
||||
var sampleCount = samples.Length;
|
||||
const int rescaleFactor = 32767; //to convert float to Int16
|
||||
|
||||
for (int i = 0; i < sampleCount; i++)
|
||||
{
|
||||
short data = (short) (samples[i] * rescaleFactor);
|
||||
_micDataBuffer.Push((byte) data);
|
||||
_micDataBuffer.Push((byte) (data >> 8));
|
||||
}
|
||||
}
|
||||
|
||||
public RingBuffer<byte>.Marker CreateMarker()
|
||||
{
|
||||
return _micDataBuffer.CreateMarker();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a marker with an offset
|
||||
/// </summary>
|
||||
/// <param name="offset">Number of seconds to offset the marker by</param>
|
||||
/// <returns></returns>
|
||||
public RingBuffer<byte>.Marker CreateMarker(float offset)
|
||||
{
|
||||
var samples = (int) (AudioEncoding.samplerate * offset);
|
||||
return _micDataBuffer.CreateMarker(samples);
|
||||
}
|
||||
|
||||
public void StartRecording(Component component)
|
||||
{
|
||||
StartCoroutine(WaitForMicToStart(component));
|
||||
}
|
||||
|
||||
private IEnumerator WaitForMicToStart(Component component)
|
||||
{
|
||||
// Wait for mic
|
||||
_waitingRecorders.Add(component);
|
||||
yield return new WaitUntil(() => null != MicInput && MicInput.IsInputAvailable);
|
||||
if (!_waitingRecorders.Contains(component))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
_waitingRecorders.Remove(component);
|
||||
|
||||
// Add component
|
||||
_activeRecorders.Add(component);
|
||||
// Start mic
|
||||
if (!MicInput.IsRecording)
|
||||
{
|
||||
MicInput.StartRecording(audioBufferConfiguration.sampleLengthInMs);
|
||||
}
|
||||
// On Start Listening
|
||||
if (component is IVoiceEventProvider v)
|
||||
{
|
||||
v.VoiceEvents.OnStartListening?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopRecording(Component component)
|
||||
{
|
||||
// Remove waiting recorder
|
||||
if (_waitingRecorders.Contains(component))
|
||||
{
|
||||
_waitingRecorders.Remove(component);
|
||||
return;
|
||||
}
|
||||
// Ignore unless active
|
||||
if (!_activeRecorders.Contains(component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove active recorder
|
||||
_activeRecorders.Remove(component);
|
||||
// Stop recording if last active recorder
|
||||
if (_activeRecorders.Count == 0)
|
||||
{
|
||||
MicInput.StopRecording();
|
||||
}
|
||||
// On Stop Listening
|
||||
if (component is IVoiceEventProvider v)
|
||||
{
|
||||
v.VoiceEvents.OnStoppedListening?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7b07c59a0c163b4d932f1b4a11b24f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
[Serializable]
|
||||
public class AudioBufferConfiguration
|
||||
{
|
||||
[Tooltip("The length of the individual samples read from the audio source")]
|
||||
[Range(10, 500)]
|
||||
[SerializeField]
|
||||
public int sampleLengthInMs = 10;
|
||||
|
||||
[Tooltip(
|
||||
"The total audio data that should be buffered for lookback purposes on sound based activations.")]
|
||||
[SerializeField]
|
||||
public float micBufferLengthInSeconds = 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dddc67743ac75b4f83ba080cafe1299
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d99f42b1387bffe4b845b1bf9f9cf5cb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Meta.WitAi.Configuration;
|
||||
using Meta.WitAi.Data.Info;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Meta.WitAi.Data.Configuration
|
||||
{
|
||||
public class WitConfiguration : ScriptableObject, IWitRequestConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Access token used in builds to make requests for data from Wit.ai
|
||||
/// </summary>
|
||||
[Tooltip("Access token used in builds to make requests for data from Wit.ai")]
|
||||
[FormerlySerializedAs("clientAccessToken")]
|
||||
[SerializeField] private string _clientAccessToken;
|
||||
|
||||
/// <summary>
|
||||
/// Application info
|
||||
/// </summary>
|
||||
[FormerlySerializedAs("application")]
|
||||
[SerializeField] private WitAppInfo _appInfo; //to be replaced by _configData
|
||||
|
||||
/// <summary>
|
||||
/// Configuration data about the app.
|
||||
/// </summary>
|
||||
[SerializeField] private WitConfigurationAssetData[] _configData;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration id
|
||||
/// </summary>
|
||||
[FormerlySerializedAs("configId")]
|
||||
[HideInInspector] [SerializeField] private string _configurationId;
|
||||
|
||||
[Tooltip("The number of milliseconds to wait before requests to Wit.ai will timeout")]
|
||||
[SerializeField] public int timeoutMS = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration parameters to set up a custom endpoint for testing purposes and request forwarding. The default values here will work for most.
|
||||
/// </summary>
|
||||
[Tooltip("Configuration parameters to set up a custom endpoint for testing purposes and request forwarding. The default values here will work for most.")]
|
||||
[SerializeField] public WitEndpointConfig endpointConfiguration = new WitEndpointConfig();
|
||||
|
||||
/// <summary>
|
||||
/// True if this configuration should not show up in the demo list
|
||||
/// </summary>
|
||||
[SerializeField] public bool isDemoOnly;
|
||||
|
||||
/// <summary>
|
||||
/// When set to true, will use Conduit to dispatch voice commands.
|
||||
/// </summary>
|
||||
[Tooltip("Conduit enables manifest-based dispatching to invoke callbacks with native types directly without requiring manual parsing.")]
|
||||
[SerializeField] public bool useConduit = true;
|
||||
|
||||
/// <summary>
|
||||
/// The path to the Conduit manifest.
|
||||
/// </summary>
|
||||
[SerializeField] private string _manifestLocalPath;
|
||||
|
||||
/// <summary>
|
||||
/// The assemblies that we want to exclude from Conduit.
|
||||
/// </summary>
|
||||
[SerializeField] public List<string> excludedAssemblies = new List<string>
|
||||
{
|
||||
"Oculus.Voice.Demo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
|
||||
"Meta.WitAi.Samples, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
};
|
||||
|
||||
[Tooltip("When true, Conduit will attempt to match incoming requests by type when no exact matches are found. This increases tolerance but reduces runtime performance.")]
|
||||
[SerializeField] public bool relaxedResolution;
|
||||
|
||||
/// <summary>
|
||||
/// Safe access of local path
|
||||
/// </summary>
|
||||
public string ManifestLocalPath
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (string.IsNullOrEmpty(_manifestLocalPath))
|
||||
{
|
||||
_manifestLocalPath = $"ConduitManifest-{Guid.NewGuid()}.json";
|
||||
SaveConfiguration();
|
||||
}
|
||||
#endif
|
||||
return _manifestLocalPath;
|
||||
}
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Returns manifest full editor path
|
||||
/// </summary>
|
||||
public string GetManifestEditorPath()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_manifestLocalPath)) return string.Empty;
|
||||
|
||||
string lookup = Path.GetFileNameWithoutExtension(_manifestLocalPath);
|
||||
string[] guids = UnityEditor.AssetDatabase.FindAssets(lookup);
|
||||
if (guids != null && guids.Length > 0)
|
||||
{
|
||||
return UnityEditor.AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Reset all data
|
||||
/// </summary>
|
||||
public void ResetData()
|
||||
{
|
||||
_configurationId = null;
|
||||
_appInfo = new WitAppInfo();
|
||||
endpointConfiguration = new WitEndpointConfig();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the individual data components of the configuration.
|
||||
/// </summary>
|
||||
public void UpdateDataAssets()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
RefreshPlugins();
|
||||
#endif
|
||||
|
||||
foreach (WitConfigurationAssetData data in _configData)
|
||||
{
|
||||
data.Refresh(this);
|
||||
}
|
||||
}
|
||||
// Logger invalid warnings
|
||||
private const string INVALID_APP_ID_NO_CLIENT_TOKEN = "App Info Not Set - No Client Token";
|
||||
private const string INVALID_APP_ID_WITH_CLIENT_TOKEN =
|
||||
"App Info Not Set - Has Client Token";
|
||||
public string GetLoggerAppId()
|
||||
{
|
||||
// Get application id
|
||||
string applicationId = GetApplicationId();
|
||||
if (String.IsNullOrEmpty(applicationId))
|
||||
{
|
||||
// NOTE: If a dev only provides a client token we may not have the application id.
|
||||
string clientAccessToken = GetClientAccessToken();
|
||||
if (!string.IsNullOrEmpty(clientAccessToken))
|
||||
{
|
||||
return INVALID_APP_ID_WITH_CLIENT_TOKEN;
|
||||
}
|
||||
return INVALID_APP_ID_NO_CLIENT_TOKEN;
|
||||
}
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
#region IWitRequestConfiguration
|
||||
/// <summary>
|
||||
/// Returns unique configuration guid
|
||||
/// </summary>
|
||||
public string GetConfigurationId()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Ensure configuration id is generated
|
||||
if (string.IsNullOrEmpty(_configurationId))
|
||||
{
|
||||
_configurationId = Guid.NewGuid().ToString();
|
||||
}
|
||||
#endif
|
||||
// Return configuration id
|
||||
return _configurationId;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns unique application id
|
||||
/// </summary>
|
||||
public string GetApplicationId() => _appInfo.id;
|
||||
/// <summary>
|
||||
/// Returns application info
|
||||
/// </summary>
|
||||
public WitAppInfo GetApplicationInfo() => _appInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the configuration data for this app.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public WitConfigurationAssetData[] GetConfigData()
|
||||
{
|
||||
if (_configData == null)
|
||||
{
|
||||
_configData = Array.Empty<WitConfigurationAssetData>();
|
||||
}
|
||||
return _configData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return endpoint override
|
||||
/// </summary>
|
||||
public IWitRequestEndpointInfo GetEndpointInfo() => endpointConfiguration;
|
||||
/// <summary>
|
||||
/// Returns client access token
|
||||
/// </summary>
|
||||
public string GetClientAccessToken()
|
||||
{
|
||||
return _clientAccessToken;
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Editor only setter
|
||||
/// </summary>
|
||||
public void SetClientAccessToken(string newToken)
|
||||
{
|
||||
_clientAccessToken = newToken;
|
||||
SaveConfiguration();
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns server access token (Editor Only)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public string GetServerAccessToken()
|
||||
{
|
||||
return WitAuthUtility.GetAppServerToken(GetApplicationId());
|
||||
}
|
||||
/// <summary>
|
||||
/// Set application info
|
||||
/// </summary>
|
||||
public void SetApplicationInfo(WitAppInfo newInfo)
|
||||
{
|
||||
_appInfo = newInfo;
|
||||
SaveConfiguration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the plugin-specific data for this WitConfiguration
|
||||
/// </summary>
|
||||
public void SetConfigData(WitConfigurationAssetData[] configData)
|
||||
{
|
||||
_configData = configData;
|
||||
}
|
||||
// Save this configuration asset
|
||||
private void SaveConfiguration()
|
||||
{
|
||||
EditorUtility.SetDirty(this);
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
AssetDatabase.SaveAssetIfDirty(this);
|
||||
#else
|
||||
AssetDatabase.SaveAssets();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void RefreshPlugins()
|
||||
{
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
// Find all derived data types
|
||||
List<Type> dataPlugins = typeof(WitConfigurationAssetData).GetSubclassTypes();
|
||||
|
||||
// Create instances of the types and register them
|
||||
List<WitConfigurationAssetData> newConfigs = new List<WitConfigurationAssetData>();
|
||||
var configurationAssetPath = AssetDatabase.GetAssetPath(this);
|
||||
foreach (Type dataType in dataPlugins)
|
||||
{
|
||||
|
||||
// Grab existing if present
|
||||
var plugin = (WitConfigurationAssetData)AssetDatabase.LoadAssetAtPath(configurationAssetPath, dataType);
|
||||
// Generate instance & add to asset
|
||||
if (plugin == null)
|
||||
{
|
||||
plugin = (WitConfigurationAssetData)CreateInstance(dataType);
|
||||
plugin.name = dataType.Name;
|
||||
AssetDatabase.AddObjectToAsset(plugin, configurationAssetPath);
|
||||
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(plugin));
|
||||
plugin = (WitConfigurationAssetData)AssetDatabase.LoadAssetAtPath(configurationAssetPath, dataType);
|
||||
}
|
||||
newConfigs.Add(plugin);
|
||||
}
|
||||
SetConfigData(newConfigs.ToArray());
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae5a46bda3295124c99b0e6537ac7252
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using Meta.WitAi.Data.Configuration;
|
||||
|
||||
namespace Meta.WitAi.Configuration
|
||||
{
|
||||
[Serializable]
|
||||
public class WitEndpointConfig : IWitRequestEndpointInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Customized uri scheme (Ex. https)
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("uriScheme")]
|
||||
private string _uriScheme;
|
||||
public string UriScheme => string.IsNullOrEmpty(_uriScheme) ? WitConstants.URI_SCHEME : _uriScheme;
|
||||
|
||||
/// <summary>
|
||||
/// Customized host location (Ex. api.wit.ai)
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("authority")]
|
||||
private string _authority;
|
||||
public string Authority =>
|
||||
string.IsNullOrEmpty(_authority) ? WitConstants.URI_AUTHORITY : _authority;
|
||||
|
||||
/// <summary>
|
||||
/// Customized host port (Ex. api.wit.ai)
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("port")]
|
||||
private int _port;
|
||||
public int Port => _port <= 0 ? WitConstants.URI_DEFAULT_PORT : _port;
|
||||
|
||||
/// <summary>
|
||||
/// API version to be used for this endpoint. Defaults to sdk default version
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("witApiVersion")]
|
||||
private string _witApiVersion;
|
||||
public string WitApiVersion => string.IsNullOrEmpty(_witApiVersion)
|
||||
? WitConstants.API_VERSION
|
||||
: _witApiVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint used for text based voice command. Defaults to 'message'
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("message")]
|
||||
private string _message;
|
||||
public string Message =>
|
||||
string.IsNullOrEmpty(_message) ? WitConstants.ENDPOINT_MESSAGE : _message;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint used for audio based voice command. Defaults to 'speech'
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("speech")]
|
||||
private string _speech;
|
||||
public string Speech =>
|
||||
string.IsNullOrEmpty(_speech) ? WitConstants.ENDPOINT_SPEECH : _speech;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint used for audio based transcription. Defaults to 'dictation'
|
||||
/// </summary>
|
||||
[SerializeField] [FormerlySerializedAs("dictation")]
|
||||
private string _dictation;
|
||||
public string Dictation => string.IsNullOrEmpty(_dictation) ? WitConstants.ENDPOINT_DICTATION : _dictation;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint used for Text-To-Speech. Defaults to 'synthesize'
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private string _synthesize;
|
||||
public string Synthesize => string.IsNullOrEmpty(_synthesize) ? WitConstants.ENDPOINT_TTS : _synthesize;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint used for Composer text requests. Defaults to 'event'
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private string _event;
|
||||
public string Event => string.IsNullOrEmpty(_event) ? WitConstants.ENDPOINT_COMPOSER_MESSAGE : _event;
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint used for Composer audio requests. Defaults to 'converse'
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
private string _converse;
|
||||
public string Converse => string.IsNullOrEmpty(_converse) ? WitConstants.ENDPOINT_COMPOSER_SPEECH : _converse;
|
||||
|
||||
// Default endpoint data
|
||||
private static WitEndpointConfig defaultEndpointConfig = new WitEndpointConfig();
|
||||
|
||||
/// <summary>
|
||||
/// Generates a configuration using a preset if possible
|
||||
/// </summary>
|
||||
public static WitEndpointConfig GetEndpointConfig(WitConfiguration witConfig)
|
||||
{
|
||||
return witConfig && null != witConfig.endpointConfiguration
|
||||
? witConfig.endpointConfiguration
|
||||
: defaultEndpointConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61a0415bfdfa4d64e89801fbc0b30ec7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Requests;
|
||||
using Meta.WitAi.Interfaces;
|
||||
|
||||
namespace Meta.WitAi.Configuration
|
||||
{
|
||||
public class WitRequestOptions : VoiceServiceRequestOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that provides a list of entities that should be used for nlu resolution.
|
||||
/// </summary>
|
||||
public IDynamicEntitiesProvider dynamicEntities;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of intent matches to return
|
||||
/// </summary>
|
||||
public int nBestIntents = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The tag for snapshot
|
||||
/// </summary>
|
||||
public string tag;
|
||||
|
||||
/// <summary>
|
||||
/// Formerly used for request id
|
||||
/// </summary>
|
||||
[Obsolete("Use 'RequestId' property instead")] [JsonIgnore]
|
||||
public string requestID => RequestId;
|
||||
|
||||
/// <summary>
|
||||
/// Callback for completion
|
||||
/// </summary>
|
||||
public Action<WitRequest> onResponse;
|
||||
|
||||
// Get json string. Used to get the payload for PI.
|
||||
// PI will reparse these parameters and construct it's own request.
|
||||
public string ToJsonString()
|
||||
{
|
||||
Dictionary<string, string> parameters = new Dictionary<string, string>();
|
||||
parameters["nBestIntents"] = nBestIntents.ToString();
|
||||
parameters["tag"] = tag;
|
||||
parameters["requestID"] = RequestId;
|
||||
foreach (var key in QueryParams.Keys)
|
||||
{
|
||||
parameters[key] = QueryParams[key];
|
||||
}
|
||||
return JsonConvert.SerializeObject(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6834fd3c55fb41a1885302e6043f5d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Data.Configuration;
|
||||
using Meta.WitAi.Interfaces;
|
||||
using Meta.WitAi.Utilities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Meta.WitAi.Configuration
|
||||
{
|
||||
[Serializable]
|
||||
public class WitRuntimeConfiguration
|
||||
{
|
||||
[Tooltip("Configuration for the application used in this instance of Wit.ai services")]
|
||||
[SerializeField]
|
||||
public WitConfiguration witConfiguration;
|
||||
|
||||
[Header("Keepalive")]
|
||||
[Tooltip("The minimum volume from the mic needed to keep the activation alive")]
|
||||
[SerializeField]
|
||||
public float minKeepAliveVolume = .0005f;
|
||||
|
||||
[FormerlySerializedAs("minKeepAliveTime")]
|
||||
[Tooltip(
|
||||
"The amount of time in seconds an activation will be kept open after volume is under the keep alive threshold")]
|
||||
[SerializeField]
|
||||
[DynamicRange("RecordingTimeRange")]
|
||||
public float minKeepAliveTimeInSeconds = 2f;
|
||||
|
||||
[FormerlySerializedAs("minTranscriptionKeepAliveTime")]
|
||||
[Tooltip(
|
||||
"The amount of time in seconds an activation will be kept open after words have been detected in the live transcription")]
|
||||
[SerializeField]
|
||||
[DynamicRange("RecordingTimeRange")]
|
||||
public float minTranscriptionKeepAliveTimeInSeconds = 1f;
|
||||
|
||||
[Tooltip("The maximum amount of time in seconds the mic will stay active")]
|
||||
[SerializeField]
|
||||
[DynamicRange("RecordingTimeRange")]
|
||||
public float maxRecordingTime = 20;
|
||||
|
||||
protected virtual Vector2 RecordingTimeRange => new Vector2(0, 20);
|
||||
|
||||
[Header("Sound Activation")]
|
||||
[Tooltip("The minimum volume level needed to be heard to start collecting data from the audio source.")]
|
||||
[SerializeField] public float soundWakeThreshold = .0005f;
|
||||
|
||||
[Tooltip("The length of the individual samples read from the audio source")]
|
||||
[Range(10, 500)] [SerializeField] public int sampleLengthInMs = 10;
|
||||
|
||||
[Tooltip("The total audio data that should be buffered for lookback purposes on sound based activations.")]
|
||||
[SerializeField] public float micBufferLengthInSeconds = 1;
|
||||
|
||||
[Tooltip("The maximum amount of concurrent requests that can occur")]
|
||||
[Range(1, 10)] [SerializeField] public int maxConcurrentRequests = 5;
|
||||
|
||||
[Header("Custom Transcription")]
|
||||
[Tooltip(
|
||||
"If true, the audio recorded in the activation will be sent to Wit.ai for processing. If a custom transcription provider is set and this is false, only the transcription will be sent to Wit.ai for processing")]
|
||||
[SerializeField]
|
||||
public bool sendAudioToWit = true;
|
||||
|
||||
[Tooltip("A custom provider that returns text to be used for nlu processing on activation instead of sending audio.")]
|
||||
[SerializeField] public CustomTranscriptionProvider customTranscriptionProvider;
|
||||
|
||||
[Tooltip("If always record is set the mic will fill the mic data buffer as long as the component is enabled in the scene.")]
|
||||
public bool alwaysRecord;
|
||||
|
||||
[Tooltip("The preferred number of seconds to offset from the time the activation happens. A negative value here could help to catch any words that may have been cut off at the beginning of an activation (assuming input is already being read into the buffer)")]
|
||||
public float preferredActivationOffset = -.5f;
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd8d40c9f75b44b5940fcc21769d6af0
|
||||
timeCreated: 1629397017
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d92a289db3a8408dba9dd973090b1ade
|
||||
timeCreated: 1632287743
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
public class DynamicEntityDataProvider : MonoBehaviour, IDynamicEntitiesProvider
|
||||
{
|
||||
[SerializeField] internal WitDynamicEntitiesData[] entitiesDefinition;
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
WitDynamicEntities entities = new WitDynamicEntities();
|
||||
foreach (var entity in entitiesDefinition)
|
||||
{
|
||||
entities.Merge(entity);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b4e835dcc764fee99862c3c535ab5fa
|
||||
timeCreated: 1646775302
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
public class DynamicEntityProvider : MonoBehaviour, IDynamicEntitiesProvider
|
||||
{
|
||||
[SerializeField] protected WitDynamicEntities entities;
|
||||
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b789a872764a60545972d2f4505ead38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b9f5c6540348cd41a3f48d0e20057db
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
using Meta.WitAi.Data.Info;
|
||||
using Meta.WitAi.Interfaces;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Singleton registry for tracking any objects owned defined in entities in
|
||||
/// a scene
|
||||
/// </summary>
|
||||
public class DynamicEntityKeywordRegistry : MonoBehaviour, IDynamicEntitiesProvider
|
||||
{
|
||||
private static DynamicEntityKeywordRegistry instance;
|
||||
|
||||
private WitDynamicEntities entities = new WitDynamicEntities();
|
||||
|
||||
public static bool HasDynamicEntityRegistry => Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance in the scene if there is one
|
||||
/// </summary>
|
||||
public static DynamicEntityKeywordRegistry Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!instance)
|
||||
{
|
||||
instance = FindObjectOfType<DynamicEntityKeywordRegistry>();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
instance = null;
|
||||
}
|
||||
|
||||
public void RegisterDynamicEntity(string entity, WitEntityKeywordInfo keyword)
|
||||
{
|
||||
entities.AddKeyword(entity, keyword);
|
||||
}
|
||||
|
||||
public void UnregisterDynamicEntity(string entity, WitEntityKeywordInfo keyword)
|
||||
{
|
||||
entities.RemoveKeyword(entity, keyword);
|
||||
}
|
||||
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7faff460c1b46b34481ecb99327be2b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
using Meta.WitAi.Data.Info;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// A configured dynamic entity meant to be placed on dynamic objects.
|
||||
/// when the object is enabled this entity will be registered with active
|
||||
/// voice services on activation.
|
||||
/// </summary>
|
||||
public class RegisteredDynamicEntityKeyword : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private string entity;
|
||||
[SerializeField] private WitEntityKeywordInfo keyword;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (string.IsNullOrEmpty(keyword.keyword)) return;
|
||||
if (string.IsNullOrEmpty(entity)) return;
|
||||
|
||||
if (DynamicEntityKeywordRegistry.HasDynamicEntityRegistry)
|
||||
{
|
||||
DynamicEntityKeywordRegistry.Instance.RegisterDynamicEntity(entity, keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
VLog.W($"Cannot register {name}: No dynamic entity registry present in the scene." +
|
||||
$"Please add one and try again.");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (string.IsNullOrEmpty(keyword.keyword)) return;
|
||||
if (string.IsNullOrEmpty(entity)) return;
|
||||
|
||||
if (DynamicEntityKeywordRegistry.HasDynamicEntityRegistry)
|
||||
{
|
||||
DynamicEntityKeywordRegistry.Instance.UnregisterDynamicEntity(entity, keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 314acb2f0d34f4d4b9a72bed29e990d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Meta.WitAi.Interfaces;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Data.Info;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
[Serializable]
|
||||
public class WitDynamicEntities : IDynamicEntitiesProvider, IEnumerable<WitDynamicEntity>
|
||||
{
|
||||
public List<WitDynamicEntity> entities = new List<WitDynamicEntity>();
|
||||
|
||||
public WitDynamicEntities()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public WitDynamicEntities(IEnumerable<WitDynamicEntity> entity)
|
||||
{
|
||||
entities.AddRange(entity);
|
||||
}
|
||||
|
||||
public WitDynamicEntities(params WitDynamicEntity[] entity)
|
||||
{
|
||||
entities.AddRange(entity);
|
||||
}
|
||||
|
||||
public WitResponseClass AsJson
|
||||
{
|
||||
get
|
||||
{
|
||||
WitResponseClass json = new WitResponseClass();
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
json.Add(entity.entity, entity.AsJson);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return AsJson.ToString();
|
||||
}
|
||||
|
||||
public IEnumerator<WitDynamicEntity> GetEnumerator() => entities.GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Merge(IDynamicEntitiesProvider provider)
|
||||
{
|
||||
if (null == provider) return;
|
||||
|
||||
entities.AddRange(provider.GetDynamicEntities());
|
||||
}
|
||||
|
||||
public void Merge(IEnumerable<WitDynamicEntity> mergeEntities)
|
||||
{
|
||||
if (null == mergeEntities) return;
|
||||
|
||||
entities.AddRange(mergeEntities);
|
||||
}
|
||||
|
||||
public void Add(WitDynamicEntity dynamicEntity)
|
||||
{
|
||||
int index = entities.FindIndex(e => e.entity == dynamicEntity.entity);
|
||||
if(index < 0) entities.Add(dynamicEntity);
|
||||
else VLog.W($"Cannot add entity, registry already has an entry for {dynamicEntity.entity}");
|
||||
}
|
||||
|
||||
public void Remove(WitDynamicEntity dynamicEntity)
|
||||
{
|
||||
entities.Remove(dynamicEntity);
|
||||
}
|
||||
|
||||
public void AddKeyword(string entityName, WitEntityKeywordInfo keyword)
|
||||
{
|
||||
var entity = entities.Find(e => entityName == e.entity);
|
||||
if (null == entity)
|
||||
{
|
||||
entity = new WitDynamicEntity(entityName);
|
||||
entities.Add(entity);
|
||||
}
|
||||
entity.keywords.Add(keyword);
|
||||
}
|
||||
|
||||
public void RemoveKeyword(string entityName, WitEntityKeywordInfo keyword)
|
||||
{
|
||||
int index = entities.FindIndex(e => e.entity == entityName);
|
||||
if (index >= 0)
|
||||
{
|
||||
entities[index].keywords.Remove(keyword);
|
||||
if(entities[index].keywords.Count == 0) entities.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a296282c67dc244dd974baca4699c554
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
public class WitDynamicEntitiesData : ScriptableObject, IDynamicEntitiesProvider
|
||||
{
|
||||
public WitDynamicEntities entities;
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86f432dec1a4be34792c2afdea52bb2d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Meta.WitAi.Interfaces;
|
||||
using Meta.WitAi.Json;
|
||||
using Meta.WitAi.Data.Info;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
[Serializable]
|
||||
public class WitDynamicEntity : IDynamicEntitiesProvider
|
||||
{
|
||||
public string entity;
|
||||
public List<WitEntityKeywordInfo> keywords = new List<WitEntityKeywordInfo>();
|
||||
|
||||
public WitDynamicEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public WitDynamicEntity(string entity, WitEntityKeywordInfo keyword)
|
||||
{
|
||||
this.entity = entity;
|
||||
this.keywords.Add(keyword);
|
||||
}
|
||||
|
||||
public WitDynamicEntity(string entity, params string[] keywords)
|
||||
{
|
||||
this.entity = entity;
|
||||
foreach (var keyword in keywords)
|
||||
{
|
||||
this.keywords.Add(new WitEntityKeywordInfo()
|
||||
{
|
||||
keyword = keyword,
|
||||
synonyms = new List<string>(new string[] { keyword })
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public WitDynamicEntity(string entity, Dictionary<string, List<string>> keywordsToSynonyms)
|
||||
{
|
||||
this.entity = entity;
|
||||
|
||||
foreach (var synonym in keywordsToSynonyms)
|
||||
{
|
||||
keywords.Add(new WitEntityKeywordInfo()
|
||||
{
|
||||
keyword = synonym.Key,
|
||||
synonyms = synonym.Value
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public WitResponseArray AsJson
|
||||
{
|
||||
get
|
||||
{
|
||||
return JsonConvert.SerializeToken(keywords).AsArray;
|
||||
}
|
||||
}
|
||||
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
return new WitDynamicEntities()
|
||||
{
|
||||
entities = new List<WitDynamicEntity>
|
||||
{
|
||||
this
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efe24d6c4ed424d25a19396c7a2eec38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
public abstract class WitEntityDataBase<T>
|
||||
{
|
||||
public WitResponseNode responseNode;
|
||||
public string id;
|
||||
public string name;
|
||||
public string role;
|
||||
|
||||
public int start;
|
||||
public int end;
|
||||
|
||||
public string type;
|
||||
|
||||
public string body;
|
||||
public T value;
|
||||
|
||||
public float confidence;
|
||||
|
||||
public bool hasData;
|
||||
|
||||
public WitResponseArray entities;
|
||||
|
||||
[Preserve]
|
||||
public WitEntityDataBase<T> FromEntityWitResponseNode(WitResponseNode node)
|
||||
{
|
||||
responseNode = node;
|
||||
WitEntityDataBase<T> result = this;
|
||||
JsonConvert.DeserializeIntoObject(ref result, node);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class WitEntityData : WitEntityDataBase<string>
|
||||
{
|
||||
[Preserve]
|
||||
public WitEntityData() {}
|
||||
|
||||
[Preserve]
|
||||
public WitEntityData(WitResponseNode node)
|
||||
{
|
||||
FromEntityWitResponseNode(node);
|
||||
}
|
||||
|
||||
public static implicit operator bool(WitEntityData data) => null != data && !string.IsNullOrEmpty(data.value);
|
||||
public static implicit operator string(WitEntityData data) => data.value;
|
||||
public static bool operator ==(WitEntityData data, object value) => Equals(data?.value, value);
|
||||
public static bool operator !=(WitEntityData data, object value) => !Equals(data?.value, value);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is string s) return s == value;
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class WitEntityFloatData : WitEntityDataBase<float>
|
||||
{
|
||||
[Preserve]
|
||||
public WitEntityFloatData() {}
|
||||
|
||||
[Preserve]
|
||||
public WitEntityFloatData(WitResponseNode node)
|
||||
{
|
||||
FromEntityWitResponseNode(node);
|
||||
}
|
||||
|
||||
public static implicit operator bool(WitEntityFloatData data) =>
|
||||
null != data && data.hasData;
|
||||
|
||||
public bool Approximately(float v, float tolerance = .001f) => Math.Abs(v - value) < tolerance;
|
||||
public static bool operator ==(WitEntityFloatData data, float value) => data?.value == value;
|
||||
public static bool operator !=(WitEntityFloatData data, float value) => !(data == value);
|
||||
public static bool operator ==(WitEntityFloatData data, int value) => data?.value == value;
|
||||
public static bool operator !=(WitEntityFloatData data, int value) => !(data == value);
|
||||
public static bool operator ==(float value, WitEntityFloatData data) => data?.value == value;
|
||||
public static bool operator !=(float value, WitEntityFloatData data) => !(data == value);
|
||||
public static bool operator ==(int value, WitEntityFloatData data) => data?.value == value;
|
||||
public static bool operator !=(int value, WitEntityFloatData data) => !(data == value);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is float f) return f == value;
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class WitEntityIntData : WitEntityDataBase<int>
|
||||
{
|
||||
[Preserve]
|
||||
public WitEntityIntData() {}
|
||||
|
||||
[Preserve]
|
||||
public WitEntityIntData(WitResponseNode node)
|
||||
{
|
||||
FromEntityWitResponseNode(node);
|
||||
}
|
||||
|
||||
public static implicit operator bool(WitEntityIntData data) =>
|
||||
null != data && data.hasData;
|
||||
public static bool operator ==(WitEntityIntData data, int value) => data?.value == value;
|
||||
public static bool operator !=(WitEntityIntData data, int value) => !(data == value);
|
||||
public static bool operator ==(int value, WitEntityIntData data) => data?.value == value;
|
||||
public static bool operator !=(int value, WitEntityIntData data) => !(data == value);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is int i) return i == value;
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50471c3e54af4dc1adc8cab506b1e28e
|
||||
timeCreated: 1646062595
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data.Entities
|
||||
{
|
||||
public class WitSimpleDynamicEntity : MonoBehaviour, IDynamicEntitiesProvider
|
||||
{
|
||||
[SerializeField] private string entityName;
|
||||
[SerializeField] private string[] keywords;
|
||||
|
||||
public WitDynamicEntities GetDynamicEntities()
|
||||
{
|
||||
var entity = new WitDynamicEntity(entityName, keywords);
|
||||
var entities = new WitDynamicEntities(entity);
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e15f31f7f3b6c49fb96d0553d125fe22
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7de07ce5d8884e15924606bffef7ed67
|
||||
timeCreated: 1632287863
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Json;
|
||||
|
||||
namespace Meta.WitAi.Data.Intents
|
||||
{
|
||||
public class WitIntentData
|
||||
{
|
||||
public WitResponseNode responseNode;
|
||||
|
||||
public string id;
|
||||
public string name;
|
||||
public float confidence;
|
||||
|
||||
public WitIntentData() {}
|
||||
|
||||
public WitIntentData(WitResponseNode node)
|
||||
{
|
||||
FromIntentWitResponseNode(node);
|
||||
}
|
||||
|
||||
public WitIntentData FromIntentWitResponseNode(WitResponseNode node)
|
||||
{
|
||||
WitIntentData result = this;
|
||||
JsonConvert.DeserializeIntoObject(ref result, node);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa212f2366174f8a900d2f10b9402ac9
|
||||
timeCreated: 1646062501
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
public class RingBuffer<T>
|
||||
{
|
||||
public delegate void OnDataAdded(T[] data, int offset, int length);
|
||||
public delegate void ByteDataWriter(T[] buffer, int offset, int length);
|
||||
|
||||
|
||||
public OnDataAdded OnDataAddedEvent;
|
||||
|
||||
private readonly T[] buffer;
|
||||
private int bufferIndex;
|
||||
private long bufferDataLength;
|
||||
public int Capacity => buffer.Length;
|
||||
|
||||
public int GetBufferArrayIndex(long bufferDataIndex)
|
||||
{
|
||||
if (bufferDataLength <= bufferDataIndex) return -1;
|
||||
if (bufferDataLength - bufferDataIndex > buffer.Length) return -1;
|
||||
|
||||
var endOffset = bufferDataLength - bufferDataIndex;
|
||||
var index = bufferIndex - endOffset;
|
||||
if (index < 0) index = buffer.Length + index;
|
||||
return (int) index;
|
||||
}
|
||||
|
||||
public T this[long bufferDataIndex] => buffer[GetBufferArrayIndex(bufferDataIndex)];
|
||||
|
||||
public void Clear(bool eraseData = false)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
bufferDataLength = 0;
|
||||
|
||||
if (eraseData)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
{
|
||||
buffer[i] = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Marker
|
||||
{
|
||||
private long bufferDataIndex;
|
||||
private int index;
|
||||
private readonly RingBuffer<T> ringBuffer;
|
||||
|
||||
public RingBuffer<T> RingBuffer => ringBuffer;
|
||||
|
||||
public Marker(RingBuffer<T> ringBuffer, long markerPosition, int bufIndex)
|
||||
{
|
||||
this.ringBuffer = ringBuffer;
|
||||
bufferDataIndex = markerPosition;
|
||||
index = bufIndex;
|
||||
}
|
||||
|
||||
public bool IsValid => ringBuffer.bufferDataLength - bufferDataIndex <= ringBuffer.Capacity;
|
||||
public long AvailableByteCount => Math.Min(ringBuffer.Capacity, RequestedByteCount);
|
||||
public long RequestedByteCount => ringBuffer.bufferDataLength - bufferDataIndex;
|
||||
public long CurrentBufferDataIndex => bufferDataIndex;
|
||||
|
||||
public int Read(T[] buffer, int offset, int length, bool skipToNextValid = false)
|
||||
{
|
||||
int read = -1;
|
||||
if (!IsValid && skipToNextValid && ringBuffer.bufferDataLength > ringBuffer.Capacity)
|
||||
{
|
||||
bufferDataIndex = ringBuffer.bufferDataLength - ringBuffer.Capacity;
|
||||
}
|
||||
|
||||
if (IsValid)
|
||||
{
|
||||
read = this.ringBuffer.Read(buffer, offset, length, bufferDataIndex);
|
||||
bufferDataIndex += read;
|
||||
index += read;
|
||||
if (index > buffer.Length) index -= buffer.Length;
|
||||
}
|
||||
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
public void ReadIntoWriters(params ByteDataWriter[] writers)
|
||||
{
|
||||
if (!IsValid && ringBuffer.bufferDataLength > ringBuffer.Capacity)
|
||||
{
|
||||
bufferDataIndex = ringBuffer.bufferDataLength - ringBuffer.Capacity;
|
||||
}
|
||||
|
||||
index = ringBuffer.GetBufferArrayIndex(bufferDataIndex);
|
||||
var length = (int) (ringBuffer.bufferDataLength - bufferDataIndex);
|
||||
if (IsValid && length > 0)
|
||||
{
|
||||
for (int i = 0; i < writers.Length; i++)
|
||||
{
|
||||
ringBuffer.WriteFromBuffer(writers[i], index, length);
|
||||
}
|
||||
}
|
||||
|
||||
bufferDataIndex += length;
|
||||
index = ringBuffer.GetBufferArrayIndex(bufferDataIndex);
|
||||
}
|
||||
|
||||
public Marker Clone()
|
||||
{
|
||||
return new Marker(ringBuffer, bufferDataIndex, index);
|
||||
}
|
||||
|
||||
public void Offset(int amount)
|
||||
{
|
||||
bufferDataIndex += amount;
|
||||
if (bufferDataIndex < 0) bufferDataIndex = 0;
|
||||
if (bufferDataIndex > ringBuffer.bufferDataLength)
|
||||
{
|
||||
bufferDataIndex = ringBuffer.bufferDataLength;
|
||||
}
|
||||
|
||||
index = ringBuffer.GetBufferArrayIndex(bufferDataIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public RingBuffer(int capacity)
|
||||
{
|
||||
buffer = new T[capacity];
|
||||
}
|
||||
|
||||
private int CopyToBuffer(T[] data, int offset, int length, int bufferIndex)
|
||||
{
|
||||
if (length > buffer.Length)
|
||||
throw new ArgumentException(
|
||||
"Push data exceeds buffer size.");
|
||||
|
||||
if (bufferIndex + length < buffer.Length)
|
||||
{
|
||||
Array.Copy(data, offset, buffer, bufferIndex, length);
|
||||
return bufferIndex + length;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = Mathf.Min(length, buffer.Length);
|
||||
int endChunkLength = buffer.Length - bufferIndex;
|
||||
int wrappedChunkLength = len - endChunkLength;
|
||||
try
|
||||
{
|
||||
|
||||
Array.Copy(data, offset, buffer, bufferIndex, endChunkLength);
|
||||
Array.Copy(data, offset + endChunkLength, buffer, 0, wrappedChunkLength);
|
||||
return wrappedChunkLength;
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteFromBuffer(ByteDataWriter writer, long bufferIndex, int length)
|
||||
{
|
||||
lock (buffer)
|
||||
{
|
||||
if (bufferIndex + length < buffer.Length)
|
||||
{
|
||||
writer(buffer, (int) bufferIndex, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (length > bufferDataLength)
|
||||
{
|
||||
length = (int) (bufferDataLength - bufferIndex);
|
||||
}
|
||||
|
||||
if (length > buffer.Length)
|
||||
{
|
||||
length = buffer.Length;
|
||||
}
|
||||
|
||||
var l = Math.Min(buffer.Length, length);
|
||||
int endChunkLength = (int) (buffer.Length - bufferIndex);
|
||||
int wrappedChunkLength = l - endChunkLength;
|
||||
|
||||
writer(buffer, (int) bufferIndex, endChunkLength);
|
||||
writer(buffer, 0, wrappedChunkLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int CopyFromBuffer(T[] data, int offset, int length, int bufferIndex)
|
||||
{
|
||||
if (length > buffer.Length)
|
||||
throw new ArgumentException(
|
||||
$"Push data exceeds buffer size {length} < {buffer.Length}" );
|
||||
|
||||
if (bufferIndex + length < buffer.Length)
|
||||
{
|
||||
Array.Copy(buffer, bufferIndex, data, offset, length);
|
||||
return bufferIndex + length;
|
||||
}
|
||||
else
|
||||
{
|
||||
var l = Mathf.Min(buffer.Length, length);
|
||||
int endChunkLength = buffer.Length - bufferIndex;
|
||||
int wrappedChunkLength = l - endChunkLength;
|
||||
|
||||
Array.Copy(buffer, bufferIndex, data, offset, endChunkLength);
|
||||
Array.Copy(buffer, 0, data, offset + endChunkLength, wrappedChunkLength);
|
||||
return wrappedChunkLength;
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(T[] data, int offset, int length)
|
||||
{
|
||||
lock (buffer)
|
||||
{
|
||||
bufferIndex = CopyToBuffer(data, offset, length, bufferIndex);
|
||||
bufferDataLength += length;
|
||||
OnDataAddedEvent?.Invoke(data, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(T data)
|
||||
{
|
||||
lock (buffer)
|
||||
{
|
||||
buffer[bufferIndex++] = data;
|
||||
if (bufferIndex >= buffer.Length)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
bufferDataLength++;
|
||||
}
|
||||
}
|
||||
|
||||
public int Read(T[] data, int offset, int length, long bufferDataIndex)
|
||||
{
|
||||
if (bufferIndex == 0 && bufferDataLength == 0) // The ring buffer has been cleared.
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
lock (buffer)
|
||||
{
|
||||
int read = (int) (Math.Min(bufferDataIndex + length, bufferDataLength) -
|
||||
bufferDataIndex);
|
||||
|
||||
int bufferIndex = this.bufferIndex - (int) (bufferDataLength - bufferDataIndex);
|
||||
if (bufferIndex < 0)
|
||||
{
|
||||
bufferIndex = buffer.Length + bufferIndex;
|
||||
}
|
||||
|
||||
CopyFromBuffer(data, offset, length, bufferIndex);
|
||||
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
public Marker CreateMarker(int offset = 0)
|
||||
{
|
||||
var markerPosition = bufferDataLength + offset;
|
||||
if (markerPosition < 0)
|
||||
{
|
||||
markerPosition = 0;
|
||||
}
|
||||
|
||||
int bufIndex = bufferIndex + offset;
|
||||
if (bufIndex < 0)
|
||||
{
|
||||
bufIndex = buffer.Length + bufIndex;
|
||||
}
|
||||
|
||||
if (bufIndex > buffer.Length)
|
||||
{
|
||||
bufIndex -= buffer.Length;
|
||||
}
|
||||
|
||||
var marker = new Marker(this, markerPosition, bufIndex);
|
||||
|
||||
return marker;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e01ee0aa0d794f7abb30675495fd7ca9
|
||||
timeCreated: 1626392023
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 982d60138e5147b88a5117adc9ded942
|
||||
timeCreated: 1632287691
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eba9bfef0d8049398230af05b25af0e6
|
||||
timeCreated: 1680299500
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
namespace Meta.WitAi.Data.ValueReferences
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class StringReference<T> : IStringReference where T : ScriptableObject, IStringReference
|
||||
{
|
||||
[SerializeField] private string stringValue;
|
||||
[SerializeField] private T stringObject;
|
||||
|
||||
public string Value
|
||||
{
|
||||
get => stringObject ? stringObject.Value : stringValue;
|
||||
set
|
||||
{
|
||||
stringObject = null;
|
||||
stringValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IStringReference
|
||||
{
|
||||
string Value { get; set; }
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d93d804b221245ecada6cf7bdf41d751
|
||||
timeCreated: 1680299563
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Json;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
[Serializable]
|
||||
public class VoiceSession
|
||||
{
|
||||
/// <summary>
|
||||
/// Voice service being used
|
||||
/// </summary>
|
||||
public VoiceService service;
|
||||
/// <summary>
|
||||
/// Voice service response data
|
||||
/// </summary>
|
||||
public WitResponseNode response;
|
||||
/// <summary>
|
||||
/// Session response data is valid & can be deactivated if true
|
||||
/// </summary>
|
||||
public bool validResponse = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4abc542ed39ac304cbfaa6f82eab7cba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
public class WitFloatValue : WitValue
|
||||
{
|
||||
[SerializeField] public float equalityTolerance = .0001f;
|
||||
|
||||
public override object GetValue(WitResponseNode response)
|
||||
{
|
||||
return GetFloatValue(response);
|
||||
}
|
||||
|
||||
public override bool Equals(WitResponseNode response, object value)
|
||||
{
|
||||
float fValue = 0;
|
||||
if (value is float f)
|
||||
{
|
||||
fValue = f;
|
||||
}
|
||||
else if(null != value && !float.TryParse("" + value, out fValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Math.Abs(GetFloatValue(response) - fValue) < equalityTolerance;
|
||||
}
|
||||
|
||||
public float GetFloatValue(WitResponseNode response)
|
||||
{
|
||||
return Reference.GetFloatValue(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab8864132457433b8281c87f23398770
|
||||
timeCreated: 1624318241
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Json;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
public class WitIntValue : WitValue
|
||||
{
|
||||
public override object GetValue(WitResponseNode response)
|
||||
{
|
||||
return GetIntValue(response);
|
||||
}
|
||||
|
||||
public override bool Equals(WitResponseNode response, object value)
|
||||
{
|
||||
int iValue = 0;
|
||||
if (value is int i)
|
||||
{
|
||||
iValue = i;
|
||||
}
|
||||
else if (null != value && !int.TryParse("" + value, out iValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return GetIntValue(response) == iValue;
|
||||
}
|
||||
|
||||
public int GetIntValue(WitResponseNode response)
|
||||
{
|
||||
return Reference.GetIntValue(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02641aecd6e142a1b375ed2fb84b8303
|
||||
timeCreated: 1624318209
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Json;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
public class WitStringValue : WitValue
|
||||
{
|
||||
public override object GetValue(WitResponseNode response)
|
||||
{
|
||||
return GetStringValue(response);
|
||||
}
|
||||
|
||||
public override bool Equals(WitResponseNode response, object value)
|
||||
{
|
||||
if (value is string sValue)
|
||||
{
|
||||
return GetStringValue(response) == sValue;
|
||||
}
|
||||
|
||||
return "" + value == GetStringValue(response);
|
||||
}
|
||||
|
||||
public string GetStringValue(WitResponseNode response)
|
||||
{
|
||||
return Reference.GetStringValue(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 872feba58ea14c069669a1d25959b22c
|
||||
timeCreated: 1624318051
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using Meta.WitAi.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Data
|
||||
{
|
||||
public abstract class WitValue : ScriptableObject
|
||||
{
|
||||
[SerializeField] public string path;
|
||||
private WitResponseReference reference;
|
||||
|
||||
public WitResponseReference Reference
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == reference)
|
||||
{
|
||||
reference = WitResultUtilities.GetWitResponseReference(path);
|
||||
}
|
||||
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract object GetValue(WitResponseNode response);
|
||||
|
||||
public abstract bool Equals(WitResponseNode response, object value);
|
||||
|
||||
public string ToString(WitResponseNode response)
|
||||
{
|
||||
return Reference.GetStringValue(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d14d7c8a51621ce419693992b114e2ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 401db7761c526c3448f1af1d549ec9f9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Data;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
[Serializable]
|
||||
public class AudioBufferEvents
|
||||
{
|
||||
public delegate void OnSampleReadyEvent(RingBuffer<byte>.Marker marker, float levelMax);
|
||||
public OnSampleReadyEvent OnSampleReady;
|
||||
|
||||
[Tooltip("Called when the volume level of the mic input has changed")]
|
||||
public WitMicLevelChangedEvent OnMicLevelChanged = new WitMicLevelChangedEvent();
|
||||
|
||||
[Header("Data")]
|
||||
public WitByteDataEvent OnByteDataReady = new WitByteDataEvent();
|
||||
public WitByteDataEvent OnByteDataSent = new WitByteDataEvent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd7c64da99e7e054c83dea7647d723b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
public class AudioDurationTrackerFinishedEvent : UnityEvent<long, double>
|
||||
{
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8dfb56f054f4aaead7cf9a29003a1d1
|
||||
timeCreated: 1670631381
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||
public class EventCategoryAttribute : PropertyAttribute
|
||||
{
|
||||
public readonly string Category;
|
||||
|
||||
public EventCategoryAttribute(string category = "")
|
||||
{
|
||||
Category = category;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c098352b8ac4407a48e88eec765e7c5
|
||||
timeCreated: 1658192444
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
public class EventRegistry
|
||||
{
|
||||
[SerializeField]
|
||||
private List<string> _overriddenCallbacks = new List<string>();
|
||||
private HashSet<string> _overriddenCallbacksHash;
|
||||
|
||||
public HashSet<string> OverriddenCallbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_overriddenCallbacksHash == null)
|
||||
{
|
||||
_overriddenCallbacksHash = new HashSet<string>(_overriddenCallbacks);
|
||||
}
|
||||
|
||||
return _overriddenCallbacksHash;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterOverriddenCallback(string callback)
|
||||
{
|
||||
if (!_overriddenCallbacks.Contains(callback))
|
||||
{
|
||||
_overriddenCallbacks.Add(callback);
|
||||
_overriddenCallbacksHash.Add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveOverriddenCallback(string callback)
|
||||
{
|
||||
if (_overriddenCallbacks.Contains(callback))
|
||||
{
|
||||
_overriddenCallbacks.Remove(callback);
|
||||
_overriddenCallbacksHash.Remove(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCallbackOverridden(string callback)
|
||||
{
|
||||
return OverriddenCallbacks.Contains(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb347bc947a144a4895c273b88f7baff
|
||||
timeCreated: 1658874536
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
public class TelemetryEvents
|
||||
{
|
||||
public AudioDurationTrackerFinishedEvent OnAudioTrackerFinished =
|
||||
new AudioDurationTrackerFinishedEvent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 671577dd5928458da0dfb66db09c5b95
|
||||
timeCreated: 1670875696
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e46f5b77b81ea435ea3274e9d3ddceaa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
using Meta.WitAi.Interfaces;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.Events.UnityEventListeners
|
||||
{
|
||||
[RequireComponent(typeof(IAudioEventProvider))]
|
||||
public class AudioEventListener : MonoBehaviour, IAudioInputEvents
|
||||
{
|
||||
[SerializeField] private WitMicLevelChangedEvent onMicAudioLevelChanged = new WitMicLevelChangedEvent();
|
||||
[SerializeField] private UnityEvent onMicStartedListening = new UnityEvent();
|
||||
[SerializeField] private UnityEvent onMicStoppedListening = new UnityEvent();
|
||||
|
||||
public WitMicLevelChangedEvent OnMicAudioLevelChanged => onMicAudioLevelChanged;
|
||||
public UnityEvent OnMicStartedListening => onMicStartedListening;
|
||||
public UnityEvent OnMicStoppedListening => onMicStoppedListening;
|
||||
|
||||
private IAudioInputEvents _events;
|
||||
|
||||
private IAudioInputEvents AudioInputEvents
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _events)
|
||||
{
|
||||
var eventProvider = GetComponent<IAudioEventProvider>();
|
||||
if (null != eventProvider)
|
||||
{
|
||||
_events = eventProvider.AudioEvents;
|
||||
}
|
||||
}
|
||||
|
||||
return _events;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
var events = AudioInputEvents;
|
||||
if (null != events)
|
||||
{
|
||||
events.OnMicAudioLevelChanged.AddListener(onMicAudioLevelChanged.Invoke);
|
||||
events.OnMicStartedListening.AddListener(onMicStartedListening.Invoke);
|
||||
events.OnMicStoppedListening.AddListener(onMicStoppedListening.Invoke);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
var events = AudioInputEvents;
|
||||
if (null != events)
|
||||
{
|
||||
events.OnMicAudioLevelChanged.RemoveListener(onMicAudioLevelChanged.Invoke);
|
||||
events.OnMicStartedListening.RemoveListener(onMicStartedListening.Invoke);
|
||||
events.OnMicStoppedListening.RemoveListener(onMicStoppedListening.Invoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b7e57a219bf949418f86fc9056e38ec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
using Meta.WitAi.Interfaces;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Meta.WitAi.Events.UnityEventListeners
|
||||
{
|
||||
public class TranscriptionEventListener : MonoBehaviour, ITranscriptionEvent
|
||||
{
|
||||
[SerializeField] private WitTranscriptionEvent onPartialTranscription = new
|
||||
WitTranscriptionEvent();
|
||||
[SerializeField] private WitTranscriptionEvent onFullTranscription = new
|
||||
WitTranscriptionEvent();
|
||||
|
||||
public WitTranscriptionEvent OnPartialTranscription => onPartialTranscription;
|
||||
public WitTranscriptionEvent OnFullTranscription => onFullTranscription;
|
||||
|
||||
private ITranscriptionEvent _events;
|
||||
|
||||
private ITranscriptionEvent TranscriptionEvents
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _events)
|
||||
{
|
||||
var eventProvider = GetComponent<ITranscriptionEventProvider>();
|
||||
if (null != eventProvider)
|
||||
{
|
||||
_events = eventProvider.TranscriptionEvents;
|
||||
}
|
||||
}
|
||||
|
||||
return _events;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
var events = TranscriptionEvents;
|
||||
if (null != events)
|
||||
{
|
||||
events.OnPartialTranscription.AddListener(onPartialTranscription.Invoke);
|
||||
events.OnFullTranscription.AddListener(onFullTranscription.Invoke);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
var events = TranscriptionEvents;
|
||||
if (null != events)
|
||||
{
|
||||
events.OnPartialTranscription.RemoveListener(onPartialTranscription.Invoke);
|
||||
events.OnFullTranscription.RemoveListener(onFullTranscription.Invoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4753c88442c94393b915563ef1b41cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
[Serializable]
|
||||
public class VoiceEvents : SpeechEvents
|
||||
{
|
||||
private const string EVENT_CATEGORY_DATA_EVENTS = "Data Events";
|
||||
|
||||
[EventCategory(EVENT_CATEGORY_DATA_EVENTS)]
|
||||
[FormerlySerializedAs("OnByteDataReady")] [SerializeField] [HideInInspector]
|
||||
private WitByteDataEvent _onByteDataReady = new WitByteDataEvent();
|
||||
public WitByteDataEvent OnByteDataReady => _onByteDataReady;
|
||||
|
||||
[EventCategory(EVENT_CATEGORY_DATA_EVENTS)]
|
||||
[FormerlySerializedAs("OnByteDataSent")] [SerializeField] [HideInInspector]
|
||||
private WitByteDataEvent _onByteDataSent = new WitByteDataEvent();
|
||||
public WitByteDataEvent OnByteDataSent => _onByteDataSent;
|
||||
|
||||
[EventCategory(EVENT_CATEGORY_ACTIVATION_RESPONSE)]
|
||||
[Tooltip("Called after an on partial response to validate data. If data.validResponse is true, service will deactivate & use the partial data as final")]
|
||||
[FormerlySerializedAs("OnValidatePartialResponse")] [SerializeField]
|
||||
private WitValidationEvent _onValidatePartialResponse = new WitValidationEvent();
|
||||
public WitValidationEvent OnValidatePartialResponse => _onValidatePartialResponse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 371044f8a8a85b34aa78547a31c99aa0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Meta.WitAi.Requests;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
[Serializable]
|
||||
public class VoiceServiceRequestEvent : UnityEvent<VoiceServiceRequest> { }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a88978da4d44ed4f962061566872b83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
[Flags]
|
||||
public enum VoiceState
|
||||
{
|
||||
MicOff = 1, //000001
|
||||
MicOn = 2, //000010
|
||||
Listening = 4,//000100
|
||||
StartProcessing = 8,//001000
|
||||
Response = 16,//010000
|
||||
Error = 32, //100000
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3a30f8f7e33c754484eaa264d133f25
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Meta.WitAi.Events
|
||||
{
|
||||
[Serializable]
|
||||
public class WitByteDataEvent : UnityEvent<byte[], int, int> { }
|
||||
|
||||
public interface IWitByteDataReadyHandler
|
||||
{
|
||||
void OnWitDataReady(byte[] data, int offset, int length);
|
||||
}
|
||||
|
||||
public interface IWitByteDataSentHandler
|
||||
{
|
||||
void OnWitDataSent(byte[] data, int offset, int length);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user