ALSA: Ways to prevent underrun for speaker
Solution 1
I assume this code runs in a tight loop and is intended to block on snd_pcm_writen()
. The sample-rate isn't given; I assume 48kHz since the numbers all divide nicely.
What I think is going here is as follows:
snd_pcm_write()
doesn't guarantee to write all frames provided (the return value is only ever checked for error conditions). Judging from the logging ofsnd_pcm_avail()
it's in fact consumingavail_min
or144
frames on each. This is 3ms of audio.- Assuming that audio is not running at this point, after two writes, the number of frames in the buffer is equal to
start_threshold
- at288
samples; audio output starts - calls to
printf()
block, and I seem to remember thatsnd_pcm_avail()
has to synchronise with the audio output hardware and might also block. Since you are now 6ms ahead of the playback, it's entirely possible that the buffer is running dry during the time of the third call ofsnd_pcm_writen()
In summary, you shouldn't be calling printf()
at this point, and you probably need to compensate for fact that snd_pcm_writen()
isn't consuming all of the frames in pSpeakerBuf
Solution 2
It is the buffer underrun,You can try increasing the buffer size by explicitly mentioning it in your ~/.asoundrc file ?
Lunar Mushrooms
Updated on July 09, 2022Comments
-
Lunar Mushrooms almost 2 years
I am playing a single channel audio in non-interleaved mode. I am getting underrun when I am writing audio data into speaker :
ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred
Here is how I write:
printf("%d",snd_pcm_avail (spkhandle)); ret = snd_pcm_writen(spkhandle, pSpeakerBuf , framesIn18Millisec); if(ret < 0) { snd_pcm_recover(spkhandle, ret, 0); }
What are the different ways/parameter configurations to prevent ALSA under run ?
(I am using Linux 3.0, ARM )
Edit: Here is a buffer measurement using snd_pcm_avail() API
snd_pcm_avail = 2304 << snd_pcm_writen call 1 success snd_pcm_avail = 2160 << snd_pcm_writen call 2 success snd_pcm_avail = 2016 << snd_pcm_writen call 3 success snd_pcm_writen error -32 Broken pipe << snd_pcm_writen call 4 failure ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred << And displays this message
Here is the output that Marko requested for:
snd_output_t* out; .... // Do alsa parameters init .... .... snd_output_stdio_attach(&out, stderr, 0); snd_pcm_dump_sw_setup(spkhandle, out); tstamp_mode : NONE period_step : 1 avail_min : 144 period_event : 0 start_threshold : 288 stop_threshold : 2304 silence_threshold: 0 silence_size : 0 boundary : 1207959552
-
twalberg over 11 yearsBuffer underrun means the buffer is getting empty, not full. A larger buffer would tend to either not affect the symptoms, or maybe even make it worse...
-
Lunar Mushrooms over 11 yearsthanks for the tips. It helped me. By the way the real reason for underrun in my case was faulty alsa driver (custom changes).
-
Roman over 6 yearsSorry, how did you get that and how did you update your alsa driver?