【问题标题】:Using NAudio with SpeechSynthesizer将 NAudio 与 SpeechSynthesizer 一起使用
【发布时间】:2015-09-18 06:13:35
【问题描述】:

我想将 NAudio 与 SpeechSynthesizer 一起使用,但如果不先将 .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 - 结果与示例 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,但情况更糟。

【问题讨论】:

    标签: c# text-to-speech naudio


    【解决方案1】:

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

    【讨论】:

    • 谢谢,我自己瞎了眼,垃圾回收的原因。我认为内存流上的 Flush() 是多余的,因为它已经直接写入 RAM ??。 link
    • 是的,刷新可能不是必需的,这正是我在自己的实现中所拥有的,所以我想我还是会提到它
    • 我还必须将 SpeechSynthesizer 放在它自己的线程中,否则我仍然会遇到仅获取输出片段的问题。另请参阅answer 了解更多信息。
    • 不需要其他线程,等待播放完成即可。你处理播放器太早了。
    【解决方案2】:

    此代码适用于我,如果可以提供帮助(对于解决方案 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多