Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 需求: APP按照16k, 16bit, 单声道去读取录音数据, 每100ms读取一次, 也就是一次要读取3200字节,读取完之后写到网络发送到发送到PC. 现象: 经验证发现,如果读取之后直接写到文件,听到的声音不会有呲呲的噪音. 而当写到网络发送缓冲时,因为耗时比写文件要长,会存在读取到的声音 会有呲呲的噪音,怀疑是丢包了. 分析: 当APP去写网络端buffer时,驱动的dma在从audio codec读取数据存到 kernel的buffer中,然后当app去读取hal层buffer时(hal层buffer从 kernel buffer获取),因为dma存的buffer一定,当数据量较多的时候, buffer有可能被冲掉,这样app拿到的数据可能就有问题了. 解决方法: 通过减小HAL层的period size来降低dma的传输数据量.
[kris@:~/rk3288/hardware/rockchip/audio/tinyalsa_hal]$ g df
diff --git a/tinyalsa_hal/audio_hw.h b/tinyalsa_hal/audio_hw.h
index d2c7992..a013469 100755
--- a/tinyalsa_hal/audio_hw.h
+++ b/tinyalsa_hal/audio_hw.h
@@ -178,9 +178,9 @@ struct pcm_config pcm_config = {
struct pcm_config pcm_config_in = {
.channels = 2,
- .rate = 44100,
- .period_size = 128,
- .period_count = 4,
+ .rate =44100,
+ .period_size = 16,
+ .period_count = 32,
.format = PCM_FORMAT_S16_LE,
};
修改period count是因为总buffer size需要一定,不然period size小了,传输快了, 数据也会丢失.
关于period_size 和 period_count的解释,可参考链接文章.
period_size. 每次传输的数据长度。值越小,时延越小,cpu占用就越高。
period_count. 缓之冲区period的个数。缓冲区越大,发生XRUN的机会就越少。
参考:
http://blog.csdn.net/azloong/article/details/51044893
http://www.alivepea.me/kernel/ALSA-TinyAlsa/