ALSA:防止扬声器欠载的方法
Posted
技术标签:
【中文标题】ALSA:防止扬声器欠载的方法【英文标题】:ALSA: Ways to prevent underrun for speaker 【发布时间】:2013-01-14 03:08:24 【问题描述】:我正在非交错模式下播放单声道音频。当我将音频数据写入扬声器时,我遇到了不足:ALSA lib pcm.c:7339:(snd_pcm_recover) underrun occurred
我是这样写的:
printf("%d",snd_pcm_avail (spkhandle));
ret = snd_pcm_writen(spkhandle, pSpeakerBuf , framesIn18Millisec);
if(ret < 0)
snd_pcm_recover(spkhandle, ret, 0);
有哪些不同的方法/参数配置可以防止 ALSA 下运行?
(我使用的是 Linux 3.0,ARM)
编辑: 这是使用 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
这是 Marko 要求的输出:
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
【问题讨论】:
你的线程有实时调度优先级吗? @Marko,是的,我已经给予实时调度优先级 - SCHED_FIFO。 你的缓冲期相对通知期是多少? 我是 alsa 的新手。我将 18 毫秒的音频写入单声道扬声器(因为我的自定义嵌入式系统需要 18 毫秒)。正如您在问题中看到的那样, snd_pcm_avail 减少了 144 个字节。如何避免这种情况? 您会期望缓冲区中样本的可用空间在写入缓冲区后会减少 - 但在 18 毫秒内会减少超过 144 帧。您愿意在音频开始之前在您的代码中的某处调用snd_pcm_dump_sw_setup()
,并与我们分享控制台输出吗?
【参考方案1】:
我假设这段代码在一个紧密的循环中运行,并且旨在阻止snd_pcm_writen()
。没有给出采样率;我假设是 48kHz,因为这些数字都很好地划分。
我认为这里的情况如下:
snd_pcm_write()
不保证写入所有提供的帧(返回值只检查错误情况)。从snd_pcm_avail()
的记录来看,实际上每个都消耗avail_min
或144
帧。这是 3ms 的音频。
假设此时音频没有运行,两次写入后,缓冲区中的帧数等于start_threshold
-288
采样;音频输出开始
调用printf()
阻塞,我似乎记得snd_pcm_avail()
必须与音频输出硬件同步并且也可能阻塞。由于您现在比播放时间提前了 6 毫秒,因此在第三次调用 snd_pcm_writen()
期间,缓冲区完全有可能耗尽。
总而言之,此时您不应该调用printf()
,并且您可能需要弥补snd_pcm_writen()
并未消耗pSpeakerBuf
中的所有帧这一事实
【讨论】:
感谢您的提示。它帮助了我。顺便说一句,在我的案例中,欠载的真正原因是 alsa 驱动程序有问题(自定义更改)。 对不起,你是怎么得到这个的,你是怎么更新你的 alsa 驱动的?【参考方案2】:这是缓冲区欠载,您可以尝试通过在 ~/.asoundrc 文件中明确提及来增加缓冲区大小?
【讨论】:
缓冲区不足意味着缓冲区变得清空,而不是满。较大的缓冲区往往不会影响症状,甚至可能会使情况变得更糟......以上是关于ALSA:防止扬声器欠载的方法的主要内容,如果未能解决你的问题,请参考以下文章