小编Ace*_*din的帖子

使用SpeechSynthesizer使用SpeechAudioFormatInfo进行流式传输

我正在使用System.Speech.Synthesis.SpeechSynthesizer将文本转换为语音.由于微软的文档不足(参见我的链接,没有任何评论或代码示例),我无法解决两种方法之间的差异:

SetOutputToAudioStream和SetOutputToWaveStream.

这是我推断的:

SetOutputToAudioStream接受一个流和一个SpeechAudioFormatInfo实例,该实例定义波形文件的格式(每秒采样数,每秒位数,音频通道等)并将文本写入流.

SetOutputToWaveStream只接收一个流,并将16位单声道22kHz PCM波形文件写入流中.没有办法传入SpeechAudioFormatInfo.

我的问题是SetOutputToAudioStream不会将有效的wave文件写入流.例如,在将流传递给System.Media.SoundPlayer时,我得到一个InvalidOperationException("wave header is corrupt").如果我将流写入磁盘并尝试使用WMP播放,我会收到"Windows Media Player无法播放文件..."错误,但SetOutputToWaveStream写入的流在两者中都正常播放.我的理论是SetOutputToAudioStream没有写一个(有效的)头.

奇怪的是,SetOutputTo*Blah*的命名约定是不一致的.SetOutputToWaveFile采用SpeechAudioFormatInfo,而SetOutputToWaveStream则不采用.

我需要能够将8kHz,16位单声道波文件写入流中,这是SetOutputToAudioStream或SetOutputToWaveStream都不允许我这样做的.有没有人深入了解SpeechSynthesizer和这两种方法?

作为参考,这里是一些代码:

Stream ret = new MemoryStream();
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
  synth.SelectVoice(voiceName);
  synth.SetOutputToWaveStream(ret);
  //synth.SetOutputToAudioStream(ret, new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
  synth.Speak(textToSpeak);
}
Run Code Online (Sandbox Code Playgroud)

解:

非常感谢@Hans Passant,这是我现在使用的要点:

Stream ret = new MemoryStream();
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
  var mi = synth.GetType().GetMethod("SetOutputStream", BindingFlags.Instance | BindingFlags.NonPublic);
  var fmt = new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono);
  mi.Invoke(synth, new object[] { ret, fmt, true, true });
  synth.SelectVoice(voiceName);
  synth.Speak(textToSpeak);
}
return …
Run Code Online (Sandbox Code Playgroud)

.net text-to-speech speech-synthesis speechsynthesizer

8
推荐指数
1
解决办法
4746
查看次数