使用带有SpeechSynthesizer的NAudio

时间:2015-07-01 07:43:30

标签: c# text-to-speech naudio

我想将NAudio和SpeechSynthesizer一起使用,但是如果不首先将.wav文件写入磁盘,我就无法工作。

我无法弄清楚为什么,我尝试了RAW wav数据和带标题的wav,请参阅以下示例。

我有以下例子:

示例1 - 这可行,但会保存.wav文件

  using (var synth = new SpeechSynthesizer())
  {
    synth.SetOutputToWaveFile(@".\Test.wav");
    synth.Speak("This is sample text-to-speech output.");
    synth.SetOutputToNull();

    var reader = new WaveFileReader(@".\Test.wav");
    var waveOut = new WaveOut();
    waveOut.Init(reader);
    waveOut.Play();
  }

示例2 - 这也有效,但仍使用文件

  using (var synth = new SpeechSynthesizer())
  using (var stream = new MemoryStream())
  {
    synth.SetOutputToWaveStream(stream);
    synth.Speak("This is sample text-to-speech output.");

    using (var fileStream = File.Create(@".\Test.wav"))
    {
      stream.Seek(0, SeekOrigin.Begin);
      stream.CopyTo(fileStream);
    }

    var reader = new WaveFileReader(@".\Test.wav");
    var waveOut = new WaveOut();
    waveOut.Init(reader);
    waveOut.Play();
  }

示例3 - 这不起作用,只需播放一小段时间然后停止

我故意使用SetOutputToWaveStream来保留RIFF标头,以避免设置波形格式。

    using (var synth = new SpeechSynthesizer())
    using (var stream = new MemoryStream())
    {
      synth.SetOutputToWaveStream(stream);
      synth.Speak("This is sample text-to-speech output.");

      stream.Seek(0, SeekOrigin.Begin);
      var reader = new WaveFileReader(stream);
      var waveOut = new WaveOut();
      waveOut.Init(reader);
      waveOut.Play();
    }

示例4 - 与示例4相同的结果

这使用原始数据并且有点笨重。

  using (var synth = new SpeechSynthesizer())
  using (var stream = new MemoryStream())
  {
    synth.SetOutputToAudioStream(stream, new SpeechAudioFormatInfo(44100, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
    synth.Speak("This is sample text-to-speech output.");

    stream.Seek(0, SeekOrigin.Begin);
    IWaveProvider provider = new RawSourceWaveStream(stream, new WaveFormat(44100, 16, 1));
    var waveOut = new WaveOut();
    waveOut.Init(provider);
    waveOut.Play();
  }

我也尝试过使用WasapiOut,但情况更糟。

2 个答案:

答案 0 :(得分:2)

你就是那里的示例3.在重新定位到开始之前,在内存流上调用Flush。此外,Play仅开始播放,因此您需要等待播放完成或将WaveOut实例移至using块之外。否则它只是在收集垃圾之前才会收集垃圾。

答案 1 :(得分:0)

这段代码对我有用,如果有帮助的话(对于解决方案3)。

{
    "metafield": {
        "namespace": "inventory",
        "key": "test",
        "value": [{
            "5": 10,
            "8": 10
        }],
        "value_type": "string"
    }
}