alsa应用程序缓存区的大小可以通过ALSA库函数调用来控制。缓存区可以很大,一次传输操作可能会导致不可接受的延迟,我们把它称为延时(latency)。
为了解决这个问题,ALSA将缓存区拆分成一系列周期(period)(OSS/Free中叫片断fragments)。
ALSA以period为单元来传送数据。一个周期(period)存储一些帧(frames)。每一帧包含时间上一个点所抓取的样本。
对于立体声设备,一个帧会包含两个信道上的样本。
以下是关于声卡的一些基本概念:
采样(sample):
PCM audio不论是输入还是输出,都包含采样,采样值代表声音的一个声道在某个特定时间点的振幅。
很多这样的采样组成了声音。样本是记录音频数据的最基本单位。
样本尺寸(bits_per_sample)
采样的尺寸从8bit 到64bit精度。采样的格式也各式各样: 大端整形,小端整形或者浮点数。
采样尺寸决定动态声响范围。动态声响范围是指最静和最大声之差
通道数(channel):
分为单声道mono;立体声stereo。当然还存在更多的通道数
帧(frame):
帧记录了一个声音单元,其长度为样本长度和通道数的乘积。frame size = sizeof(one sample) * nChannels
采样率(rate):
PCM声音是包含多个frame的流。每秒钟采样次数,也就是每秒钟获取到的帧个数。对于CD audio,每秒有44100个采样。
period_size:
音频设备一次处理所需要的帧数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。
period_time:硬件中断的间隔时间。它表示输入延时。
声卡接口中有一个指针来指示声卡硬件缓存区中当前的读写位置。只要接口在运行,这个指针将循环地指向缓存区中的某个位置。
alsa中配置的缓存(buffer)和周期(period)大小在runtime中是以帧(frames)形式存储的。
period_bytes = frames_to_bytes(runtime, runtime->period_size);
交错模式(interleaved):
是一种音频数据的记录方式,在交错模式下,数据以连续真的方式存放,即首先记录帧1的左声道样被和右声道样本,再开始帧2的记录。
非交错模式(non-interleaved):
首先记录的是一个周期内所有帧的左声道样本,再记录所有右声道样本。
/** Unsigned frames quantity */
typedef unsigned long snd_pcm_uframes_t;
int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir);
int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
frame_size = channel * bits_per_sample / 8
period_size = n
buffer_size = m * period_size
bytes_of_period_size = n*frame_size
bytes_of_buffer_size = m*n*frame_size
period_time = n / rate ,比如n=256,rate=8KHz,那么period_time=32ms
buffer_time = m * period_time