public async Task SpeakAsync(string text, int max, SpeechOptions options, CancellationToken cancelToken) { await Initialize(); // Wait for any previous calls to finish up if (tcsUtterances?.Task != null) { await tcsUtterances.Task; } tcsUtterances = new TaskCompletionSource <bool>(); if (cancelToken != null) { cancelToken.Register(() => { try { tts?.Stop(); tcsUtterances?.TrySetResult(true); } catch { } }); } if (options?.Locale?.Language != null) { JavaLocale locale = null; if (!string.IsNullOrWhiteSpace(options?.Locale.Country)) { locale = new JavaLocale(options.Locale.Language, options.Locale.Country); } else { locale = new JavaLocale(options.Locale.Language); } tts.SetLanguage(locale); } else { SetDefaultLanguage(); } if (options?.Pitch.HasValue ?? false) { tts.SetPitch(options.Pitch.Value); } else { tts.SetPitch(TextToSpeech.PitchDefault); } tts.SetSpeechRate(1.0f); var parts = text.SplitSpeak(max); numExpectedUtterances = parts.Count; var guid = Guid.NewGuid().ToString(); for (var i = 0; i < parts.Count && !cancelToken.IsCancellationRequested; i++) { // We require the utterance id to be set if we want the completed listener to fire var map = new Dictionary <string, string> { { AndroidTextToSpeech.Engine.KeyParamUtteranceId, $"{guid}.{i}" } }; if (options != null && options.Volume.HasValue) { map.Add(AndroidTextToSpeech.Engine.KeyParamVolume, options.Volume.Value.ToString(CultureInfo.InvariantCulture)); } // We use an obsolete overload here so it works on older API levels at runtime // Flush on first entry and add (to not flush our own previous) subsequent entries #pragma warning disable CS0618 tts.Speak(parts[i], i == 0 ? QueueMode.Flush : QueueMode.Add, map); #pragma warning restore CS0618 } await tcsUtterances.Task; }
internal static Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default) => throw new System.PlatformNotSupportedException();
internal static Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default) { var speechUtterance = GetSpeechUtterance(text, options); return(SpeakUtterance(speechUtterance, cancelToken)); }
static string GetSpeakParametersSSMLProsody(SpeechSynthesizer synthesizer, string text, SpeechOptions options) { var volume = "default"; var pitch = "default"; var rate = "default"; // Look for the specified language, otherwise the default voice var locale = options?.Locale?.Language ?? synthesizer.Voice.Culture.Name; if (options?.Volume.HasValue ?? false) { volume = (options.Volume.Value * 100f).ToString(CultureInfo.InvariantCulture); } if (options?.Pitch.HasValue ?? false) { pitch = ProsodyPitch(options.Pitch); } // SSML generation var ssml = new StringBuilder(); ssml.AppendLine($"<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='{locale}'>"); ssml.AppendLine($"<prosody pitch='{pitch}' rate='{rate}' volume='{volume}'>{text}</prosody> "); ssml.AppendLine($"</speak>"); return(ssml.ToString()); }
internal static Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default) => throw ExceptionUtils.NotSupportedOrImplementedException;
internal static Task PlatformSpeakAsync(string text, SpeechOptions options, CancellationToken cancelToken = default) => throw new NotImplementedInReferenceAssemblyException();