我有2个树莓派,其中1个将audio数据的UDP帧传输到另一个树莓派。 收到的UDP数据包是每个160字节。 发送树莓派正在发送8KHz的8位单声道采样。 接收树莓派使用Qt 5.4.0与QUDPSocket并尝试播放收到的数据与ALSA。 代码如下。 当字节到达接收树莓派时,每当“readyRead”信号被触发,缓冲区就被写入ALSA。 接收机上的耳机插孔出现了非常杂乱的声音,但它是可识别的。 所以这是工作,但听起来很糟糕。
谢谢你的任何build议。
UdpReceiver::UdpReceiver(QObject *parent) : QObject(parent) { // Debug qDebug() << "Setting up a UDP Socket..."; // Create a socket m_Socket = new QUdpSocket(this); // Bind to the 2616 port bool didBind = m_Socket->bind(QHostAddress::Any, 0x2616); if ( !didBind ) { qDebug() << "Error - could not bind to UDP Port!"; } else { qDebug() << "Success binding to port 0x2616!"; } // Get notified that data is incoming to the socket connect(m_Socket, SIGNAL(readyRead()), this, SLOT(readyRead())); // Init to Zero m_NumberUDPPacketsReceived = 0; } void UdpReceiver::readyRead() { // When data comes in QByteArray buffer; buffer.resize(m_Socket->pendingDatagramSize()); QHostAddress sender; quint16 senderPort; // Cap buffer size int lenToRead = buffer.size(); if ( buffer.size() > NOMINAL_AUDIO_BUFFER_SIZE ) { lenToRead = NOMINAL_AUDIO_BUFFER_SIZE; } // Read the data from the UDP Port m_Socket->readDatagram(buffer.data(), lenToRead, &sender, &senderPort); // Kick off audio playback if ( m_NumberUDPPacketsReceived == 0 ) { qDebug() << "Received Data - Setting up ALSA Now...."; // Error handling int err; // Device to Write to char *snd_device_out = "hw:0,0"; if ((err = snd_pcm_open (&playback_handle, snd_device_out, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", snd_device_out, snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_U8)) < 0) { // Unsigned 8 bit fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)); exit (1); } uint sample_rate = 8000; if ((err = snd_pcm_hw_params_set_rate (playback_handle, hw_params, sample_rate, 0)) < 0) { // 8 KHz fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 1)) < 0) { // 1 Channel Mono fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)); exit (1); } if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); // Flush handle prepare for playback snd_pcm_drop(playback_handle); if ((err = snd_pcm_prepare (playback_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); } qDebug() << "Done Setting up ALSA...."; } // Grab the buffer m_Buffer = buffer.data(); // Write the data to the ALSA device int error; if ((error = snd_pcm_writei (playback_handle, m_Buffer, NOMINAL_AUDIO_BUFFER_SIZE)) != NOMINAL_AUDIO_BUFFER_SIZE) { fprintf (stderr, "write to audio interface failed (%s)\n", snd_strerror (error)); exit (1); } // Count up m_NumberUDPPacketsReceived++; }
我不理解代码的“上限缓冲区大小”部分。 如果传入的数据大于您的任意NOMINAL_AUDIO_BUFFER_SIZE,那么您将切断传入的数据。 你有没有尝试删除这一点的代码?