2 tinyalsa
tinyalsa是Google在Android 4.0之后推的基于alsa内核的用户层音频接口。在Android 4.0之前还一直是使用这alsa-lib接口。Google之所以推出tinyalsa,可能是因为alsa使用了GPL许可证的缘故,也有可能是因为alsa-lib的库过于复杂繁琐而大部分功能在Android平台没有实际实用意义却依然占用屈指可数的内存空间。Google在Android4.0之后推出了tinyalsa 。
tinyalsa的源代码位于 external/tinyalsa/目录下。
tinyalsa的源代码包括两部分,tinyalsa库文件和小工具。
tinyalsa库文件的源代码有两个,是mixer.c pcm.c。其中mixer.c提供了控制接口。pcm.c提供了PCM播放、录音的接口。
tinyalsa工具包括了四个文件,tinyplay.c、tinycap.c、tinymix.c、tinypcminfo.c。每个文件对应一个可执行文件。tinyplay 是一个简单的播放器,可以播放WAV文件。tinycap是一个简单的录音程序,可以进行录音并保存到一个wav文件中。tinymix用于配置control,例如切换音频通道等等。tinypcminfo获取PCM的参数的示例,例如采样率的范围、通道数的范围等等。
2.1 PCM播放录音说明。
重要的数据结构
struct pcm_config {
unsigned int channels;
unsigned int rate;
unsigned int period_size;
unsigned int period_count;
enum pcm_format format;
/* Values to use for the ALSA start, stop and silence thresholds. Setting
* any one of these values to 0 will cause the default tinyalsa values to be
* used instead. Tinyalsa defaults are as follows.
*
* start_threshold : period_count * period_size
* stop_threshold : period_count * period_size
* silence_threshold : 0
*/
unsigned int start_threshold;
unsigned int stop_threshold;
unsigned int silence_threshold;
/* Minimum number of frames available before pcm_mmap_write() will actually
* write into the kernel buffer. Only used if the stream is opened in mmap mode
* (pcm_open() called with PCM_MMAP flag set). Use 0 for default.
*/
int avail_min;
};
.channels :通道数
.rate : 采样率
.period_size : 每次传输的数据长度。值越小,时延越小,cpu占用就越高。
.period_count: 缓冲区period的个数。缓冲区越多,发生XRUN的机会就越少。
.format : 定义数据格式,如数据宽度
.start_threshold : 缓冲区的数据超过该值时,硬件开始启动数据传输。
.stop_threshold : 缓冲区空闲区大于该值时,硬件停止传输。默认情况下,这个数 为整个缓冲区的大小,即整个缓冲区空了,就停止传输。
.avail_min : 缓冲区空闲区大于该值时,pcm_mmap_write()往缓冲写数据。
播放和录音的调用可以参考tinyplay.c、tinycap.c里面的示例。
2.1 mix使用说明。
2.1.1 打开mixer设备
struct mixer *mixer = mixer_open(card);
card是一个整型的变量。是声卡的控制器的编号。mixer_open会打开controlCX,card就是对应X的数值。
我们在/dev/snd/目录下用ls命令就可以看到相关的声卡设备。
2.1.2 mixer的读写
首先获得mixer_ctl的指针。
mixer_ctl ctl =mixer_get_ctl_by_name(mixer, name);
参数name就是control的名称,就是要和我们前面介绍的snd_kcontrol_new结构中name相匹配。
也可以通过id来得到mixer_ctl的指针。
mixer_ctl ctl =mixer_get_ctl(mixer, id);
这个id和驱动中添加control的顺序是一样的,例如第一个control的id是0,第二个是1...
设置control的值。
mixer_ctl_set_value(ctl, index, value);
前面讲过control的名称相同,则通过index来区分,这个index就是和snd_kcontrol_new结构中index相匹配的。如果没有同名的control,那么index就直接设为0。value为要设置的值。
读control的值
mixer_ctl_get_value(ctl, index);
详细的代码可以参考tinymix.c。
tinyalsa是Google在Android 4.0之后推的基于alsa内核的用户层音频接口。在Android 4.0之前还一直是使用这alsa-lib接口。Google之所以推出tinyalsa,可能是因为alsa使用了GPL许可证的缘故,也有可能是因为alsa-lib的库过于复杂繁琐而大部分功能在Android平台没有实际实用意义却依然占用屈指可数的内存空间。Google在Android4.0之后推出了tinyalsa 。
tinyalsa的源代码位于 external/tinyalsa/目录下。
tinyalsa的源代码包括两部分,tinyalsa库文件和小工具。
tinyalsa库文件的源代码有两个,是mixer.c pcm.c。其中mixer.c提供了控制接口。pcm.c提供了PCM播放、录音的接口。
tinyalsa工具包括了四个文件,tinyplay.c、tinycap.c、tinymix.c、tinypcminfo.c。每个文件对应一个可执行文件。tinyplay 是一个简单的播放器,可以播放WAV文件。tinycap是一个简单的录音程序,可以进行录音并保存到一个wav文件中。tinymix用于配置control,例如切换音频通道等等。tinypcminfo获取PCM的参数的示例,例如采样率的范围、通道数的范围等等。
2.1 PCM播放录音说明。
重要的数据结构
struct pcm_config {
unsigned int channels;
unsigned int rate;
unsigned int period_size;
unsigned int period_count;
enum pcm_format format;
/* Values to use for the ALSA start, stop and silence thresholds. Setting
* any one of these values to 0 will cause the default tinyalsa values to be
* used instead. Tinyalsa defaults are as follows.
*
* start_threshold : period_count * period_size
* stop_threshold : period_count * period_size
* silence_threshold : 0
*/
unsigned int start_threshold;
unsigned int stop_threshold;
unsigned int silence_threshold;
/* Minimum number of frames available before pcm_mmap_write() will actually
* write into the kernel buffer. Only used if the stream is opened in mmap mode
* (pcm_open() called with PCM_MMAP flag set). Use 0 for default.
*/
int avail_min;
};
.channels :通道数
.rate : 采样率
.period_size : 每次传输的数据长度。值越小,时延越小,cpu占用就越高。
.period_count: 缓冲区period的个数。缓冲区越多,发生XRUN的机会就越少。
.format : 定义数据格式,如数据宽度
.start_threshold : 缓冲区的数据超过该值时,硬件开始启动数据传输。
.stop_threshold : 缓冲区空闲区大于该值时,硬件停止传输。默认情况下,这个数 为整个缓冲区的大小,即整个缓冲区空了,就停止传输。
.avail_min : 缓冲区空闲区大于该值时,pcm_mmap_write()往缓冲写数据。
播放和录音的调用可以参考tinyplay.c、tinycap.c里面的示例。
2.1 mix使用说明。
2.1.1 打开mixer设备
struct mixer *mixer = mixer_open(card);
card是一个整型的变量。是声卡的控制器的编号。mixer_open会打开controlCX,card就是对应X的数值。
我们在/dev/snd/目录下用ls命令就可以看到相关的声卡设备。
2.1.2 mixer的读写
首先获得mixer_ctl的指针。
mixer_ctl ctl =mixer_get_ctl_by_name(mixer, name);
参数name就是control的名称,就是要和我们前面介绍的snd_kcontrol_new结构中name相匹配。
也可以通过id来得到mixer_ctl的指针。
mixer_ctl ctl =mixer_get_ctl(mixer, id);
这个id和驱动中添加control的顺序是一样的,例如第一个control的id是0,第二个是1...
设置control的值。
mixer_ctl_set_value(ctl, index, value);
前面讲过control的名称相同,则通过index来区分,这个index就是和snd_kcontrol_new结构中index相匹配的。如果没有同名的control,那么index就直接设为0。value为要设置的值。
读control的值
mixer_ctl_get_value(ctl, index);
详细的代码可以参考tinymix.c。