| using System.Collections.Generic; |
| using UnityEngine; |
|
|
| namespace OnDeviceAgent.Inference |
| { |
| public sealed class SupertonicTtsRequest |
| { |
| public string Text; |
| public string Language; |
| public string VoiceStyle; |
| } |
|
|
| public static class SupertonicTtsModule |
| { |
| const int MaxQueuedRequests = 8; |
|
|
| static readonly object s_Lock = new object(); |
| static readonly Queue<SupertonicTtsRequest> s_Requests = new Queue<SupertonicTtsRequest>(); |
| static SupertonicTtsPlayer s_Player; |
| |
| |
| static bool s_Speaking; |
|
|
| public static bool IsAvailable |
| { |
| get |
| { |
| lock (s_Lock) |
| return !ReferenceEquals(s_Player, null); |
| } |
| } |
|
|
| public static bool IsSpeaking |
| { |
| get |
| { |
| lock (s_Lock) |
| return s_Speaking; |
| } |
| } |
|
|
| public static void StopSpeaking() |
| { |
| SupertonicTtsPlayer player; |
| lock (s_Lock) |
| { |
| s_Requests.Clear(); |
| player = s_Player; |
| } |
| if (!ReferenceEquals(player, null)) |
| player.StopPlayback(); |
| } |
|
|
| internal static void SetSpeaking(bool speaking) |
| { |
| lock (s_Lock) |
| s_Speaking = speaking; |
| } |
|
|
| public static bool TryPlay(string text, string language, string voiceStyle, out string message) |
| { |
| if (string.IsNullOrWhiteSpace(text)) |
| { |
| message = "TTS text is empty."; |
| return false; |
| } |
|
|
| lock (s_Lock) |
| { |
| if (ReferenceEquals(s_Player, null)) |
| { |
| message = "No Supertonic TTS player is registered in the active scene."; |
| return false; |
| } |
|
|
| if (s_Requests.Count >= MaxQueuedRequests) |
| { |
| var preview = text.Length <= 50 ? text : text.Substring(0, 50) + "..."; |
| Debug.LogWarning("[TTS] Queue full (" + MaxQueuedRequests + "); dropping: '" + preview + "'"); |
| message = "The Supertonic TTS request queue is full."; |
| return false; |
| } |
|
|
| s_Requests.Enqueue(new SupertonicTtsRequest |
| { |
| Text = text.Trim(), |
| Language = string.IsNullOrWhiteSpace(language) ? string.Empty : language.Trim(), |
| VoiceStyle = string.IsNullOrWhiteSpace(voiceStyle) ? string.Empty : voiceStyle.Trim() |
| }); |
| } |
|
|
| message = "Queued Supertonic TTS playback."; |
| return true; |
| } |
|
|
| internal static void Register(SupertonicTtsPlayer player) |
| { |
| if (ReferenceEquals(player, null)) |
| return; |
|
|
| lock (s_Lock) |
| s_Player = player; |
| } |
|
|
| internal static void Unregister(SupertonicTtsPlayer player) |
| { |
| lock (s_Lock) |
| { |
| if (!ReferenceEquals(s_Player, player)) |
| return; |
|
|
| s_Player = null; |
| s_Requests.Clear(); |
| s_Speaking = false; |
| } |
| } |
|
|
| internal static bool TryDequeue(out SupertonicTtsRequest request) |
| { |
| lock (s_Lock) |
| { |
| if (s_Requests.Count == 0) |
| { |
| request = null; |
| return false; |
| } |
|
|
| request = s_Requests.Dequeue(); |
| return true; |
| } |
| } |
| } |
| } |
|
|