using Ryuclaw.Shared.Speech; using AVFoundation; namespace Ryuclaw.Speech.MacOS { public class TTS : ISpeech { private float Rate { get; set; } private float Pitch { get; set; } private AVSpeechSynthesizer Synth; private AVSpeechSynthesisVoice Voice; public TTS() { Synth = new AVSpeechSynthesizer(); Rate = 1; Pitch = 1; Voice = AVSpeechSynthesisVoice.FromIdentifier(AVSpeechSynthesisVoice.IdentifierAlex); } public void SetRate(float rate) { Rate = rate; } public void SetPitch(float pitch) { Pitch = pitch; } public List GetVoices() { var availableVoices = AVSpeechSynthesisVoice.GetSpeechVoices(); List voices = new(); foreach (var voice in availableVoices) { voices.Add(voice.Name); } return null; } public void SetVoice(string name) { foreach (var voice in AVSpeechSynthesisVoice.GetSpeechVoices()) { if (voice.Name.Equals(name)) { Voice = voice; return; } } Voice = AVSpeechSynthesisVoice.FromIdentifier(AVSpeechSynthesisVoice.IdentifierAlex); } public void Speak(string text) { var utterance = new AVSpeechUtterance(text); utterance.Rate = Rate; utterance.PitchMultiplier = Pitch; utterance.Voice = Voice; utterance.PrefersAssistiveTechnologySettings = true; Synth.SpeakUtterance(utterance); } public void Stop() { Synth.StopSpeaking(AVSpeechBoundary.Immediate); } } }