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; // base name of the audio HW module (primary, a2dp ...)
-
audio_module_handle_t mHandle;
-
Vector <IOProfile *> mOutputProfiles; // output profiles exposed by this module
-
Vector <IOProfile *> mInputProfiles; // input profiles exposed by this module
-
};
可见每个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, /* Source for the mix to be presented remotely. */
-
/* An example of remote presentation is Wifi Display */
-
/* where a dongle attached to a TV can be used to */
-
/* play the mix captured by this audio source. */
-
-
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。