title: How to properly handle xrun in ALSA programming when playing audio with snd_pcm_writei()?
body: <p>I've tried multiple example programs that appear to have code to handle xruns under playback:</p>
  
  <p><a href="https://albertlockett.wordpress.com/2013/11/06/creating-digital-audio-with-alsa/" rel="nofollow noreferrer">https://albertlockett.wordpress.com/2013/11/06/creating-digital-audio-with-alsa/</a></p>
  
  <p><a href="https://www.linuxjournal.com/article/6735" rel="nofollow noreferrer">https://www.linuxjournal.com/article/6735</a> (listing 3)</p>
  
  <p>When using snd_pcm_writei(), it appears that when the return value is -EPIPE (which is xrun/underrun), they do:</p>
  
  <pre><code>if (rc == -EPIPE) {
    /* EPIPE means underrun */
    fprintf(stderr, "underrun occurred\n");
    snd_pcm_prepare(handle);
  }
  </code></pre>
  
  <p>I.e. call snd_pcm_prepare() on the handle.</p>
  
  <p>However, I still get stuttering when I attempt to run programs like these. Typically, I will get at least a few, to maybe half a dozen xrun, and then it will play smoothly and continuously without further xruns. However, if I have something else using the sound card, such as Firefox, I will get many more xruns, and sometimes only xruns. But again, even if I kill any other program that uses the sound card, I still experience the issue with some initial xruns and actual stuttering on the speakers.</p>
  
  <p>This is not acceptable for me, how can I modify this type of xrun handling to prevent stuttering?</p>
  
  <p>My own attempt at figuring this out:</p>
  
  <p>From the ALSA API, I see that snd_pcm_prepare() does:</p>
  
  <blockquote>
    <p>Prepare PCM for use.</p>
  </blockquote>
  
  <p>This is not very helpful to an ALSA beginner like myself. It is not explained how this can be used to recover xrun issues.</p>
  
  <p>I also note, from: <a href="https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html" rel="nofollow noreferrer">https://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html</a></p>
  
  <blockquote>
    <p>SND_PCM_STATE_XRUN
        The PCM device reached overrun (capture) or underrun (playback). You can use the -EPIPE return code from I/O functions
    (snd_pcm_writei(), snd_pcm_writen(), snd_pcm_readi(), snd_pcm_readn())
    to determine this state without checking the actual state via
    snd_pcm_state() call. It is recommended to use the helper function
    snd_pcm_recover() to recover from this state, but you can also use
    snd_pcm_prepare(), snd_pcm_drop() or snd_pcm_drain() calls.</p>
  </blockquote>
  
  <p>Again, it is not clear to me. I can use snd_pcm_prepare() OR I can use these other calls? What is the difference? What should I use?</p>