Пример #1
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);
        }
Пример #2
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);
        }