c# - NAudio缓冲区完全异常

时间:2017-03-06 08:22:49

标签: c# stream naudio

我尝试制作软电话。它传递声音,但是在5秒后我得到了#34; Buffer Full"异常。

这是我的发送代码:

public class Media
{
    static WaveInEvent s_WaveIn = new WaveInEvent();
    Action<byte[]> waveHandler;
    public void Capture(Action<byte[]> toRtp)
    {
        s_WaveIn = new WaveInEvent();
        s_WaveIn.WaveFormat = new WaveFormat(8000, 1);//44100, 2);
        waveHandler = toRtp;

        s_WaveIn.DataAvailable += new EventHandler<WaveInEventArgs>(SendCaptureSamples);
        s_WaveIn.StartRecording();
    }

    void SendCaptureSamples(object sender, WaveInEventArgs e)
    {
        waveHandler(e.Buffer);
    }

    public void Stop()
    {
        s_WaveIn.StopRecording();
    }
}

ToRtp是

    private void ToRtp(byte[] buffer)
    {
        myRTP.SequenceNumber++;
        Sender.SendResponse(myRTP.MakePacket(alaw.Encode(buffer,0,buffer.Length)), RTPClient, rtpPort);//ToRTPData(buffer, 8000, 1), myUdpClient);
    }

接收:

class Client
{
        WaveFormat pcmFormat = new WaveFormat(8000, 16, 1);
        WaveFormat alawFormat = WaveFormat.CreateALawFormat(8000, 1);

        WaveOut waveOut;
        BufferedWaveProvider waveProvider;
        ALawChatCodec alaw = new ALawChatCodec();

    public Client(IHandlerFactory handlerFactory, IPAddress hostAddress, int portNumber)
    {
        waveOut = new WaveOut();
        waveProvider = new BufferedWaveProvider(pcmFormat);
        waveOut.Init(waveProvider);
        waveOut.Play();
    }

    private void HandleIncomingRTPRequest(IAsyncResult ar)
    {
        IPEndPoint temp = new IPEndPoint(IPAddress.Parse(asteriskip), rtpPort);
        byte[] received = RTPClient.EndReceive(ar, ref temp);
        byte[] decoded = alaw.Decode(received, 12, received.Length - 12);
        waveProvider.AddSamples(decoded, 0, decoded.Length);//Exception occures here
    }
}

我读过类似的问题,每个人都建议不要使用WaveInProvider,但在那些问题中他们不需要传输声音,他们只是保存它。为什么我得到这个例外,如果因为WaveInProvider,我怎么能在没有它的情况下进行流式传输?

EDIT。问题是我没有通过SIP发送正确的ACK请求,并且在我对初始INVITE请求得到OK响应后发送它。结果,Asterisk发给我另一个OK响应,当我收到OK邀请时,我开始流声音,所以有多个流线程。

2 个答案:

答案 0 :(得分:1)

缓冲区完全异常意味着您将数据写入缓冲区的速度比读取缓冲区要快。如果您正在播放实时流式传输的音频,这很奇怪。你确定发送音频的是什么并没有发送给你超过你期望的东西?

为了缓解偶尔的缓冲区完全异常,您可以随时清除BufferedWaveProvider,如果它已满。但是,如果它经常发生,则意味着您获得的传入音频的速度要快于播放速度。

答案 1 :(得分:0)

作为替代方案,如果您无法找出缓冲区问题的根源,则可以在DiscardOnBufferOverflow = true实例上设置BufferedWaveProvider。这有点像破解,因为您可能会删除样本,但是如果您不需要完美的精度,这是一种快速而肮脏的解决方法。