Health/Assets/_VoiceAssistant/Scripts/Voice/Azure/VWU_AzureExample.cs

214 lines
7.4 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using Microsoft.CognitiveServices.Speech;
using System.Threading.Tasks;
using System.IO;
using System;
using System.Collections;
#if PLATFORM_ANDROID
using UnityEngine.Android;
using UnityEngine.Networking;
#endif
#if PLATFORM_IOS
using UnityEngine.iOS;
using System.Collections;
#endif
public class VWU_AzureExample : VoiceWakeUp
{
// Hook up the two properties below with a Text and Button object in your UI.
//public Text outputText;
//public Button startRecoButton;
private object threadLocker = new object();
private bool waitingForReco;
private string message;
private bool micPermissionGranted = false;
private string kwsModelDir;
[SerializeField]
private string key = "";
[SerializeField]
private string ServiceRegion = "eastasia";
[SerializeField]
private string kwsModelFile = "kws.table";
private const string keyword = "hey mike";
#if PLATFORM_ANDROID || PLATFORM_IOS
// Required to manifest microphone permission, cf.
// https://docs.unity3d.com/Manual/android-manifest.html
private Microphone mic;
#endif
public async void ButtonClick()
{
try
{
lock (threadLocker)
{
waitingForReco = true;
}
// Creates an instance of a speech config with specified subscription key and service region.
// Replace with your own subscription key and service region (e.g., "westus").
var config = SpeechConfig.FromSubscription(key, ServiceRegion);
#if PLATFORM_ANDROID
kwsModelDir = Application.persistentDataPath + Path.DirectorySeparatorChar + kwsModelFile;
#else
kwsModelDir = Application.streamingAssetsPath + Path.DirectorySeparatorChar + kwsModelFile;
#endif
UnityEngine.Debug.Log(kwsModelDir);
var model = KeywordRecognitionModel.FromFile(kwsModelDir);
var stopRecognition = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
var resultStr = "";
// Creates a speech recognizer using microphone as audio input.
using (var recognizer = new SpeechRecognizer(config))
{
// Subscribes to events.
recognizer.Recognized += (s, e) =>
{
if (e.Result.Reason == ResultReason.RecognizedKeyword)
{
resultStr = $"RECOGNIZED KEYWORD: '{e.Result.Text}'";
}
else if (e.Result.Reason == ResultReason.RecognizedSpeech)
{
resultStr = $"RECOGNIZED: '{e.Result.Text}'";
}
else if (e.Result.Reason == ResultReason.NoMatch)
{
resultStr = "NOMATCH: Speech could not be recognized.";
}
UnityEngine.Debug.Log(resultStr);
lock (threadLocker)
{
message = resultStr;
}
};
recognizer.Canceled += (s, e) =>
{
var cancellation = CancellationDetails.FromResult(e.Result);
resultStr = $"CANCELED: Reason={cancellation.Reason} ErrorDetails={cancellation.ErrorDetails}";
if (cancellation.Reason == CancellationReason.Error)
{
lock (threadLocker)
{
message = resultStr;
}
}
UnityEngine.Debug.Log(resultStr);
stopRecognition.TrySetResult(0);
};
recognizer.SessionStarted += (s, e) =>
{
UnityEngine.Debug.Log("\nSession started event.");
};
recognizer.SessionStopped += (s, e) =>
{
UnityEngine.Debug.Log("\nSession stopped event.");
UnityEngine.Debug.Log("\nStop recognition.");
stopRecognition.TrySetResult(0);
};
UnityEngine.Debug.Log($"Say something starting with the keyword '{keyword}' followed by whatever you want...");
// Starts continuous recognition using the keyword model. Use StopKeywordRecognitionAsync() to stop recognition.
await recognizer.StartKeywordRecognitionAsync(model).ConfigureAwait(false);
// Waits for a single successful keyword-triggered speech recognition (or error).
// Use Task.WaitAny to keep the task rooted.
Task.WaitAny(new[] { stopRecognition.Task });
await recognizer.StopKeywordRecognitionAsync().ConfigureAwait(false);
lock (threadLocker)
{
waitingForReco = false;
}
}
}
catch (Exception ex)
{
lock (threadLocker)
{
message = "Exception: " + ex.ToString();
waitingForReco = false;
}
}
}
#if PLATFORM_ANDROID
IEnumerator CopyKwsModelFileFromStreamingAssetsAsync()
{
string fromFile = Application.streamingAssetsPath + Path.DirectorySeparatorChar + kwsModelFile;
string toFile = Application.persistentDataPath + Path.DirectorySeparatorChar + kwsModelFile;
UnityWebRequest downloader = UnityWebRequest.Get(fromFile);
yield return downloader.SendWebRequest();
DownloadHandler handler = downloader.downloadHandler;
File.WriteAllBytes(toFile, handler.data);
}
#endif
void Start()
{
Debug.Log("Start enter");
// Continue with normal initialization, Text and Button objects are present.
#if PLATFORM_ANDROID
// Request to use the microphone, cf.
// https://docs.unity3d.com/Manual/android-RequestingPermissions.html
message = "Waiting for mic permission";
if (!Permission.HasUserAuthorizedPermission(Permission.Microphone))
{
Permission.RequestUserPermission(Permission.Microphone);
}
StartCoroutine(CopyKwsModelFileFromStreamingAssetsAsync());
#elif PLATFORM_IOS
if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
{
Application.RequestUserAuthorization(UserAuthorization.Microphone);
}
#else
micPermissionGranted = true;
message = "Click button to recognize speech using a keyword";
#endif
Debug.Log("Start exit");
}
void Update()
{
#if PLATFORM_ANDROID
if (!micPermissionGranted && Permission.HasUserAuthorizedPermission(Permission.Microphone))
{
micPermissionGranted = true;
message = "Click button to recognize speech";
}
#elif PLATFORM_IOS
if (!micPermissionGranted && Application.HasUserAuthorization(UserAuthorization.Microphone))
{
micPermissionGranted = true;
message = "Click button to recognize speech";
}
#endif
}
public override void StartRecgnition(Action<bool> callback)
{
base.StartRecgnition(callback);
ButtonClick();
}
public override void StopRecognition()
{
throw new NotImplementedException();
}
}