我在我的 C# WPF 项目中实现了一个 TTS。
以前,我使用 System.Speech.Synthesis 命名空间中的 TTS 说话。讲话内容为 SSML 格式(Speech Synthesizer Markup Language,支持自定义语速、语音、强调),如下所示:
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US"><prosody rate="x-fast">hello world. This is a long sentence speaking very fast!</prosody></speak>
但不幸的是,System.Speech.Synthesis TTS 存在内存泄漏问题,正如我在 .Net Speech.Synthesizer 中的内存泄漏问题中提到的那样?.
所以我决定使用 SAPI COM 组件。我可以轻松地让 SAPI 说出纯文本内容。但后来我继续尝试让它说 SSML 字符串,我失败了。代码如下:
//Initialize TTS instance
SpeechLib.SpVoiceClass tts = new SpeechLib.SpVoiceClass();
//Generate SSML string
string textToSpeak = "hello world speak Extra Fast.";
PromptBuilder pb = new PromptBuilder();
pb.StartStyle(new PromptStyle(PromptRate.ExtraFast));
pb.AppendText(textToSpeak);
pb.EndStyle();
ssmlString = pb.ToXml(); //ssmlString = @"<speak version=""1.0"" ....
//Speak!
tts.Speak(ssmlString, SpeechLib.SpeechVoiceSpeakFlags.SVSFParseSsml);
代码的重要部分是
tts.Speak(ssmlString, SpeechLib.SpeechVoiceSpeakFlags.SVSFParseSsml);
它使用SpeechVoiceSpeakFlags 枚举来指定 TTS 说话行为。我尝试了几种标志组合,但没有一个能成功说出 SSML 内容。
特别是,上面的代码还会引发以下异常:
System.Runtime.InteropServices.COMException 未处理
Message="Exception from HRESULT: 0x80045003"
Source="Interop.SpeechLib" ErrorCode=-2147201021 StackTrace: 在 SpeechLib.SpVoiceClass.Speak(String Text, SpeechVoiceSpeakFlags Flags) 在 SpeechSynthesisMemLeakTest.Program.Test2() 在 D:\Proj\TestSolutions\CSharp_Quick_Apps\SpeechSynthesisMemLeakTest\Program.cs:第 60 行 SpeechSynthesisMemLeakTest.Program.Main(String[] args) 在 D:\Proj\TestSolutions\CSharp_Quick_Apps\SpeechSynthesisMemLeakTest\Program.cs:第 17 行在 Microsoft 的 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)。 VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart() InnerException:
谁能告诉我如何正确使用该标志说出 SSML 内容?