Alsa period_size/periods/buffer_size计算逻辑

Alsa period_size/periods/buffer_size计算逻辑

背景:

ZX2000 FPGA验证时发现,S24_3LE mono格式的音乐播放时,会有周期性的噪音出现,噪音信号发生时是有音频数据的,只是看起来和原数据相比有位移,用正弦波测试时可以看出噪音信号的包络和原信号有些相似。

用默认配置的时候,读取runtime->period_size = 1366一个比较奇怪的值。

当用tinyplay –p设置period_size时,发现如果设置的period_size <= 1024的时候,读出的runtime->period_size就会为1024这样常见的值,而此时播放S24_3LE mono格式的音乐就不会有噪音。

runtime->period_size = 1366这个奇怪的值是怎么来的?

原因:

在驱动里,我们会设置

period_bytes_min = 1024 * 4 = 4096,

period_bytes_max = 1024 *16,

alsa会根据上面的最大最小值算出一个合适的值作为runtime->period_size

pcm_native.c中,

上面的rule 10/11/12会定义相应的计算规则,其中rule 11是何我们关系最大的。

 

 

上面:

a->min = 4096// period_bytes_min

k = 8// (void *) 8, rule -> private

b->max// S24_3LE mono时为24S24_3LE stereo 时为24*2 S24_LE stereo 时为32*2S16_LE mono 时为16, S16_LE stereo时为16*2。实际上就是一个framebit数。

c->min = a->min * k /b->max = 4096 * 8 /24 = 1365.3333

上面:

i->min = 1024; //tinyplay.c main()中设置的

v->min = c-> min = 1365;

i->min < v->min, so i->min = v->min = 1365;

i->min++ , so i->min = 1366

也就是runtime->period_size = 1366

 

如果在驱动里,我们设置:

period_bytes_min = 1024,

period_bytes_max = 1024 *16,

那么:

a->min = 1024// period_bytes_min

k = 8// (void *) 8, rule -> private

b->max// S24_3LE mono时为24S24_3LE stereo 时为24*2 S24_LE stereo 时为32*2S16_LE mono 时为16, S16_LE stereo时为16*2。实际上就是一个framebit数。

c->min = a->min * k /b->max = 1024 * 8 /24 = 341.333

 

i->min = 1024;

v->min = c-> min = 341;

i->min > v->min, so i->min不变

i->min = 1024

也就是runtime->period_size = 1024

 

Buffer_size计算逻辑:

 

 

Buffer_size = c->min = a->min * b-> min = period_size * periods

底层获得的Periods = 4,是tinplay.c中赋值的,period_size是上面计算出来的值。

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值