我正在非交错模式下播放单声道音频.当我将音频数据写入扬声器时,我得到了不足:ALSA lib pcm.c:7339:(snd_pcm_recover)发生欠载
我是这样写的:
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帧.这是3ms的音频.
>假设此时音频没有运行,在两次写入之后,缓冲区中的帧数等于start_threshold – 288个样本;音频输出开始
>调用printf()块,我似乎记得snd_pcm_avail()必须与音频输出硬件同步,也可能阻塞.因为你现在比播放提前6ms,所以在第三次调用snd_pcm_writen()期间,缓冲区完全可能正在运行
总之,你不应该在这一点上调用printf(),你可能需要补偿snd_pcm_writen()没有消耗pSpeakerBuf中所有帧的事实.