Пример #1
0
        public void TestDisableIPA()
        {
            // Test removal of <phoneme> tags (and only phenome tags) when the user has indicated that they would like to disable phonetic speech
            var line   = @"<break time=""100ms""/><phoneme alphabet=""ipa"" ph=""ʃɪnˈrɑːrtə"">Shinrarta</phoneme> <phoneme alphabet='ipa' ph='ˈdezɦrə'>Dezhra</phoneme> & Co's shop";
            var result = SpeechFormatter.DisableIPA(line);

            Assert.AreEqual(@"<break time=""100ms""/>Shinrarta Dezhra & Co's shop", result);
        }
Пример #2
0
        public void TestSpeechServiceEscaping5()
        {
            // Test escaping for characters included in the escape sequence ('X' in this case)
            var line   = @"Brazilian armada <say-as interpret-as=""characters"">X</say-as>";
            var result = SpeechFormatter.EscapeSSML(line);

            Assert.AreEqual(line, result);
        }
Пример #3
0
        public void TestSpeechServiceEscaping4()
        {
            // Test escaping for Cereproc unique <usel> and <spurt> elements
            var line   = @"<spurt audio='g0001_004'>cough</spurt> This is a <usel variant=""1"">test</usel> sentence.";
            var result = SpeechFormatter.EscapeSSML(line);

            Assert.AreEqual(line, result);
        }
Пример #4
0
        public void TestSpeechServiceEscaping3()
        {
            // Test escaping for <break> elements. XML characters outside of ssml elements are escaped.
            var line   = @"<break time=""100ms""/>He said ""Foo"".";
            var result = SpeechFormatter.EscapeSSML(line);

            Assert.AreEqual("<break time=\"100ms\"/>He said &quot;Foo&quot;.", result);
        }
Пример #5
0
        public void TestSpeechServiceEscaping2()
        {
            // Test escaping for double quotes, single quotes, and <phoneme> ssml commands. XML characters outside of ssml elements are escaped.
            var line   = @"<phoneme alphabet=""ipa"" ph=""ʃɪnˈrɑːrtə"">Shinrarta</phoneme> <phoneme alphabet='ipa' ph='ˈdezɦrə'>Dezhra</phoneme> & Co's shop";
            var result = SpeechFormatter.EscapeSSML(line);

            Assert.AreEqual("<phoneme alphabet=\"ipa\" ph=\"ʃɪnˈrɑːrtə\">Shinrarta</phoneme> <phoneme alphabet='ipa' ph='ˈdezɦrə'>Dezhra</phoneme> &amp; Co&apos;s shop", result);
        }
Пример #6
0
        public void TestSpeechServiceEscaping1()
        {
            // Test escaping for invalid ssml.
            var line   = @"<invalid>test</invalid> <invalid withattribute='attribute'>test2</invalid>";
            var result = SpeechFormatter.EscapeSSML(line);

            Assert.AreEqual("&lt;invalid&gt;test&lt;/invalid&gt; &lt;invalid withattribute='attribute'&gt;test2&lt;/invalid&gt;", result);
        }
Пример #7
0
        private MemoryStream SystemSpeechSynthesis(VoiceDetails voice, string speech, SpeechServiceConfiguration Configuration)
        {
            if (voice is null || speech is null)
            {
                return(null);
            }

            // Speak using the system's native speech synthesizer (System.Speech.Synthesis).
            var stream      = new MemoryStream();
            var synthThread = new Thread(() =>
            {
                try
                {
                    lock (synthLock)
                    {
                        if (!voice.name.Equals(synth.Voice.Name))
                        {
                            Logging.Debug("Selecting voice " + voice);
                            synth.SelectVoice(voice.name);
                        }

                        synth.Rate   = Configuration.Rate;
                        synth.Volume = Configuration.Volume;
                        synth.SetOutputToWaveStream(stream);
                        Logging.Debug(JsonConvert.SerializeObject(Configuration));
                        SpeechFormatter.PrepareSpeech(voice, ref speech, out var useSSML);
                        if (useSSML)
                        {
                            try
                            {
                                Logging.Debug("Feeding SSML to synthesizer: " + speech);
                                synth.SpeakSsml(speech);
                            }
                            catch (Exception ex)
                            {
                                var badSpeech = new Dictionary <string, object>
                                {
                                    { "voice", voice },
                                    { "speech", speech },
                                    { "exception", ex }
                                };
                                Logging.Warn("Speech failed. Stripping IPA tags and re-trying.", badSpeech);
                                synth.SpeakSsml(SpeechFormatter.DisableIPA(speech));
                            }
                        }
                        else
                        {
                            Logging.Debug("Feeding normal text to synthesizer: " + speech);
                            synth.Speak(speech);
                        }
                    }

                    stream.Position = 0;
                }
                catch (ThreadAbortException)
                {
                    Logging.Debug("Thread aborted");
                }
                catch (Exception ex)
                {
                    Logging.Warn("Speech failed: ", ex);
                    var badSpeech = new Dictionary <string, object>
                    {
                        { "voice", voice },
                        { "speech", speech },
                    };
                    string badSpeechJSON = JsonConvert.SerializeObject(badSpeech);
                    Logging.Info("Speech failed", badSpeechJSON);
                }
            });

            synthThread.Start();
            synthThread.Join();
            return(stream);
        }
Пример #8
0
        private SpeechSynthesisStream WindowsMediaSpeechSynthesis(VoiceDetails voice, string speech, SpeechServiceConfiguration Configuration)
        {
            if (voice is null || speech is null)
            {
                return(null);
            }

            // Speak using the Windows.Media.SpeechSynthesis speech synthesizer.
            SpeechSynthesisStream stream = null;
            var synthThread = new Thread(() =>
            {
                try
                {
                    double ConvertSpeakingRate(int rate)
                    {
                        // Convert from rate from -10 to 10 (with 0 being normal speed) to rate from 0.5X to 3X (with 1.0 being normal speed)
                        var result = 1.0;
                        if (rate < 0)
                        {
                            result += rate * 0.05;
                        }
                        else if (rate > 0)
                        {
                            result += rate * 0.2;
                        }

                        return(result);
                    }

                    lock (synthLock)
                    {
                        if (!voice.name.Equals(synth.Voice.DisplayName))
                        {
                            Logging.Debug("Selecting voice " + voice);
                            synth.Voice =
                                SpeechSynthesizer.AllVoices.FirstOrDefault(v =>
                                                                           v.DisplayName == voice.name);
                        }

                        synth.Options.SpeakingRate = ConvertSpeakingRate(Configuration.Rate);
                        synth.Options.AudioVolume  = (double)Configuration.Volume / 100;
                        Logging.Debug(JsonConvert.SerializeObject(Configuration));

                        SpeechFormatter.PrepareSpeech(voice, ref speech, out var useSSML);
                        if (useSSML)
                        {
                            try
                            {
                                Logging.Debug("Feeding SSML to synthesizer: " + speech);
                                stream = synth.SynthesizeSsmlToStreamAsync(speech).AsTask().Result;
                            }
                            catch (Exception ex)
                            {
                                var badSpeech = new Dictionary <string, object>
                                {
                                    { "voice", voice },
                                    { "speech", speech },
                                    { "exception", ex }
                                };
                                Logging.Warn("Speech failed. Stripping IPA tags and re-trying.", badSpeech);
                                stream = synth.SynthesizeSsmlToStreamAsync(SpeechFormatter.DisableIPA(speech)).AsTask().Result;
                            }
                        }
                        else
                        {
                            Logging.Debug("Feeding normal text to synthesizer: " + speech);
                            stream = synth.SynthesizeTextToStreamAsync(speech).AsTask().Result;
                        }
                    }

                    stream.Seek(0);
                }
                catch (ThreadAbortException)
                {
                    Logging.Debug("Thread aborted");
                }
                catch (Exception ex)
                {
                    var badSpeech = new Dictionary <string, object>
                    {
                        { "voice", voice },
                        { "speech", speech },
                        { "exception", ex }
                    };
                    string badSpeechJSON = JsonConvert.SerializeObject(badSpeech);
                    Logging.Warn("Speech failed", badSpeechJSON);
                }
            });

            synthThread.Start();
            synthThread.Join();
            return(stream);
        }