简体   繁体   English

c# - NAudio 缓冲区已满异常

[英]c# - NAudio buffer full exception

I try to make a softphone.我尝试制作软电话。 It passes sound, but after 5 seconds i get "Buffer Full" exception.它通过声音,但 5 秒后我得到“缓冲区已满”异常。

Here's my sending code:这是我的发送代码:

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 is 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);
    }

Receiving:接收:

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

I read similar questions, everyone suggest to not use WaveInProvider, but in those questions they don't need to stream sound, they just save it.我读过类似的问题,每个人都建议不要使用 WaveInProvider,但是在这些问题中,他们不需要流式传输声音,他们只是保存它。 Why i get this exception, and if it's because of WaveInProvider, how can i stream without it?为什么我会收到此异常,如果是因为 WaveInProvider,我如何在没有它的情况下进行流式传输?

EDIT.编辑。 The problem was that I didn't send correct ACK request via SIP, and I send it after I get OK response to initial INVITE request.问题是我没有通过 SIP 发送正确的 ACK 请求,我在对初始 INVITE 请求的响应得到 OK 响应后发送它。 As a result, Asterisk sent me another OK response, and when I receive OK to an INVITE request I start streaming sound, so there were multiple streaming threads.结果,Asterisk 向我发送了另一个 OK 响应,当我收到 INVITE 请求的 OK 时,我开始流式传输声音,因此有多个流式传输线程。

The buffer full exception means you are writing data into the buffer faster than you are reading it out.缓冲区已满异常意味着您将数据写入缓冲区的速度比读取数据的速度快。 Which is strange if you are playing audio that is being streamed in real-time.如果您正在播放实时流式传输的音频,这很奇怪。 Are you sure that whatever is sending the audio isn't sending you more than you expect?您确定发送音频的内容不会超出您的预期吗?

To mitigate occasional buffer full exceptions you can always clear the BufferedWaveProvider if it gets full.为了减轻偶尔的缓冲区已满异常,您可以随时清除 BufferedWaveProvider 如果它已满。 But if it's happening regularly it means you are getting incoming audio faster than you can play it.但是,如果它经常发生,则意味着您获得传入音频的速度比播放速度快。

As an alternative, if you can't figure out the source of the buffer issue, you can set DiscardOnBufferOverflow = true on the BufferedWaveProvider instance.作为替代方案,如果您无法找出缓冲区问题的根源,您可以在BufferedWaveProvider实例上设置DiscardOnBufferOverflow = true This is somewhat of a hack, as you'll likely be dropping samples, but it's a quick and dirty workaround if you don't need perfect precision.这有点像黑客,因为您可能会丢弃样本,但如果您不需要完美的精度,这是一种快速而肮脏的解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM