手机里有很多设备,比如外放,听筒,耳机,蓝牙,还可以分很多很细的设备,比如内置麦克风,耳机麦克风。在写程序的时候上层很少去管理这么多复杂的设备,Android都是通过底层AudioPolicyEngine进行自动切换控制的。比如插入耳机的时候,上层可能会收到广播,提醒耳机已经插入,但是程序并不需要将声音切换到耳机,在AudioPolicyEngine里面实现这样的功能切换。
要介绍这个比较大的框架,需要一定的C++和Android源码经验才可以理解。但是我尽量尝试自己也是站在一个初学者的角度去分析源码,也可以从之前工作中碰到的问题出发进行分析,因为只有解决实际的问题,分析代码才会有意义。这个也是对自己两年Android Audio工作的总结。
首先来看Android源码定义多少设备,因为google被墙的原因,自己去下载代码比较困难,公司的代码有很多修改,很多地方可能会误导大家。所以我推荐使用网页的形式,http://androidxref.com/,可以使用这个网站进行源码查看。后面的分析都是基于Android 8.0.0_r4 分支,Android 6.0之后底层的改动不大。
查看/system/media/audio/include/system/audio-base.h文件,
8.0之前的定义在/system/media/audio/include/system/audio.h中,通过enum枚举很多设备。
enum {
AUDIO_DEVICE_NONE = 0u, // 0x0
AUDIO_DEVICE_BIT_IN = 2147483648u, // 0x80000000
AUDIO_DEVICE_BIT_DEFAULT = 1073741824u, // 0x40000000
AUDIO_DEVICE_OUT_EARPIECE = 1u, // 0x1
AUDIO_DEVICE_OUT_SPEAKER = 2u, // 0x2
AUDIO_DEVICE_OUT_WIRED_HEADSET = 4u, // 0x4
AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 8u, // 0x8
AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 16u, // 0x10
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 32u, // 0x20
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 64u, // 0x40
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 128u, // 0x80
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 256u, // 0x100
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 512u, // 0x200
AUDIO_DEVICE_OUT_AUX_DIGITAL = 1024u, // 0x400
AUDIO_DEVICE_OUT_HDMI = 1024u, // OUT_AUX_DIGITAL
AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 2048u, // 0x800
AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 4096u, // 0x1000
AUDIO_DEVICE_OUT_USB_ACCESSORY = 8192u, // 0x2000
AUDIO_DEVICE_OUT_USB_DEVICE = 16384u, // 0x4000
AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 32768u, // 0x8000
AUDIO_DEVICE_OUT_TELEPHONY_TX = 65536u, // 0x10000
AUDIO_DEVICE_OUT_LINE = 131072u, // 0x20000
AUDIO_DEVICE_OUT_HDMI_ARC = 262144u, // 0x40000
AUDIO_DEVICE_OUT_SPDIF = 524288u, // 0x80000
AUDIO_DEVICE_OUT_FM = 1048576u, // 0x100000
AUDIO_DEVICE_OUT_AUX_LINE = 2097152u, // 0x200000
AUDIO_DEVICE_OUT_SPEAKER_SAFE = 4194304u, // 0x400000
AUDIO_DEVICE_OUT_IP = 8388608u, // 0x800000
AUDIO_DEVICE_OUT_BUS = 16777216u, // 0x1000000
AUDIO_DEVICE_OUT_PROXY = 33554432u, // 0x2000000
AUDIO_DEVICE_OUT_USB_HEADSET = 67108864u, // 0x4000000
AUDIO_DEVICE_OUT_FM_HEADSET = 268435456u, //0x10000000,
AUDIO_DEVICE_OUT_FM_SPEAKER = 536870912u, //0x20000000,
AUDIO_DEVICE_OUT_DEFAULT = 1073741824u, // BIT_DEFAULT
AUDIO_DEVICE_OUT_ALL = 2013265919u, // (((((((((((((((((((((((((((OUT_EARPIECE | OUT_SPEAKER) | OUT_WIRED_HEADSET) | OUT_WIRED_HEADPHONE) | OUT_BLUETOOTH_SCO) | OUT_BLUETOOTH_SCO_HEADSET) | OUT_BLUETOOTH_SCO_CARKIT) | OUT_BLUETOOTH_A2DP) | OUT_BLUETOOTH_A2DP_HEADPHONES) | OUT_BLUETOOTH_A2DP_SPEAKER) | OUT_HDMI) | OUT_ANLG_DOCK_HEADSET) | OUT_DGTL_DOCK_HEADSET) | OUT_USB_ACCESSORY) | OUT_USB_DEVICE) | OUT_REMOTE_SUBMIX) | OUT_TELEPHONY_TX) | OUT_LINE) | OUT_HDMI_ARC) | OUT_SPDIF) | OUT_FM) | OUT_AUX_LINE) | OUT_SPEAKER_SAFE) | OUT_IP) | OUT_BUS) | OUT_PROXY) | OUT_USB_HEADSET) | OUT_DEFAULT | OUT_FM_HEADSET | OUT_FM_SPEAKER)
AUDIO_DEVICE_OUT_ALL_A2DP = 896u, // ((OUT_BLUETOOTH_A2DP | OUT_BLUETOOTH_A2DP_HEADPHONES) | OUT_BLUETOOTH_A2DP_SPEAKER)
AUDIO_DEVICE_OUT_ALL_SCO = 112u, // ((OUT_BLUETOOTH_SCO | OUT_BLUETOOTH_SCO_HEADSET) | OUT_BLUETOOTH_SCO_CARKIT)
AUDIO_DEVICE_OUT_ALL_USB = 67133440u, // ((OUT_USB_ACCESSORY | OUT_USB_DEVICE) | OUT_USB_HEADSET)
AUDIO_DEVICE_OUT_ALL_FM = 805306368u, // (OUT_FM_HEADSET | OUT_FM_SPEAKER)
AUDIO_DEVICE_IN_COMMUNICATION = 2147483649u, // (BIT_IN | 0x1)
AUDIO_DEVICE_IN_AMBIENT = 2147483650u, // (BIT_IN | 0x2)
AUDIO_DEVICE_IN_BUILTIN_MIC = 2147483652u, // (BIT_IN | 0x4)
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = 2147483656u, // (BIT_IN | 0x8)
AUDIO_DEVICE_IN_WIRED_HEADSET = 2147483664u, // (BIT_IN | 0x