将 NAudio 与 SpeechSynthesizer 结合使用

Using NAudio with SpeechSynthesizer

我想将 NAudio 与 SpeechSynthesizer 一起使用,但如果不先将 .wav 文件写入磁盘,我将无法使用它。

我不明白为什么,我尝试了 RAW 波形数据和 headers 的波形,请参阅以下示例...

示例 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 header,以避免设置波形格式。

    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 - 与示例 3 相同的结果

这使用原始数据并且有点庞大。

  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,但那更糟。

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

此代码对我有用,如果可以帮助(解决方案 3)。

        IWaveProvider provider = null;
        var stream = new MemoryStream();
        using (var synth = new SpeechSynthesizer())
        {

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

            stream.Seek(0, SeekOrigin.Begin);
            provider = new RawSourceWaveStream(stream, new WaveFormat(44100, 16, 1));

        }
        var waveOut = new WaveOut();
        waveOut.Init(provider);
        waveOut.Play();