接着上一篇AudioPolicyService代码,目录:

E:\liuzhibao\android\android\frameworks\av\services\audioflinger

直接看代码:主要看构造函数内:

// ----------------------------------------------------------------------------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);    }}


其中:

// start tone playback thread    mTonePlaybackThread = new AudioCommandThread(String8(""));    // start audio commands thread    mAudioCommandThread = new AudioCommandThread(String8("ApmCommand"));
这里面的AudioCommandThread : 所有的命令(音量控制,输入、输出的切换等)最终都会在该线程中排队执行.

下面有一个对应HAL的结构体:

const struct hw_module_t *module;

对应一共是三个:

struct hw_module_t;
struct hw_module_methods_t;
struct hw_device_t;

对应开发的需要调整,比如,如果是一个led灯的控制,可以改如下:

struct led_module_t;
struct led_module_methods_t;
struct led_device_t;

这几个结构体的定义是在hardware.h中,有兴趣的,也必须要要看这几个结构体的作用,因为library层全部要用,不看懂完全都不知道这三个家伙是干什么的,也可以查看网上面关于HAL开发文章,还是比较简单的,主要是它有一套规则,定义方式基本上是死的.如果自己需要改的话,可以调整:

struct *_module_t;
struct *_module_methods_t;
struct *_device_t;

*改成你的设备名称,如上面的led等控制,这样library库层就可以直接使用调用了,这个library库层的开发和linux的设备使用开发基本上是一样的,打开设备,控制设备,读写设备.具体可以详读:Android深度探索这本书.

继续看代码

rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);

打开设备:

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);

其中:

struct audio_policy_device *mpAudioPolicyDev;


audio_policy这是一个类似虚拟设备,它在linux并没有驱动节点,但是它又是类似一个linux驱动节点:程序可以查看Audio_policy.cpp,你会发现生成的audio_policy.default.so文件:

想上个图片,可以用adb 到/system/lib/hw下面看到有audio_policy.default.so这个东东了

typedef struct audio_policy_module {    struct hw_module_t common;} audio_policy_module_t;struct audio_policy_device {    struct hw_device_t common;    int (*create_audio_policy)(const struct audio_policy_device *device,                               struct audio_policy_service_ops *aps_ops,                               void *service,                               struct audio_policy **ap);    int (*destroy_audio_policy)(const struct audio_policy_device *device,                                struct audio_policy *ap);};

看了上面的就知道了它也是个类似HAL访问驱动节点的,不过它是虚拟的.

那么上面那个create_audio_policy(...)就要查看HAL层的Audio_policy.c文件

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;}

上面的一看create_audio_policy实际上调用的是create_legacy_ap函数,感觉这个HAL不是去体验linux层的驱动节点,而是做了一下转手,那么该函数:

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->aps_ops = aps_ops;    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;    }    *ap = &lap->policy;


一看上面的AudioPolicyCompatClient,AudioPolicyManager创建,感觉绕了这么一大圈,从HAL层又有点绕上来了.

继续看AudioPolicyManager这个类,先看它的头文件AudioPolicyManager.h,原来它又是继承了AudioPolicyManagerBase这个类的:

class AudioPolicyManager: public AudioPolicyManagerBase

看一下它的构造函数,想所有的人都非常关注,上面既然是个虚拟设备,那总的调用实际设备吧,那么这里面就开始了:

mA2dpDeviceAddress = String8("");    mScoDeviceAddress = String8("");    mUsbCardAndDevice = String8("");    if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {        if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {            ALOGE("could not load audio policy configuration file, setting defaults");            defaultAudioPolicyConfig();        }    }


其中上面那个AudioPolicyConfig配置参数:Audio_policy_conf.h文件中

#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"

这就是很多网友提到的audio设备配置.就是在这里面进行加载.conf文件大致内容:

# Global configuration section: lists input and output devices always present on the device# as well as the output device selected by default.# Devices are designated by a string that corresponds to the enum in audio.hglobal_configuration {  attached_output_devices AUDIO_DEVICE_OUT_SPEAKER  default_output_device AUDIO_DEVICE_OUT_SPEAKER  attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC}# audio hardware module section: contains descriptors for all audio hw modules present on the# device. Each hw module node is named after the corresponding hw module library base name.# For instance, "primary" corresponds to audio.primary.<device>.so.# The "primary" module is mandatory and must include at least one output with# AUDIO_OUTPUT_FLAG_PRIMARY flag.# Each module descriptor contains one or more output profile descriptors and zero or more# input profile descriptors. Each profile lists all the parameters supported by a given output# or input stream category.# The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding# to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n".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_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_ALL_SCO        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      }      bt {        sampling_rates 8000         channel_masks AUDIO_CHANNEL_OUT_MONO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_ALL_SCO        flags AUDIO_OUTPUT_FLAG_DIRECT      }      usb {        sampling_rates 44100        channel_masks AUDIO_CHANNEL_OUT_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET        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_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_USB_DEVICE|AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET|AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET      }    }  }  a2dp {    outputs {      a2dp {        sampling_rates 44100        channel_masks AUDIO_CHANNEL_OUT_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_ALL_A2DP      }    }  }  r_submix {    outputs {      submix {        sampling_rates 44100|48000        channel_masks AUDIO_CHANNEL_OUT_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX      }    }    inputs {      submix {        sampling_rates 44100|48000        channel_masks AUDIO_CHANNEL_IN_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_IN_REMOTE_SUBMIX      }    }  } usb {    outputs {      usb_accessory {        sampling_rates 44100        channel_masks AUDIO_CHANNEL_OUT_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_USB_ACCESSORY      }      usb_device {        sampling_rates 44100        channel_masks AUDIO_CHANNEL_OUT_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_USB_DEVICE      }    }  }}

回到前面的代码AudioPolicyManagerBase,下面就是加载所有的设备,并且打开它们各自的流:

// open all output streams needed to access attached devices    for (size_t i = 0; i < mHwModules.size(); i++) {        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);


打开所有的设备,并且等待对应的数据流进行处理,那么还需要提供一个策略方式,不可能一个数据过来了,所有的output设备都去播放,那speaker,receiver,蓝牙(如果连上)都会同时播放出声音,那不是很混乱.

这里提供了一个策略:算是默认的.

updateDevicesAndOutputs();


... ...

走完上面一路下来,重要需要注意的是上面那个虚拟设备的地方,绕了一个大弯,因为一般情况下,我们遇到下面结构体以后,都会认为要去linux的驱动设备节点了:

struct hw_module_t;struct hw_module_methods_t;struct hw_device_t;
但是上面很显然没有.

Binder呢??

这个在Android Audio起着非常重要的作用,但是没有太多好说的,因为Audio就是用binder的机制:主要的感觉是在数据memory的分配,释放,以及对象的"复制",这个复制不知道准不准确啊.下次看看.














更多相关文章

  1. C语言函数以及函数的使用
  2. Android AudioManager修改设备默认音量
  3. 获取Android设备电池电量状态
  4. webview开发-适配多分辨率的Android设备
  5. android内核字符驱动设备实战之----------设备驱动程序篇
  6. Google 发布 Android @ Home,让你用 Android 设备控制家电
  7. Android之蓝牙设备使用
  8. adb通过wifi连接android设备的方法
  9. 通过JavaScript或PHP检测Android设备

随机推荐

  1. Android(安卓)Activity生命周期
  2. Activity的四种启动方式
  3. android:textAppearance设置文字外观
  4. A Faster Emulator with Better Hardware
  5. 「抄底 Android 内存优化 3」 —— JVM
  6. Android(安卓)LogCat使用详解
  7. Android待机流程分析
  8. Android-使用AutoCompleteTextView进行动
  9. Android Studio自带模拟器读写SDcard不成
  10. android 获取sim卡运营商信息