0

我可能错了,但似乎我在 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 创建一个阅读器流:

            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循环(在这里注释掉......)

这是我将代码移到语音类时的样子。如果我从表单中实例化它,并在那里运行它,我会得到截断的声音:

        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;
        //}

似乎我错过了一些简单的东西,但我似乎无法让它在语音类中工作,只能从表单中得到。

4

1 回答 1

1

您的问题最可能的解释是:

  1. 您正在尝试从MemoryStream仍在写入的
  2. 您的输出设备已超出范围并在播放时被垃圾回收

尝试订阅您的PlaybackStopped事件IWavePlayer以查看它何时以及为何触发(如果出现问题,它可能包含异常)。

另外,我非常怀疑您是否需要 aWaveFormatConversionStream和 aBlockAlignReductionStream,通过删除它们来简化您的代码。

于 2013-05-08T08:41:59.780 回答