我在非交错模式下播放单声道音频。当我将音频数据写入扬声器时,我变得不安全: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
最佳答案
我假设此代码在一个紧密循环中运行,并且打算在snd_pcm_writen()
上进行阻止。没有给出采样率;我假设48kHz,因为数字都很好地相除。
我认为这里的内容如下:
snd_pcm_write()
不保证写出所有提供的帧(仅检查返回值是否有错误情况)。从snd_pcm_avail()
的日志记录来看,实际上每个帧都在消耗avail_min
或144
帧。这是3毫秒的音频。 start_threshold
-在288
样本处;音频输出开始printf()
块,我似乎还记得snd_pcm_avail()
必须与音频输出硬件同步,并且也可能会阻塞。由于您现在比回放快6毫秒,因此在第三次调用snd_pcm_writen()
总而言之,您此时不应该调用
printf()
,并且您可能需要弥补snd_pcm_writen()
并没有消耗pSpeakerBuf
中的所有帧这一事实。关于c - ALSA:防止扬声器欠载的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14601666/