public static void start(IModHelper h) { Helper = h; currentText = ""; tmppath = Path.Combine(Path.Combine(Environment.CurrentDirectory, "Content"), "TTS"); ensureFolderStructureExists(Path.Combine(tmppath, "speech.mp3")); pc = AWSHandler.getPollyClient(); currentVoice = VoiceId.Amy; lastText = ""; lastDialog = ""; lastHud = ""; speak = false; runSpeech = true; currentCulture = CultureInfo.CreateSpecificCulture("en-us"); culturelang = "en"; installedVoices = new List <string>(); setupVoices(); setVoice("default"); speechThread = new Thread(t2sOut); speechThread.Start(); GameEvents.QuarterSecondTick += GameEvents_QuarterSecondTick; MenuEvents.MenuClosed += MenuEvents_MenuClosed; //ControlEvents.KeyPressed += ControlEvents_KeyPressed; }
public static void start(IModHelper h) { Helper = h; currentText = ""; tmppath = Path.Combine(Helper.DirectoryPath, "TTS"); if (!Directory.Exists(tmppath)) { Directory.CreateDirectory(tmppath); } if (pc == null) { pc = AWSHandler.getPollyClient(); } currentVoice = VoiceId.Salli; lastText = ""; lastDialog = ""; lastHud = ""; speak = false; runSpeech = true; setVoice("default"); speechThread = new Thread(t2sOut); speechThread.Start(); h.Events.GameLoop.UpdateTicked += OnUpdateTicked; h.Events.Display.MenuChanged += OnMenuChanged; }
internal static void configSay(string name, string voice, string text, int rate = -1, float pitch = -1, float volume = -1) { Task.Run(() => { currentVoice = VoiceId.FindValue(voice); tmppath = Path.Combine(PelicanTTSMod._helper.DirectoryPath, "TTS"); if (pc == null) { pc = AWSHandler.getPollyClient(); } bool mumbling = PelicanTTSMod.config.MumbleDialogues; string language1 = "<lang xml:lang=\"" + getLanguageCode() + "\">"; string language2 = "</lang>"; text = text.Replace("0g", "0 gold").Replace("< ", " ").Replace("` ", " ").Replace("> ", " ").Replace('^', ' ').Replace(Environment.NewLine, " ").Replace("$s", "").Replace("$h", "").Replace("$g", "").Replace("$e", "").Replace("$u", "").Replace("$b", "").Replace("$8", "").Replace("$l", "").Replace("$q", "").Replace("$9", "").Replace("$a", "").Replace("$7", "").Replace("<", "").Replace("$r", "").Replace("[", "<").Replace("]", ">"); text = language1 + text + language2; bool neural = shouldUseNeuralEngine(voice, out string v); if (!neural && voice != v) { currentVoice = VoiceId.FindValue(v); } bool useNeuralEngine = !mumbling && neural; var amzeffectIn = mumbling ? "<amazon:effect phonation='soft'><amazon:effect vocal-tract-length='-20%'>" : "<amazon:auto-breaths><amazon:effect phonation='soft'>"; var amzeffectOut = mumbling ? "</amazon:effect></amazon:effect>" : "</amazon:effect></amazon:auto-breaths>"; if (mumbling) { text = @"<speak>" + (useNeuralEngine ? "" : amzeffectIn) + Dialogue.convertToDwarvish(text) + (useNeuralEngine ? "" : amzeffectOut) + @"</speak>"; } else { text = @"<speak>" + (useNeuralEngine ? "" : amzeffectIn) + "<prosody rate='" + (rate == -1 ? PelicanTTSMod.config.Rate : rate) + "%'>" + text + @"</prosody>" + (useNeuralEngine ? "" : amzeffectOut) + "</speak>"; } int hash = (text + (useNeuralEngine ? "-neural" : "")).GetHashCode(); if (!Directory.Exists(Path.Combine(tmppath, name))) { Directory.CreateDirectory(Path.Combine(tmppath, name)); } string file = Path.Combine(Path.Combine(tmppath, name), "speech_" + currentVoice.Value + (mumbling ? "_mumble_" : "_") + hash + ".wav"); SoundEffect nextSpeech = null; if (!File.Exists(file)) { SynthesizeSpeechRequest sreq = new SynthesizeSpeechRequest(); sreq.Text = text; sreq.TextType = TextType.Ssml; sreq.OutputFormat = OutputFormat.Ogg_vorbis; sreq.Engine = useNeuralEngine ? Engine.Neural : Engine.Standard; sreq.VoiceId = currentVoice; SynthesizeSpeechResponse sres = pc.SynthesizeSpeech(sreq); using (var memStream = new MemoryStream()) { sres.AudioStream.CopyTo(memStream); nextSpeech = Convert(memStream, file); } } using (FileStream stream = new FileStream(file, FileMode.Open)) nextSpeech = SoundEffect.FromStream(stream); if (currentSpeech != null) { currentSpeech.Stop(); } currentSpeech = nextSpeech.CreateInstance(); speak = false; currentSpeech.Pitch = (mumbling ? 0.5f : pitch == -1 ? PelicanTTSMod.config.Voices[name].Pitch : pitch); currentSpeech.Volume = volume == -1 ? PelicanTTSMod.config.Volume : volume; currentSpeech.Play(); }); }
internal static void configSay(string name, string voice, string text) { Task.Run(() => { currentVoice = VoiceId.FindValue(voice); tmppath = Path.Combine(PelicanTTSMod._helper.DirectoryPath, "TTS"); if (pc == null) { pc = AWSHandler.getPollyClient(); } bool mumbling = PelicanTTSMod.config.MumbleDialogues; text = text.Replace("< ", " ").Replace("` ", " ").Replace("> ", " ").Replace('^', ' ').Replace(Environment.NewLine, " ").Replace("$s", "").Replace("$h", "").Replace("$g", "").Replace("$e", "").Replace("$u", "").Replace("$b", "").Replace("$8", "").Replace("$l", "").Replace("$q", "").Replace("$9", "").Replace("$a", "").Replace("$7", "").Replace("<", "").Replace("$r", "").Replace("[", "<").Replace("]", ">"); if (mumbling) { text = @"<speak><amazon:effect phonation='soft'><amazon:effect vocal-tract-length='-20%'>" + Dialogue.convertToDwarvish(text) + @"</amazon:effect></amazon:effect></speak>"; } else { text = @"<speak><amazon:auto-breaths><amazon:effect phonation='soft'>" + text + @"</amazon:effect></amazon:auto-breaths></speak>"; } int hash = text.GetHashCode(); if (!Directory.Exists(Path.Combine(tmppath, name))) { Directory.CreateDirectory(Path.Combine(tmppath, name)); } string file = Path.Combine(Path.Combine(tmppath, name), "speech_" + currentVoice.Value + (mumbling ? "_mumble_" : "_") + hash + ".wav"); SoundEffect nextSpeech = null; if (!File.Exists(file)) { SynthesizeSpeechRequest sreq = new SynthesizeSpeechRequest(); sreq.Text = text; sreq.TextType = TextType.Ssml; sreq.OutputFormat = OutputFormat.Ogg_vorbis; sreq.VoiceId = currentVoice; SynthesizeSpeechResponse sres = pc.SynthesizeSpeech(sreq); using (var memStream = new MemoryStream()) { sres.AudioStream.CopyTo(memStream); nextSpeech = Convert(memStream, file); } } using (FileStream stream = new FileStream(file, FileMode.Open)) nextSpeech = SoundEffect.FromStream(stream); if (currentSpeech != null) { currentSpeech.Stop(); } currentSpeech = nextSpeech.CreateInstance(); speak = false; currentSpeech.Pitch = (mumbling ? 0.5f : PelicanTTSMod.config.Voices[name].Pitch); currentSpeech.Volume = PelicanTTSMod.config.Volume; currentSpeech.Play(); }); }