播放来自 UDP 收到的消息的音频,点击声音(Naudio API)

Playing Audio from UDP received message, Clicking sound (Naudio API)

我正在创建一个具有用于语音聊天的 UDP 的聊天客户端,但是当我将音频(以字节为单位)发送到其他客户端时,客户端播放音频时一切都很清晰,但我听到随机的咔嗒声的背景。我认为这可能是因为它是 UDP 而不是检查数据是否正确,但没有。即使我通过 TCP 发送,我仍然可以听到背景中的咔哒声。

要重新创建的代码:

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace QuestionStack
{
    public partial class Form1 : Form
    {
        UdpClient UDPc;
        private NAudio.Wave.WaveIn sourceStream;
        IPEndPoint ep;//where the client will send the udp data from recording
        public Form1()
        {
            InitializeComponent();
        }


        /// <summary>
        /// client clicks when he wants to start connection with other client
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartAudioButton_Click(object sender, EventArgs e)
        {
            UDPc = new UdpClient(Int32.Parse(MyPortTextBox.Text));
            ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), Int32.Parse(OtherUserTextBoxPort.Text)); // endpoint where other clienr is listening
            UDPc.Connect(ep);
            UDPc.BeginReceive(new AsyncCallback(ReceiveUdpMessage), null);
            Thread.Sleep(100);
            StartAudioRecording();
        }


        /// <summary>
        /// where the client takes the audio in bytes, he got from otehr client to convert and play the audio 
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveUdpMessage(IAsyncResult ar)
        {

            try
            {
                byte[] bytesRead = UDPc.EndReceive(ar, ref ep);

                BufferedWaveProvider provider = new BufferedWaveProvider(new WaveFormat(44100, 16, 2));
                provider.DiscardOnBufferOverflow = true;
                provider.AddSamples(bytesRead, 0, bytesRead.Length);
                DirectSoundOut _waveOut = new DirectSoundOut();
                _waveOut.Init(provider);
                _waveOut.Play();

                UDPc.BeginReceive(new AsyncCallback(ReceiveUdpMessage), null);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }


        /// <summary>
        /// starts recording and sents to other client if check box to only listen is not on
        /// </summary>
        public void StartAudioRecording()
        {
            if (!checkBoxOnlyListen.Checked)
            {
                sourceStream = new NAudio.Wave.WaveIn();
                sourceStream.DeviceNumber = 0;
                sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(0).Channels);


                sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);

                sourceStream.StartRecording();
            }
        }


        /// <summary>
        /// if got recording, sends it to other client
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
        {
            if (sourceStream == null) return;
            try
            {
                UDPc.Send(e.Buffer, e.BytesRecorded);//sending data UPD
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

        }
    }
}

FormsPicture 所以如果数据没问题,我翻译和播放它的方式就会导致问题。 我查了下,Wave out对象是不是在方法外创建的并不重要。 我尝试了一百万种不同的方法来修复它。我不知道该怎么做。如果有人知道更好的翻译或修复方法,那将是我的一周。

提前致谢。

您应该创建一个输出设备和一个 BufferedWaveProvider,并在收到任何音频之前开始播放。然后在接收函数中,您唯一需要做的就是将接收到的音频添加到BufferedWaveProvider。但是,如果通过网络接收音频的速度不够快,您仍然会获得点击,这意味着您在接收到的音频中有丢失。