[RK3288][Android6.0] Audio的frame/period_size/bps_rate

来源:互联网 发布:js数组取最后一个 编辑:程序博客网 时间:2024/06/05 10:06

Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92


Alsa Project上有篇文章,

http://www.alsa-project.org/main/index.php/FramesPeriods

觉得不错,简单地翻译了下:

FramesPeriods

A frame is equivalent of one sample being played, irrespective of the number of channels or the number of bits. e.g.
一个frame相当于一个采样点,通过channel或者bits计算,例如:
1 frame of a Stereo 48khz 16bit PCM stream is 4 bytes.
48k立体声16bit就是4字节。
1 frame of a 5.1 48khz 16bit PCM stream is 12 bytes.
5.1声道16bit就是12字节。
A period is the number of frames in between each hardware interrupt. The poll() will return once a period.
而一个period就是每次硬件中断的number,poll()是一个period返回一次。
The buffer is a ring buffer. The buffer size always has to be greater than one period size. Commonly this is 2*period size, but some hardware can do 8 periods per buffer. It is also possible for the buffer size to not be an integer multiple of the period size.
用来存数据的是一个环形buffer, buffer size一定要被period size大,一般来说是两倍的period size, 有的硬件可以是8个period size,buffer可以不是period size的整数倍。
Now, if the hardware has been set to 48000Hz , 2 periods, of 1024 frames each, making a buffer size of 2048 frames. The hardware will interrupt 2 times per buffer. ALSA will endeavor to keep the buffer as full as possible. Once the first period of samples has been played, the third period of samples is transfered into the space the first one occupied while the second period of samples is being played. (normal ring buffer behaviour).
如果硬件采样率是48k, 有两个period,一个是1024帧, 那么buffer size就是2048帧,硬件会触发两次中断,第一帧被播放之后,第三帧会存放在第一帧的buffer位置,这也是ring buffer的特性。

所以帧率概念其实就是:
一帧 = channel * bits / 2,而period size就是一次中断的帧数

Additional example
一个如何计算bps的例子:
Say we want to work with a stereo, 16-bit, 44.1 KHz stream, one-way (meaning, either in playback or in capture direction). Then we have:
'stereo' = number of channels: 2
1 analog sample is represented with 16 bits = 2 bytes
1 frame represents 1 analog sample from all channels; here we have 2 channels, and so:
1 frame = (num_channels) * (1 sample in bytes) = (2 channels) * (2 bytes (16 bits) per sample) = 4 bytes (32 bits)
To sustain 2x 44.1 KHz analog rate - the system must be capable of data transfer rate, in Bytes/sec:
Bps_rate = (num_channels) * (1 sample in bytes) * (analog_rate)= (1 frame) * (analog_rate) = ( 2 channels ) * (2 bytes/sample) * (44100 samples/sec) = 2*2*44100 = 176400 Bytes/sec 
如果要正常播放,那么数据的速率必须要满足公式:
bps rate = 2 × 2 × 44100 = 176400 Bytes/sec 




Now, if ALSA would interrupt each second, asking for bytes - we'd need to have 176400 bytes ready for it (at end of each second), in order to sustain analog 16-bit stereo @ 44.1Khz.
也就是说,alsa每一秒中断需要176400bytes的数据量才能正常播放。
If it would interrupt each half a second, correspondingly for the same stream we'd need 176400/2 = 88200 bytes ready, at each interrupt;
如果一秒有两次中断,那么每次中断需要一半的数据量。
if the interrupt hits each 100 ms, we'd need to have 176400*(0.1/1) = 17640 bytes ready, at each interrupt.
如果是100ms,那么就是1/10的数据量。

We can control when this PCM interrupt is generated, by setting a period size, which is set in frames.
那么我们可以通过period size来控制每次interrupt的帧数。
Thus, if we set 16-bit stereo @ 44.1Khz, and the period_size to 4410 frames => (for 16-bit stereo @ 44.1Khz, 1 frame equals 4 bytes - so 4410 frames equal 4410*4 = 17640 bytes) => an interrupt will be generated each 17640 bytes - that is, each 100 ms.
Correspondingly, buffer_size should be at least 2*period_size = 2*4410 = 8820 frames (or 8820*4 = 35280 bytes).
这样, 如果period_size设成4410 frames,也就是17640bytes,那么传输完就需要100ms。

这篇文章的重点概念主要就是介绍 帧,period size以及bps_rate。不过实际使用中period size的概念有点不一样,rk3288平台使用dma来控制数据的传输,中断的触发是根据period size来产生的,比如period size设置成1024bytes,那么dma搬运完1024bytes后,中断就会被触发,而不是像上面的例子固定时间触发的!


阅读全文
1 0