tinyalsa 终极详解
1、tinyalsa位于Android源码的external/tinyalsa位置。关于tinyalsa,tinyalsa是Google在Android 4.0之后推的基于alsa内核的用户层音频接口。tinyalsa中主要的头文件和数据结构如下,通过ioctrl和内核的alsa驱动交互。...
1.tinyalsa 背景
1、tinyalsa位于 Android源码的 external/ tinyalsa 位置。
关于 tinyalsa,tinyalsa是Google在Android 4.0之后推的 基于 alsa内核的用户层音频接口。
tinyalsa中主要的 头文件 和 数据结构 如下,通过 ioctrl 和内核的 alsa驱动 交互。
alsa-lib 的库 过于复杂 繁琐大部分功能 在Android平台 没有实际实用意义 却依然占 用屈指可数的内存空间。
driver 文件:
在Android中 一个pcm设备最多可有一个mixer设备 "/dev/snd/controlC%u"(一般是controlC0)和32个/dev/snd/pcmC%uD%uc(一般是pcmC0D0c)、/dev/snd/pcmC%uD%u%p(一般是pcmC0D0p),pcm设备中的C代表card,D代表device,c代表capture,p代表playback。当我们新增一个pcm声卡C的值会+1,D还是从0开始,可能只有c(pcmC1D0c 例如麦克风),可能只有p(pcmC1D0p 例如音响),可能同时存在c和p(pcmC1D0c pcmC1D0p )。
tinyalsa 的对外提供的头文件就我上图提到的一个"asoundlib.h",提供最基础的 pcm 和 mixer 操作。实现文件为pcm.c(实现 声卡原始数据 操作 api)和 mixer.c(音频设备相关的操作 api)。
根据 asoundlib.h 编写了四个小工具 tinypcminfo tinyplay tinycap tinymix,这四个小工具作为系统命令存放在系统中,可以很方便的使用。tinyasla作为精简版的alsa-lib可能会有人想把它移植到Linux使用,tinyasla依赖的库有libcutils && libutils,如果能把依赖的这两个库的一些方法使用Linux接口实现那么剩下的问题应该不大了吧。
2.音频小工具总结
tinypcminfo的 实现文件 tinypcminfo.c (查看 pcm设备 能力)
tinyplay的实现文件 tinyplay.c( 使用pcm设备播放 wav格式 的音频文件)
tinycap的实现文件 tinycap.c( 使用pcm设备采集pcm格式的码流,并保存为wav格式的文件)
tinymix的实现文件 tinymix.c( 对pcm设备的控制,包括音量调节、设备切换)
查看当前声卡
cat /proc/asound/cards
2、 tinymix
tinymix -h -crontrol s
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);
3、 tinyplay
tinyplay 是一个 简易的音乐播放器, 一般用于播放测试。 tinyplay 只能播放wav原始格式的音乐,不能进行Mp3等格式的解码,支持44.1kHz,48kHz采样率的wav音乐。在调用tinyplay播放音乐之前需要先使用 tinymix 切换好音频通路,设置音量:
4, tinycap
tinycap是一个简易的录音软件,一般用于录音测试。
在调用tinycap录音之前需要先使用 tinymix调整好音频通路:
[objc] view plain copy
- tinymix 14 30 //mic1 volume
- tinymix 19 1 //mic1 boost on
- tinymix 26 1 //adc1 -> mic1
- tinymix 50 ADC1 //i2sR out -> adc1
- tinymix 51 ADC1 //i2sL out -> adc2
- echo "0xfb 0x01" > /sys/devices/platform/comip_codec/lc1160_reg //bias poweron
- echo "0xad 0x08" > /sys/devices/platform/comip_codec/lc1160_reg //adc1 enable
- echo "0xac 0x01" > /sys/devices/platform/comip_codec/lc1160_reg //mic1 pga enable
- echo "0x3b 0xcc" > /sys/devices/platform/comip_codec/lc1160_reg //ldo
- echo 2 > /sys/bus/i2c/drivers/fm2018/0-0060/mode //bypass 外部的回声消除音频芯片(M730x项目特有)
- tinycap /sdcard/Music/l.wav
3、tinyalsa
+-- Android.mk +-- include | +-- tinyalsa | +-- asoundlib.h +--
mixer.c ## 类alsa-lib的control,作用音频部件开关、音量调节等 +--
pcm.c ##类alsa-lib的pcm,作用音频pcm数据回放录制 +-- README +--
tinycap.c ##类alsa_arecord
+-- tinymix.c ##类alsa_amixer
+-- tinyplay.c ##类alsa_aplay
录音结束通过ctrl+C强行退出即可,之后在/sdcard/Music/路径下查看到l.wav音频文件 有源码包
4.音频框架总结
(1). ALSA 是 kernel 里面管理 audio 的核心,我们的 audio driver
部分一般会调用 snd_soc_register_card(), 将我们在 软件层面抽象出来的声卡注册进audio核心
(2). 在用户空间android同样给我们提供了tinyalsa方便 我们操作我们的driver
(3).audio的 hal层,这部分也是和具体的厂商有关,
(4).mediaservice,图中的media是在init.rc里面启动的native进程
在我们所用的android版本中这个service其实还启动了camera
service,这里只讲解与audio相关的AudioFlinger和
AudioPolicyService
(5).在 mediaservice 启动之后会zygote进程,zygote紧接着会启动
android的核心进程systemserver进程。在systemserver进程
里面会注册AudioService,其实这里AudioService虽然叫做
service,其实他是通过调用AudioSystem间接地获得
AudioFlinger的代理到具体的audio,之所以service是由于
我们一般在应用程序中又是通过获得AudioService的代理
操作的,可见虽然android的binder进程间通讯功能强大
但是效率可能并没有其他的进程间通讯机制高效。
比如我们一般在应用程序中通过 AudioManager 操作得到当前
的音量会首先通过binder机制先获得 AudioService 代理,然后
AudioService在通过AudioSystem获得AudioFlinger的代理才
能操作到实际的实现部分会发现这里一次调用却用了两次
binder通信,显然没有普通的进程间通信机制高效,优点确实功能很强大。
(6).应用程序中有 AudioTrack,AudioRecoder, AudioManager,
MediaPlayer 等接口实际操作我们的audio的。
目前技术经理 提供成长学习星球 加V 13106543984 (299 48小时内可退)
提供程序员成长学习地图 提供成长学习通道 减少自我摸索的过程
专职提供服务
Android Linux C C++ 初级程序员入行
Android Linux C C++ 中级程序员进阶
Android Linux C C++ 高级程序员成型
技术转管理进阶 带团队解决问题
简历打造 跳槽时机 工作指导 职场发展 解惑答疑 项目探讨等
对于刚要入行初级程序员 初级程序升中级 有极大收益
中级升高级 高级升管理 有较大收益...
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)