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); }
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); }
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); }
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 "Foo".", result); }
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> & Co's shop", result); }
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("<invalid>test</invalid> <invalid withattribute='attribute'>test2</invalid>", result); }
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); }
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); }