I2S详解

工作中需要用到I2S通信协议,对协议中设计的BCLK, MCLK之间的关系不熟悉。 所以查找各种资料系统学习一下。

I2S是音频数据传输格式。

对模拟信号数字化需要经过采样和量化两个阶段:

1) 采样:

     就是间隔一定的时间对模拟信号做一个取样。比如间隔0.001秒(s)采一个样,这样采样频率(Fs)就是:

         Fs= 1/0.001=1Khz.

要多大采样率才可以还原一个模拟信号,这涉及到数字信号处理原理(奈奎斯特定理)。采样频率 Fs 大于信号中最高频率fmax的2倍时(Fs>2fmax),采样之后的数字信号完整地保留了原始信号中的信息。

人耳听到的音频范围是20Hz-20KHz, 如果对人耳听力范围内音频数字化,fmax=20Khz, Fs> 40KHz 的采样率44.1KHz就是高保真了。它能覆盖人耳听到的所有声音。

  I2S中  LRCLK= Fs

2)量化:

  就是对采到的信号进行数字编码。这里涉及到一个采样精度(n)的概念。举个例子: 我的ADC采样电压为0-5V,采样位数为16Bit.

采样精度就是(5V-0V)/(2^16)。

 每次取样转化为16bit数据,然后同步,取的要够快,不然下一次采样数据到来时就会导致本次数据丢失。所以对于 Fs=44.1KHz

采样精度为16bit的双声道的Mclk应该 >  16*2*441000bps=1411.2kbit/s

I2S详解_第1张图片

Frame:构成一个完整的声音单元,所谓的声音单元是指一个采样样本,Frame = 采样精度(n) * 声道数channel;

Period Size周期:每次硬件中断处理PCM音频数据的帧数,对于音频设备的数据读写,以此为单位;

Buffer Size数据缓冲区大小,这里指 runtime 的 buffer size,而不是结构图 snd_pcm_hardware 中定义的 buffer_bytes_max;一般来说 buffer_size = period_size * period_count, period_count 相当于处理完一个 buffer 数据所需的硬件中断次数。如果周期大小设定得较大,则单次处理的数据较多,这意味着单位时间内硬件中断的次数较少,CPU 也就有更多时间处理其他任务,功耗也更低,但这样也带来一个显著的弊端——数据处理的时延会增大。

下面一张图直观的表示 buffer/period/frame/sample 之间的关系:

I2S详解_第2张图片

这个 buffer 中有 4 个 period,每当 DMA 搬运完一个 period 的数据就会出生一次中断,因此搬运这个 buffer 中的数据将产生 4 次中断。ALSA 为什么这样做?因为数据缓存区可能很大,一次传输可能会导致不可接受的延迟;为了解决这个问题,alsa 把缓存区拆分成多个周期,以周期为单元传输数据。 period 和 buffer size 在 PCM 数据搬运中扮演着非常重要的角色。下面引用两段来自 alsa 官网对 Period 的详细解释:

The interval between interrupts from the hardware. This defines the input latency, since the CPU will not have any idea that there is data waiting until the audio interface interrupts it.
The audio interface has a “pointer” that marks the current position for read/write in its h/w buffer. The pointer circles around the buffer as long as the interface is running.
Typically, there are an integral number of periods per traversal of the h/w buffer, but not always. There is at least one card (ymfpci) that generates interrupts at a fixed rate indepedent of the buffer size (which can be changed), resulting in some “odd” effects compared to more traditional designs.
Note: h/w generally defines the interrupt in frames, though not always.
Alsa’s period size setting will affect how much work the CPU does. if you set the period size low, there will be more interrupts and the work that is done every interrupt will be done more often. So, if you don’t care about low latency, set the period size large as possible and you’ll have more CPU cycles for other things. The defaults that ALSA provides are in the middle of the range, typically.
(from an old AlsaDevel thread[1], quoting Paul Davis)
Retrieved from “http://alsa.opensrc.org/Period”

A frame is equivalent of one sample being played, irrespective of the number of channels or the number of bits. e.g.

  • 1 frame of a Stereo 48khz 16bit PCM stream is 4 bytes.
  • 1 frame of a 5.1 48khz 16bit PCM stream is 12 bytes.
    A period is the number of frames in between each hardware interrupt. The poll() will return once a 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.
    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).

dditional example
Here is an alternative example for the above discussion.
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) = 2244100 = 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.

  • 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.
 

We can control when this PCM interrupt is generated, by setting a period size, which is set in frames.

  • 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 2period_size = 24410 = 8820 frames (or 8820*4 = 35280 bytes).

On some hardwares, the irq is controlled on the basis of a timer. In this case, the period is defined as the timer frequency to invoke an irq.

再说说 period bytes,对于 dma 处理来说,它直接关心的是数据大小,而非 period_size(一个周期的帧数),有个转换关系:period_bytes = period_size * sample_bits * channels / 8

由于 I2S 总线采样率是稳定的,我们可以计算 I2S 传输一个周期的数据所需的时间:transfer_time = 1 * period_size / sample_rate, in second

例如 period_size = 1024,sample_rate = 48KHz ,那么一个周期数据的传输时间是: 1 * 1024 / 48000 = 21.3 (ms)。

 

---待补充,如软件相关。。。。

 

参考:

https://wenku.baidu.com/view/c131c90390c69ec3d5bb7597.html

https://blog.csdn.net/zyuanyun/article/details/59180272

https://wenku.baidu.com/view/eae9cb97c8d376eeafaa3143.html

你可能感兴趣的:(android,audio)