有没有办法在NAudio中同步播放WAV文件?

时间:2013-05-07 21:04:54

标签: c# text-to-speech naudio

我可能错了,但看起来我在NAudio中的WAV文件正在异步播放,如果我从库中调用它,我可以听到WAV启动,但它几乎立即退出(并停止播放)。

如果我从表格(保持打开状态)运行它就可以了。但是如果我尝试从代码作为后台线程运行它,我只会在开始时听到一个小片段。它看起来像是在声音播放完毕之前退出的方法。

我正在使用文本到语音合成器在内存流上创建WAV:

        SpeechSynthesizer m_speechSynth = new SpeechSynthesizer();
        m_speechSynth.Volume = 100;
        m_speechSynth.Rate = 2;

        MemoryStream waveStream = new MemoryStream();

        m_speechSynth.SetOutputToWaveStream(waveStream);
        m_speechSynth.Speak(txtToRead);
        m_speechSynth.SetOutputToNull();

        waveStream.Position = 0; // reset counter to start

工作正常。然后我创建了一个围绕NAudio的类:

VoiceThroughNetAudio netAudio = new VoiceThroughNetAudio(waveStream, "WAV");

我正在努力保持代码示例易于遵循......但是这个类的功能只是初始化事物,并让我更高级别的控制来完成NAudio播放器上的主要内容...... VoiceThroughNetAudio构造函数,

首先,我从MemStream创建一个阅读器Stream:

            readerStream = new WaveFileReader(memStream);
            readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
            readerStream = new BlockAlignReductionStream(readerStream);

并附上音量控制(所以我可以放大它):

_volumeStream = new WaveChannel32(Reader);

当我从WinForm代码中调用它时,一切正常:

        MemoryStream waveStream = new MemoryStream();
        ReadStringAmplified(readTextField.Text, waveStream); // TTS to waveStream
        VoiceThroughNetAudio  PlaySound = new VoiceThroughNetAudio (waveStream, "WAV");
        PlaySound.Volume = 9;
        PlaySound.Play();

但是当我将此代码移动到Voice类中时,声音将播放,然后停止(几乎立即)。就像它开始一个事件然后在声音结束前退出?如果是这样,是否有一种让方法等到声音结束的好方法? (我尝试将一个while循环放入并检查状态,但这最终会进入while循环一段无限期(在这里注释掉了......)

以下是将代码移动到Voice Class时代码的外观。如果我从表单中实例化它,并在那里运行它,我得到截断的声音:

        SpeechSynthesizer m_speechSynth = new SpeechSynthesizer();
        m_speechSynth.Volume = 100;
        m_speechSynth.Rate = 2;

        MemoryStream waveStream = new MemoryStream();
        m_speechSynth.SetOutputToWaveStream(waveStream);
        m_speechSynth.Speak(txtToRead);
        m_speechSynth.SetOutputToNull();
        waveStream.Position = 0; // reset counter to start

        VoiceThroughNetAudio netAudio = new VoiceThroughNetAudio(waveStream, "WAV");
        netAudio.Volume = 9;
        TimeSpan ts = netAudio.TotalDuration;
        string len = ts.Milliseconds.ToString();

        netAudio.Play();

        //VoiceThroughNetAudio.PlayBackState chkState = netAudio.State;
        //while (netAudio.State != VoiceThroughNetAudio.PlayBackState.Stopped)
        //{
        //    chkState = netAudio.State;
        //}

似乎我错过了一些简单的东西,但我似乎无法在Voice Class中使用它,只能从Form中使用。

1 个答案:

答案 0 :(得分:1)

您问题的最可能解释是:

  1. 您正在尝试使用仍在写入<{li>的MemoryStream
  2. 您的输出设备已超出范围,并且在播放时已被垃圾收集
  3. 尝试订阅PlaybackStopped的{​​{1}}事件,了解它的触发时间和原因(如果出现问题,可能会包含异常)。

    此外,我非常怀疑您需要IWavePlayerWaveFormatConversionStream,以便通过删除代码来简化您的代码。