如何在Raspberry Pi上用C语言将接收到的UDP音频数据正确写入ALSA

如何在Raspberry Pi上用C语言将接收到的UDP音频数据正确写入ALSA,第1张

概述我有2个Raspberry Pis,其中1个将UDP帧的音频数据传输到另一个Raspberry Pi.收到的UDP数据包各为160字节.传输的Raspberry Pi正在发送8KHz 8位单声道样本.接收Raspberry Pi使用带有QUDPSocket的Qt 5.4.0并尝试使用ALSA播放接收的数据.代码如下.每当字节到达接收Raspberry Pi时触发“readyRead”信号,缓冲区就 我有2个RaspBerry Pis,其中1个将UDP帧的音频数据传输到另一个RaspBerry Pi.收到的UDP数据包各为160字节.传输的RaspBerry Pi正在发送8KHz 8位单声道样本.接收RaspBerry Pi使用带有QUDPSocket的Qt 5.4.0并尝试使用ALSA播放接收的数据.代码如下.每当字节到达接收RaspBerry Pi时触发“readyRead”信号,缓冲区就会写入ALSA.我在接收Pi上的耳机插孔中发出了非常低声和毛躁的声音 – 但它是可识别的.所以它工作但听起来很糟糕.

>对于ALSA,我的配置有什么明显的错误吗?
>我应该如何使用snd_pcm_writei将收到的UDP数据包写入ALSA?

谢谢你的任何建议.

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_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,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,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,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,"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,那么您将切断传入的数据.你试过删除那段代码吗? 总结

以上是内存溢出为你收集整理的如何在Raspberry Pi上用C语言将接收到的UDP音频数据正确写入ALSA全部内容,希望文章能够帮你解决如何在Raspberry Pi上用C语言将接收到的UDP音频数据正确写入ALSA所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1239641.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-06
下一篇2022-06-06

发表评论

登录后才能评论

评论列表(0条)

    保存