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 s_Requests = new Queue(); static SupertonicTtsPlayer s_Player; // There is a single player, so speaking is a simple on/off flag. (A counter could drift upward if // SetSpeaking(true) was ever called more often than SetSpeaking(false), leaving IsSpeaking stuck.) 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; } } } }