http://blog.csdn.net/ifloveelse/article/details/44097125
Android的Audio系统分为两大块,一块是audio的策略管理,即Audio Policy模块;一块是AudioFlinger模块,负责和Audio Hardware Module直接交互。
本文主要讲解Audio Policy模块的以下知识点:
1. audio policy策略文件的加载;
2. 创建AudioRecord的时候,如何根据intput source选择合适的device;
3. 创建AudioTrack的时候,如何根据output stream选择合适的device;
首先讲第一点。
audio policy策略文件即:/system/etc/audio_policy.conf 或者/vendor/etc/audio_policy.conf。在AudioPolicyManagerBase的构造函数中会加载和分析这个配置文件。
那么AudioPolicyManagerBase又是在何时构造的呢?
AudioPolicyService构造函数中会加载audio policy的HAL Module。AudioPolicyService与 audio policy module的组件图如下:
下面是一个audio_policy.conf文件的部分内容:
- audio_hw_modules {
- primary {
- outputs {
- primary {
- sampling_rates 44100
- channel_masks AUDIO_CHANNEL_OUT_STEREO
- formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_AUX_DIGITAL
- flags AUDIO_OUTPUT_FLAG_PRIMARY
- }
- hdmi {
- sampling_rates dynamic
- channel_masks dynamic
- formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_AUX_DIGITAL
- flags AUDIO_OUTPUT_FLAG_DIRECT
- }
- }
- inputs {
- primary {
- sampling_rates 8000|11025|16000|22050|24000|32000|44100|48000
- channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO
- formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_USB_DEVICE
- }
- }
- }
-
- }
- audio_hw_modules节点表示系统中包含的audio hardware module。每个子节点都对应一个 hal so。比如primary对应着audio.primary.<device>.so。primary可以理解为一个audio interface。
- 一个audio interface模块有输入模块和输入模块,在文件中的outputs和inputs中定义。primary 部分解析完毕后对应于抽象的class HwModule 。
- class HwModule {
- public:
- HwModule(const char *name);
- ~HwModule();
-
- void dump(int fd);
-
- const char *const mName;
- audio_module_handle_t mHandle;
- Vector <IOProfile *> mOutputProfiles;
- Vector <IOProfile *> mInputProfiles;
- };
可见每个HwModule都有好多个输入模块和输出模块,输入输出模块的属性用IOProfile抽象。接着讲第二点,创建AudioRecord的时候,如何根据intput source选择合适的device。在创建AudioRecord的时候会指定一个参数:audio_source_t
- typedef enum {
- AUDIO_SOURCE_DEFAULT = 0,
- AUDIO_SOURCE_MIC = 1,
- AUDIO_SOURCE_VOICE_UPLINK = 2,
- AUDIO_SOURCE_VOICE_DOWNLINK = 3,
- AUDIO_SOURCE_VOICE_CALL = 4,
- AUDIO_SOURCE_CAMCORDER = 5,
- AUDIO_SOURCE_VOICE_RECOGNITION = 6,
- AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
- AUDIO_SOURCE_REMOTE_SUBMIX = 8,
-
-
-
-
- AUDIO_SOURCE_USB_DEVICE_1 = 9,
- AUDIO_SOURCE_USB_DEVICE_2 = 10,
-
- AUDIO_SOURCE_CNT,
- AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1,
- } audio_source_t;
根据不同的audio_source_t枚举值,AudioPolicyManagerBase会选择不同的Device录入音频数据。具体选择的策略在audio_io_handle_t AudioPolicyManagerBase::getInput
函数中实现。对于一个系统来说,可能有多个设备都可以录入音频数据,那个如何选择正确的设备,这就是getInput函数的职责。
第三个问题,创建AudioTrack的时候,如何根据output stream选择合适的device。这个可以从下面的图标中得知一二:
通过AudioTrack的stream type,获得一个strategy,然后根据strategy获得一个device。然后根据device的属性,AudioPolicyManagerBase会为之匹配合适的audio_io_handle.对于一个audio hardware module来说,AudioFlinger加载完毕之后会为之分配一个handle:audio_module_handle_t。每一个audio_module_handle_t中创建的输入输出流都用audio_io_handle_t标识。每一个audio_io_handle_t背后是一个工作thread和与这个thread所绑定的stream。