2015-07-01 55 views
4

我想与SpeechSynthesizer一起使用n音讯,但我不能没有先写.wav文件到硬盘的工作。使用n音讯与SpeechSynthesizer

我想不通为什么,我都尝试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,但那更糟。

回答

1

你只是大约有实例3在你的记忆流呼叫Flush重新定位的开始之前。另外,Play仅开始播放,因此您需要等待播放才能完成,或者将WaveOut实例移到using区块之外。否则,它只会在垃圾回收之前得到垃圾回收。

+0

谢谢你,是我自己主演的盲目就可以了,这是关闭的原因,因为垃圾收集。我以为内存流上的Flush()是多余的,因为它已经直接写入RAM了。 [链接](https://msdn.microsoft.com/en-us/library/vstudio/system.io.memorystream.flush(v = vs.100).aspx) –

+1

是的可能冲洗没有必要,这正是我在自己的实现中所拥有的,所以我想我会提及它 –

+0

我还必须将SpeechSynthesizer放在它自己的线程中,否则我仍然只能得到输出的一部分。有关更多信息,另请参阅本[回答](http://stackoverflow.com/a/5599972/3131828)。 – MagicMau

0

此代码的工作对我来说,如果能帮助(对解决方案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();