У меня есть аудиоприложение, которое использует ALSA для воспроизведения аудиосэмплов. Устройство "hw:0" настроено следующим образом: Образцы: 48 кГц, 16 бит LE Размер буфера: 1920 кадров (=20 мс) Размер периода: 960 кадров (=10 мс) Это псевдокод:
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;
}
Лог выглядит так:
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
Происходят две странности: 1. Хотя у меня все пишет 960 кадров, snd_pcm_avail_update не всегда это отражает 2. На ровном месте вдруг происходит xrun. Например, в случае, когда доступно только 18 кадров, следующая строка выдает xrun при попытке записи нового периода в буфер.
Может кто-нибудь объяснить мне, что здесь происходит?