1
votes

I have an audio application that uses ALSA to play back audio samples. The "hw:0" device has been setup as: Samples: 48kHz, 16-bit LE Buffersize: 1920 frames (=20 ms) Periodsize: 960 frames (=10 ms) This is the pseudo-code:

snd_pcm_sframes_t delayp = 0;
snd_pcm_sframes_t availp = 0;

while(true)
{
    snd_pcm_delay(m_pHandle, &delayp);
    availp = snd_pcm_avail(m_pHandle);
    print "Delay" + delay + "Available" + availp
    err = snd_pcm_writei(m_pHandle, data, periodSize);
    availp = snd_pcm_avail_update(m_pHandle);
    print "Wrote " + err + "samples - samples available" + avail;
}

The log looks like this:

Periodsize 960 frames for a periodtime of 20 ms
Buffersize 1920 frames for a buffertime of 40 ms

Delay: 0 frames/ 0 ms; available 1920 frames/ 40
Wrote 960 frames; available after write: 960 frames/ 20 ms

xrunRecovery: Underrun!!! (at least 0.669 ms/ 32.112 frames long

Delay: 0 frames/ 0 ms; available 1920 frames/ 40
Wrote 960 frames; available after write: 960 frames/ 20 ms
Delay: 955 frames/ 19.8958 ms; available 965 frames/ 20.1042
Wrote 960 frames; available after write: 9 frames/ 0.1875 ms
Delay: 906 frames/ 18.875 ms; available 1014 frames/ 21.125
...
Delay: 952 frames/ 19.8333 ms; available 968 frames/ 20.1667
Wrote 960 frames; available after write: 18 frames/ 0.375 ms

xrunRecovery: Underrun!!! (at least 234.825 ms/ 11271.6 frames long

Delay: 0 frames/ 0 ms; available 1920 frames/ 40

Wrote 960 frames; available after write: 960 frames/ 20 ms

xrunRecovery: Underrun!!! (at least 0.869 ms/ 41.712 frames long

Delay: 0 frames/ 0 ms; available 1920 frames/ 40

There are two strange things happening: 1. Although everything I write 960 frames, the snd_pcm_avail_update is not always reflecting this 2. Out of a blue, suddenly an xrun happens. For instance, in the case where only 18 frames are available, the next line gives an xrun when trying to write a new period to the buffer.

Can someone explain me what is going on here?

1

1 Answers

1
votes

When you write 960 frames, the number of available frames decreases by 960. At the same time, any samples being played increase the number of available frames.

You get an underrun when the buffer becomes empty. According to your log, your program didn't run for about 234 ms.