Android音频系统之AudioFlinger(二)

本文详细介绍了Android音频系统中的AudioFlinger如何管理音频设备,包括AudioPolicyService的角色、AudioFlinger的加载音频接口过程以及如何打开音频输出通道。AudioFlinger在接收到AudioPolicyService的策略后,负责执行与音频设备的交互,包括设备的加载、初始化和输出通道的创建。此外,文章还探讨了AudioFlinger如何根据设备和策略选择合适的音频接口,并创建和初始化输出通道。
摘要由CSDN通过智能技术生成

1.1.1 音频设备的管理

虽然AudioFlinger实体已经成功创建并初始化,但到目前为止它还是一块静态的内存空间,没有涉及到具体的工作。

从职能分布上来讲,AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多个音频流的混音如何处理等等都得由它来完成。

目前Audio系统中支持的音频设备接口(Audio Interface)分为三大类,即:

/*frameworks/av/services/audioflinger/AudioFlinger.cpp*/

static const char * const audio_interfaces[] = {

   AUDIO_HARDWARE_MODULE_ID_PRIMARY, //主音频设备,必须存在

   AUDIO_HARDWARE_MODULE_ID_A2DP, //蓝牙A2DP音频

   AUDIO_HARDWARE_MODULE_ID_USB, //USB音频,早期的版本不支持

};

每种音频设备接口由一个对应的so库提供支持。那么AudioFlinger怎么会知道当前设备中支持上述的哪些接口,每种接口又支持哪些具体的音频设备呢?这是AudioPolicyService的责任之一,即根据用户配置来指导AudioFlinger加载设备接口。

当AudioPolicyManagerBase(AudioPolicyService中持有的Policy管理者,后面小节有详细介绍)构造时,它会读取厂商关于音频设备的描述文件(audio_policy.conf),然后据此来打开以上三类音频接口(如果存在的话)。这一过程最终会调用loadHwModule@AudioFlinger,如下所示:

/*frameworks/av/services/audioflinger*/

audio_module_handle_t AudioFlinger::loadHwModule(const char *name)/*name就是前面audio_interfaces 数组

                                                            成员中的字符串*/

{

    if (!settingsAllowed()) {

        return 0;

    }

    Mutex::Autolock _l(mLock);

    returnloadHwModule_l(name);

}

这个函数没有做实质性的工作,只是执行了加锁动作,然后接着调用下面的函数:

audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)

{

                /*Step 1. 是否已经添加了这个interface?*/

    for (size_t i = 0; i <mAudioHwDevs.size(); i++) {

        if(strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {

           ALOGW("loadHwModule() module %s already loaded", name);

            returnmAudioHwDevs.keyAt(i);

        }

    }

               

                /*Step 2. 加载audio interface*/

    audio_hw_device_t *dev;

    int rc =load_audio_interface(name, &dev);   

/*Step 3. 初始化*/

mHardwareStatus = AUDIO_HW_INIT;

rc = dev->init_check(dev);

mHardwareStatus = AUDIO_HW_IDLE;

if ((mMasterVolumeSupportLvl !=MVS_NONE) && (NULL != dev->set_master_volume)) {

    AutoMutex lock(mHardwareLock);

    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;

    dev->set_master_volume(dev, mMasterVolume);

    mHardwareStatus = AUDIO_HW_IDLE;

}

/*Step 4. 添加到全局变量中*/

    audio_module_handle_t  handle = nextUniqueId();

    mAudioHwDevs.add(handle,new AudioHwDevice(name, dev));

 

    return handle;

}

Step1@ loadHwModule_l. 首先查找mAudioHwDevs是否已经添加了变量name所指示的audio interface,如果是的话直接返回。第一次进入时mAudioHwDevs的size为0,所以还会继续往下执行。

Step2@ loadHwModule_l. 加载指定的audiointerface,比如“primary”、“a2dp”或者“usb”。函数load_audio_interface用来加载设备所需的库文件,然后打开设备并创建一个audio_hw_device_t实例。音频接口设备所对应的库文件名称是有一定格式的,比如a2dp的模块名可能是audio.a2dp.so或者audio.a2dp.default.so等等。查找路径主要有两个,即:

/** Base path of the hal modules */

#define HAL_LIBRARY_PATH1 "/system/lib/hw"

#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

当然,因为Android是完全开源的,各开发商可以根据自己的需要来进行相应的修改,比如下面是某手机设备的音频库截图:

             

  • 13
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值