title: How to Properly Write Received UDP Audio Data to ALSA with C++ on Raspberry Pi
body: <p>I have 2 Raspberry Pis and 1 of them transmits UDP frames of Audio data to the other Raspberry Pi. The UDP Packets received are 160 Bytes each. The transmitting Raspberry Pi is sending 8KHz 8-bit Mono samples. The receiving Raspberry Pi uses Qt 5.4.0 with QUDPSocket and tries to play the received data with ALSA. The code is below. Each time the "readyRead " signal is fired when bytes arrive on the receiving Raspberry Pi, the Buffer is written to ALSA. I have very Choppy and Glitchy sound coming out of the headphone Jack on the Receiving Pi - but it is recognizable. So it is working but sounds Terrible. </p>
  
  <ol>
  <li>Is there anything glaringly wrong with my configuration below for ALSA?</li>
  <li>How should I approach writing the received UDP packets to ALSA with snd_pcm_writei? </li>
  </ol>
  
  <p>Thank you for any suggestions. </p>
  
  <pre><code>UdpReceiver::UdpReceiver(QObject *parent) : QObject(parent)
  {
  
      // Debug
      qDebug() &lt;&lt; "Setting up a UDP Socket...";
  
      // Create a socket
      m_Socket = new QUdpSocket(this);
  
      // Bind to the 2616 port
      bool didBind = m_Socket-&gt;bind(QHostAddress::Any, 0x2616);
      if ( !didBind ) {
          qDebug() &lt;&lt; "Error - could not bind to UDP Port!";
      }
      else {
          qDebug() &lt;&lt; "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-&gt;pendingDatagramSize());
  
      QHostAddress sender;
      quint16 senderPort;
  
      // Cap buffer size
      int lenToRead = buffer.size();
      if ( buffer.size() &gt; NOMINAL_AUDIO_BUFFER_SIZE ) {
          lenToRead = NOMINAL_AUDIO_BUFFER_SIZE;
      }
  
      // Read the data from the UDP Port
      m_Socket-&gt;readDatagram(buffer.data(), lenToRead,
                           &amp;sender, &amp;senderPort);
  
      // Kick off audio playback
      if ( m_NumberUDPPacketsReceived == 0 ) {
  
          qDebug() &lt;&lt; "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 (&amp;playback_handle, snd_device_out, SND_PCM_STREAM_PLAYBACK, 0)) &lt; 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 (&amp;hw_params)) &lt; 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)) &lt; 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)) &lt; 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)) &lt; 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)) &lt; 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)) &lt; 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)) &lt; 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)) &lt; 0) {
              fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
                       snd_strerror (err));
              exit (1);
          }
  
          qDebug() &lt;&lt; "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++;
  
  }
  </code></pre>