Beispiel #1
0
        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;
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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();
            });
        }
Beispiel #4
0
        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();
            });
        }