android这个Audio部分还是非常大的一个模块,下面从设备的角度简读一下Audio设备是如何工作的.
假设:
<1> : 熟悉了AudioFlinger和AudioPolicyService的基本程序流程.
<2> : 知道HAL中hardware.h那三个结构体是干什么的:
typedef struct hw_module_t
typedef struct hw_module_methods_t
typedef struct hw_device_t
如果不知道这三个结构体的规范,就会出现AudioFlinger和AudioPolicyService两个核心和HAL的关联很难连上,代码流程交互衔接不上.
OK!
前面说了AudioFlinger和AudioPolicyService会随着系统启动而跟随启动,而这两个核心是差不多同时启动的,由于AudioPolicyService才是真正的设备管理者和调度者,所以从AudioPolicyService.cpp开始:
// ----------------------------------------------------------------------------
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
{
char value[PROPERTY_VALUE_MAX];
const struct hw_module_t *module;
int forced_val;
int rc;
Mutex::Autolock _l(mLock);
// start tone playback thread
mTonePlaybackThread = new AudioCommandThread(String8(""));
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmCommand"));
/* instantiate the audio policy manager */
rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
if (rc)
return;
rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
if (rc)
return;
rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
&mpAudioPolicy);
ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
if (rc)
return;
rc = mpAudioPolicy->init_check(mpAudioPolicy);
ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
if (rc)
return;
ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
// load audio pre processing modules
if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
} else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
}
}
熟悉HAL三个结构,看了上面的程序,第一反应挑出两处:
/* instantiate the audio policy manager */
rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
if (rc)
return;
rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
根据AUDIO_POLICY_HARDWARE_MODULE_ID获取设备module,然后将标为AUDIO_POLICY_HARDWARE_MODULE_ID这个设备打开.打开了设备节点后,反馈的mpAudioPolicyDev对象就可以用于操作各种设备输入输出等动作了.
那么这个设备是什么设备了,还好,根据linux的规范,任何一个节点都有独一无二的AUDIO_POLICY_HARDWARE_MODULE_ID号.搜索这个关键字(source insight中),
Audio_policy_hal.cpp (e:\liuzhibao\android\android\hardware\libhardware_legacy\audio)
就知道打开设备和操作设备都是在这里完成的了.那就理顺了,后面打开函数:
static inline int audio_policy_dev_open(const hw_module_t* module,
struct audio_policy_device** device)
{
return module->methods->open(module, AUDIO_POLICY_INTERFACE,
(hw_device_t**)device);
}
这个open其实就是调用了Audio_policy_hal.cpp中的:
static int legacy_ap_dev_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
struct legacy_ap_device *dev;
if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
return -EINVAL;
dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));
if (!dev)
return -ENOMEM;
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = 0;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = legacy_ap_dev_close;
dev->device.create_audio_policy = create_legacy_ap;
dev->device.destroy_audio_policy = destroy_legacy_ap;
*device = &dev->device.common;
return 0;
}
但是是谁要去打开了呢?AudioPolicyService.cpp构造函数中:
rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
&mpAudioPolicy);
ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
然后就调用了上面的hal层的:
static int create_legacy_ap(const struct audio_policy_device *device,
struct audio_policy_service_ops *aps_ops,
void *service,
struct audio_policy **ap)
{
这个函数中有几个地方:
lap->service_client =
new AudioPolicyCompatClient(aps_ops, service);
if (!lap->service_client) {
ret = -ENOMEM;
goto err_new_compat_client;
}
lap->apm = createAudioPolicyManager(lap->service_client);
if (!lap->apm) {
ret = -ENOMEM;
goto err_create_apm;
}
new了一个AudioPolicyCompatClient对象,暂时注意这个地方.
lap->apm = createAudioPolicyManager(lap->service_client);
这个返回一个AudioPolicyManager对象,继续查看,最终到AudioPolicyManagerBase中,前面大致介绍过这个类,其中参数就是上面提到的一个new对象
AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
结果我们发现这里开始打开设备:
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
if (mHwModules[i]->mHandle == 0) {
ALOGW("could not open HW module %s", mHwModules[i]->mName);
continue;
}
// open all output streams needed to access attached devices
for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
{
const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];
if (outProfile->mSupportedDevices & mAttachedOutputDevices && !(outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice &
outProfile->mSupportedDevices);
audio_io_handle_t output = mpClientInterface->openOutput(
outProfile->mModule->mHandle,
&outputDesc->mDevice,
&outputDesc->mSamplingRate,
&outputDesc->mFormat,
&outputDesc->mChannelMask,
&outputDesc->mLatency,
outputDesc->mFlags);
开始是loadHwModule(...),然后下面是openOutput(...),这个时候我们在回头来看看AudioPolicyCompatClient这个类:
audio_module_handle_t AudioPolicyCompatClient::loadHwModule(const char *moduleName)
{
return mServiceOps->load_hw_module(mService, moduleName);
}
audio_io_handle_t AudioPolicyCompatClient::openOutput(audio_module_handle_t module,
audio_devices_t *pDevices,
uint32_t *pSamplingRate,
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
audio_output_flags_t flags)
{
return mServiceOps->open_output_on_module(mService, module, pDevices, pSamplingRate,
pFormat, pChannelMask, pLatencyMs,
flags);
}
看了一下,发现还不是自己去load和open,还是让"别人"去搞定,这个mServiceOps又是谁了,这个是AudioPolicyService一级一级传递下来的aps_ops:
struct audio_policy_service_ops aps_ops = {
open_output : aps_open_output,
open_duplicate_output : aps_open_dup_output,
close_output : aps_close_output,
suspend_output : aps_suspend_output,
restore_output : aps_restore_output,
open_input : aps_open_input,
close_input : aps_close_input,
set_stream_volume : aps_set_stream_volume,
set_stream_output : aps_set_stream_output,
set_parameters : aps_set_parameters,
get_parameters : aps_get_parameters,
start_tone : aps_start_tone,
stop_tone : aps_stop_tone,
set_voice_volume : aps_set_voice_volume,
move_effects : aps_move_effects,
load_hw_module : aps_load_hw_module,
open_output_on_module : aps_open_output_on_module,
open_input_on_module : aps_open_input_on_module,
};
这下爽了吧,一张函数映射表.open_output_on_module对应了aps_open_output_on_module函数,查看一下:
static audio_io_handle_t aps_open_output_on_module(void *service,
audio_module_handle_t module,
audio_devices_t *pDevices,
uint32_t *pSamplingRate,
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
audio_output_flags_t flags)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
return 0;
}
return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
pLatencyMs, flags);
}
这下好了,它是通过获取AudioFlinger核心模块来打开的,也就是绕了一个大弯,从AudioPolicyService那边到HAL,再到进程AudioFlinger中了,让AudioFlinger这个老实人来做事的.
audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_devices_t *pDevices,
uint32_t *pSamplingRate,
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
audio_output_flags_t flags)
{
... ...
对照前面aps_ops那个结构体的映射表关系,就可以想象,AudioPolicyService让AudioFlinger做了多少事(当然可能还不全).
整个流程基本上就清楚很多了,
下面附一张调试日志logcat的信息证明以上说的:注意Tag标签信息顺序