USB audio调试

来源:互联网 发布:python io模块 编辑:程序博客网 时间:2024/05/19 13:14

androidstudio打印的信息有如下:

07-12 08:27:17.660 2284-2284/? I/AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 707-12 08:27:17.660 2284-2284/? I/AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 807-12 08:27:17.660 2284-2284/? I/r_submix: adev_open(name=audio_hw_if)
其中的第二行信息就是usb声卡的打印的一条信息。

"frameworks/av/services/audioflinger/AudioFlinger.cpp" 3024 lines --52%--1573 // loadHwModule_l() must be called with AudioFlinger::mLock held1574 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)1575 {1576     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {1577         if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {1578             ALOGW("loadHwModule() module %s already loaded", name);1579             return mAudioHwDevs.keyAt(i);1580         }1581     }...1643     audio_module_handle_t handle = nextUniqueId();1644     mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));1645 1646     ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",1647           name, dev->common.module->name, dev->common.module->id, handle);1648 1649     return handle;1650 1651 }
这条信息的内容是AudioFlinger打印出来的信息。调用的hardware目录下的工具。

<hardware/libhardware/modules/usbaudio/audio_hal.c>1074 static struct hw_module_methods_t hal_module_methods = {1075     .open = adev_open,1076 };1077 1078 struct audio_module HAL_MODULE_INFO_SYM = {1079     .common = {1080         .tag = HARDWARE_MODULE_TAG,1081         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,1082         .hal_api_version = HARDWARE_HAL_API_VERSION,1083         .id = AUDIO_HARDWARE_MODULE_ID,1084         .name = "USB audio HW HAL",1085         .author = "The Android Open Source Project",1086         .methods = &hal_module_methods,1087     },1088 };
打印的信息都在common这个结构体可以找到出处。

id的定义如下:

libhardware/include/hardware/audio.h:39:#define AUDIO_HARDWARE_MODULE_ID "audio"libhardware/include/hardware/audio.h:44:#define AUDIO_HARDWARE_INTERFACE "audio_hw_if" 
这个open函数如下:



policy文件作用:

gsc@gsc-250:/media/gsc/31269c00-69bd-4eed-814e-bade5758e213/7420_ext/frameworks$ grep -nr "AUDIO_POLICY_CONFIG_FILE"av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp:2748:        if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE,av/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h:26:#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"


1037 static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)1038 {1039     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)1040         return -EINVAL;1041 1042     struct audio_device *adev = calloc(1, sizeof(struct audio_device));1043     if (!adev)1044         return -ENOMEM;1045 1046     profile_init(&adev->out_profile, PCM_OUT);1047     profile_init(&adev->in_profile, PCM_IN);1048 1049     adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;1050     adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;1051     adev->hw_device.common.module = (struct hw_module_t *)module;1052     adev->hw_device.common.close = adev_close;1053 1054     adev->hw_device.init_check = adev_init_check;1055     adev->hw_device.set_voice_volume = adev_set_voice_volume;1056     adev->hw_device.set_master_volume = adev_set_master_volume;1057     adev->hw_device.set_mode = adev_set_mode;1058     adev->hw_device.set_mic_mute = adev_set_mic_mute;1059     adev->hw_device.get_mic_mute = adev_get_mic_mute;1060     adev->hw_device.set_parameters = adev_set_parameters;1061     adev->hw_device.get_parameters = adev_get_parameters;1062     adev->hw_device.get_input_buffer_size = adev_get_input_buffer_size;1063     adev->hw_device.open_output_stream = adev_open_output_stream;1064     adev->hw_device.close_output_stream = adev_close_output_stream;1065     adev->hw_device.open_input_stream = adev_open_input_stream;1066     adev->hw_device.close_input_stream = adev_close_input_stream;1067     adev->hw_device.dump = adev_dump;1068 1069     *device = &adev->hw_device.common;1070 1071     return 0;1072 }

该函数提供了其它操作硬件设备的函数。

out_profile定义于<system/media/alsa_utils/include/alsa_device_profile.h>文件。

typedef struct  {    int card;    int device;    int direction; /* PCM_OUT or PCM_IN */    enum pcm_format formats[MAX_PROFILE_FORMATS];    unsigned sample_rates[MAX_PROFILE_SAMPLE_RATES];    unsigned channel_counts[MAX_PROFILE_CHANNEL_COUNTS];    bool is_valid;    /* read from the hardware device */    struct pcm_config default_config;    unsigned min_period_size;    unsigned max_period_size;    unsigned min_channel_count;    unsigned max_channel_count;} alsa_device_profile;

在USB的Audio HAL层比较关键的两个函数是adev_open_output_stream和adev_open_input_stream,它们分别对应输出和输入流打开操作。

472 static int adev_open_output_stream(struct audio_hw_device *dev, 473                                    audio_io_handle_t handle, 474                                    audio_devices_t devices, 475                                    audio_output_flags_t flags, 476                                    struct audio_config *config, 477                                    struct audio_stream_out **stream_out, 478                                    const char *address /*__unused*/) 479 { 480     ALOGV("adev_open_output_stream() handle:0x%X, device:0x%X, flags:0x%X, addr:%s", 481           handle, devices, flags, address); 482  483     struct audio_device *adev = (struct audio_device *)dev; 484  485     struct stream_out *out; 486  487     out = (struct stream_out *)calloc(1, sizeof(struct stream_out)); 488     if (!out) 489         return -ENOMEM; 490  491     /* setup function pointers */ 492     out->stream.common.get_sample_rate = out_get_sample_rate; 493     out->stream.common.set_sample_rate = out_set_sample_rate; 494     out->stream.common.get_buffer_size = out_get_buffer_size; 495     out->stream.common.get_channels = out_get_channels; 496     out->stream.common.get_format = out_get_format; 497     out->stream.common.set_format = out_set_format; 498     out->stream.common.standby = out_standby; 499     out->stream.common.dump = out_dump; 500     out->stream.common.set_parameters = out_set_parameters; 501     out->stream.common.get_parameters = out_get_parameters; 502     out->stream.common.add_audio_effect = out_add_audio_effect; 503     out->stream.common.remove_audio_effect = out_remove_audio_effect; 504     out->stream.get_latency = out_get_latency; 505     out->stream.set_volume = out_set_volume; 506     out->stream.write = out_write; 507     out->stream.get_render_position = out_get_render_position; 508     out->stream.get_presentation_position = out_get_presentation_position; 509     out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 510  511     pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL); 512     pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL); 513  514     out->dev = adev; 515     pthread_mutex_lock(&adev->lock); 516     out->profile = &adev->out_profile; 517  518     // build this to hand to the alsa_device_proxy 519     struct pcm_config proxy_config; 520     memset(&proxy_config, 0, sizeof(proxy_config)); 521  522     /* Pull out the card/device pair */ 523     parse_card_device_params(address, &(out->profile->card), &(out->profile->device));... 526  527     profile_read_device_info(out->profile); 528  529     pthread_mutex_unlock(&adev->lock); 530  531     int ret = 0; 532  533     /* Rate */ 534     if (config->sample_rate == 0) { 535         proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(out->profile); 536     } else if (profile_is_sample_rate_valid(out->profile, config->sample_rate)) { 537         proxy_config.rate = config->sample_rate; 538     } else {539         proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(out->profile); 540         ret = -EINVAL; 541     } 542  543     /* Format */ 544     if (config->format == AUDIO_FORMAT_DEFAULT) { 545         proxy_config.format = profile_get_default_format(out->profile); 546         config->format = audio_format_from_pcm_format(proxy_config.format); 547     } else { 548         enum pcm_format fmt = pcm_format_from_audio_format(config->format); 549         if (profile_is_format_valid(out->profile, fmt)) { 550             proxy_config.format = fmt; 551         } else { 552             proxy_config.format = profile_get_default_format(out->profile); 553             config->format = audio_format_from_pcm_format(proxy_config.format); 554             ret = -EINVAL; 555         } 556     } 557  558     /* Channels */ 559     unsigned proposed_channel_count = 0; 560     if (k_force_channels) { 561         proposed_channel_count = k_force_channels; 562     } else if (config->channel_mask == AUDIO_CHANNEL_NONE) { 563         proposed_channel_count =  profile_get_default_channel_count(out->profile); 564     } 565     if (proposed_channel_count != 0) { 566         if (proposed_channel_count <= FCC_2) { 567             // use channel position mask for mono and stereo 568             config->channel_mask = audio_channel_out_mask_from_count(proposed_channel_count); 569         } else { 570             // use channel index mask for multichannel 571             config->channel_mask = 572                     audio_channel_mask_for_index_assignment_from_count(proposed_channel_count); 573         } 574         out->hal_channel_count = proposed_channel_count; 575     } else { 576         out->hal_channel_count = audio_channel_count_from_out_mask(config->channel_mask); 577     } 578     /* we can expose any channel mask, and emulate internally based on channel count. */ 579     out->hal_channel_mask = config->channel_mask; 580  581     /* no validity checks are needed as proxy_prepare() forces channel_count to be valid. 582      * and we emulate any channel count discrepancies in out_write(). */ 583     proxy_config.channels = proposed_channel_count; 584  585     proxy_prepare(&out->proxy, out->profile, &proxy_config); 586  587     /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */ 588     ret = 0; 589  590     out->conversion_buffer = NULL; 591     out->conversion_buffer_size = 0; 592  593     out->standby = true; 594  595     *stream_out = &out->stream; 596  597     return ret;... 603 }                                                                                 
这个函数的整体流程还是比较好理解的,首先为创建的output stream关联一些函数操作集合,操作集包括了采样率/通道数/声音格式等这些信息。并且out_write会调用ALSA接口pcm_write写pcm数据。pcm_config

<external/tinyalsa/include/asoundlib.h> 88 /* Configuration for a stream */ 89 struct pcm_config { 90     unsigned int channels; 91     unsigned int rate; 92     unsigned int period_size; 93     unsigned int period_count; 94     enum pcm_format format; 95  96     /* Values to use for the ALSA start, stop and silence thresholds, and 97      * silence size.  Setting any one of these values to 0 will cause the 98      * default tinyalsa values to be used instead. 99      * Tinyalsa defaults are as follows.100      *101      * start_threshold   : period_count * period_size102      * stop_threshold    : period_count * period_size103      * silence_threshold : 0104      * silence_size      : 0105      */106     unsigned int start_threshold;107     unsigned int stop_threshold;108     unsigned int silence_threshold;109     unsigned int silence_size;110 111     /* Minimum number of frames available before pcm_mmap_write() will actually112      * write into the kernel buffer. Only used if the stream is opened in mmap mode113      * (pcm_open() called with PCM_MMAP flag set).   Use 0 for default.114      */115     int avail_min;116 };

如果在初始化出问题,这个函数是需要跟踪。

ndroid 的USB支持已经由谷歌支持的很好了,基本上只需要开启内核的usb,如下图所示:

其所在的路径如下:

make ARCH=arm64 menuconfigDevice Drivers--->         [*] Sound card support--->                   [*] Advanced Linux Sound Architecture ---->                             [*] USB sound devices------------->                                       [*] USB Audio/MIDI driver        
配置上述的选项后,则在/dev/snd目录会有声卡信息,并且使用tinyplay能够播放wav类型的音乐。接下来就是安卓层的设置了。

如果该系统有外接codec,则对于安卓6.0上层只需要开启USB host即可,但是如果只有usb这么一个声卡,则有些麻烦,因为audio policy会涉及到选择output stream的问题,output stream是有audio_policy.conf文件来指定的,主要来说就是配置文件中的primary和usb这两个声卡的信息填写方法。

usb host的使能方式是:

"device.mk" 587 lines --66%-- 391 PRODUCT_COPY_FILES += \392     frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \393     frameworks/native/data/etc/android.hardware.camera.xml:system/etc/permissions/android.hardware.camera.xml \394     frameworks/native/data/etc/android.hardware.camera.front.xml:system/etc/permissions/android.hardware.camera.front.xml \395     frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml     \396     frameworks/native/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml \
392行添加usb host权限文件即可,该文件实际上只有一行。device.mk是对应android根目录的device下具体型号设备的device.mk文件。

接着将该文件push到系统中reboot即可生效:

adb push frameworks/native/data/etc/android.hardware.usb.host.xml /system/etc/permissions/

USB的audio设备有两种类型一种是usb device一种是usb accessory,这两种设备的区别在于7420侧的usb所扮演的角色不同。如果7420做host,则其要和一个能做slave的设备连接,则在conf文件中,这样的设备被称为usb device,反之被称为usb accessory。其源码中的定义和说明位置如下:

 604     /* USB accessory mode: your Android device is a USB device and the dock is a USB host */ 605     AUDIO_DEVICE_OUT_USB_ACCESSORY             = 0x2000, 606     /* USB host mode: your Android device is a USB host and the dock is a USB device */ 607     AUDIO_DEVICE_OUT_USB_DEVICE                = 0x4000, 608     AUDIO_DEVICE_OUT_REMOTE_SUBMIX             = 0x8000, 609     /* Telephony voice TX path */ 610     AUDIO_DEVICE_OUT_TELEPHONY_TX              = 0x10000,"system/media/audio/include/system/audio.h" 1446 lines --38%--   
所以在audio_policy.conf文件根据需要配置usb声卡信息;

  usb {    outputs {      #usb_accessory {       # sampling_rates 48000       # channel_masks AUDIO_CHANNEL_OUT_STEREO       # formats AUDIO_FORMAT_PCM_16_BIT       # devices AUDIO_DEVICE_OUT_USB_ACCESSORY      #}      usb_device {        sampling_rates 48000        channel_masks AUDIO_CHANNEL_OUT_STEREO        formats AUDIO_FORMAT_PCM_16_BIT        devices AUDIO_DEVICE_OUT_USB_DEVICE      }    }  }
在audio_policy.conf文件中还有global_configuration字段,该字段的可以按如下方式填写:
global_configuration {  #attached_output_devices AUDIO_DEVICE_OUT_USB_ACCESSORY  #default_output_device   AUDIO_DEVICE_OUT_USB_ACCESSORY  attached_output_devices AUDIO_DEVICE_OUT_USB_DEVICE  default_output_device   AUDIO_DEVICE_OUT_USB_DEVICE  #attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC}

在调试过程中发现了如下错误:

01-01 16:16:14.220 V/AudioPolicyService( 3954): inserting command: 3 at index 0, num commands 001-01 16:16:14.220 V/AudioPolicyService( 3954): AudioCommandThread() processing set parameters string card=0;connect=16384;device=0, io 001-01 16:16:14.220 V/AudioFlinger( 3954): setParameters(): io 0, keyvalue card=0;connect=16384;device=0, calling pid 395401-01 16:16:14.220 V/AudioPolicyService( 3954): AudioCommandThread() going to sleep01-01 16:16:14.220 V/APM::AudioPolicyManager( 3954): checkOutputForStrategy() strategy 1, moving from output 4 to output 601-01 16:16:14.220 V/AudioFlinger( 3954): invalidateStream() stream 001-01 16:16:14.220 V/AudioFlinger( 3954): invalidateStream() stream 601-01 16:16:14.220 F/APM::AudioPolicyManager( 3954): const TYPE& android::SortedVector<TYPE>::operator[](size_t) const [with TYPE = int; size_t = unsigned int]: index=0 out of range (0)01-01 16:16:14.220 F/libc    ( 3954): Fatal signal 6 (SIGABRT), code -6 in tid 3954 (mediaserver)01-01 16:16:14.320 F/DEBUG   ( 2287): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***01-01 16:16:14.330 W/NativeCrashListener( 2595): Couldn't find ProcessRecord for pid 395401-01 16:16:14.320 F/DEBUG   ( 2287): Build fingerprint: 'Android/full_phoenix/phoenix:6.0.1/MMB29T/gsc06080916:eng/dev-keys'01-01 16:16:14.320 F/DEBUG   ( 2287): Revision: '0'01-01 16:16:14.320 F/DEBUG   ( 2287): ABI: 'arm'01-01 16:16:14.320 F/DEBUG   ( 2287): pid: 3954, tid: 3954, name: mediaserver  >>> /system/bin/mediaserver <<<01-01 16:16:14.320 F/DEBUG   ( 2287): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------01-01 16:16:14.330 F/DEBUG   ( 2287): Abort message: 'const TYPE& android::SortedVector<TYPE>::operator[](size_t) const [with TYPE = int; size_t = unsigned int]: index=0 out of range (0)'01-01 16:16:14.340 E/DEBUG   ( 2287): AM write failed: Broken pipe01-01 16:16:14.340 F/DEBUG   ( 2287):     r0 00000000  r1 00000f72  r2 00000006  r3 f72f6b9401-01 16:16:14.340 F/DEBUG   ( 2287):     r4 f72f6b9c  r5 f72f6b4c  r6 00000000  r7 0000010c01-01 16:16:14.340 F/DEBUG   ( 2287):     r8 00000000  r9 f63f8014  sl ffbfbea4  fp f63ce75001-01 16:16:14.350 F/DEBUG   ( 2287):     ip 00000006  sp ffbfb9f0  lr f6dc528d  pc f6dc767c  cpsr 400f001001-01 16:16:14.360 F/DEBUG   ( 2287): 01-01 16:16:14.360 F/DEBUG   ( 2287): backtrace:01-01 16:16:14.370 F/DEBUG   ( 2287):     #00 pc 0004267c  /system/lib/libc.so (tgkill+12)01-01 16:16:14.370 F/DEBUG   ( 2287):     #01 pc 00040289  /system/lib/libc.so (pthread_kill+32)01-01 16:16:14.370 F/DEBUG   ( 2287):     #02 pc 0001c9d3  /system/lib/libc.so (raise+10)01-01 16:16:14.370 F/DEBUG   ( 2287):     #03 pc 00019c51  /system/lib/libc.so (__libc_android_abort+34)01-01 16:16:14.370 F/DEBUG   ( 2287):     #04 pc 000174ac  /system/lib/libc.so (abort+4)01-01 16:16:14.380 F/DEBUG   ( 2287):     #05 pc 00008173  /system/lib/libcutils.so (__android_log_assert+86)01-01 16:16:14.380 F/DEBUG   ( 2287):     #06 pc 00014d75  /system/lib/libaudiopolicymanagerdefault.so01-01 16:16:14.380 F/DEBUG   ( 2287):     #07 pc 0001bb95  /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::checkOutputForStrategy(android::routing_strategy)+268)01-01 16:16:14.380 F/DEBUG   ( 2287):     #08 pc 0001bd81  /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::checkOutputForAllStrategies()+56)01-01 16:16:14.380 F/DEBUG   ( 2287):     #09 pc 0001c3c5  /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::setDeviceConnectionStateInt(unsigned int, audio_policy_dev_state_t, char const*, char const*)+1548)01-01 16:16:14.380 F/DEBUG   ( 2287):     #10 pc 000097df  /system/lib/libaudiopolicyservice.so01-01 16:16:14.380 F/DEBUG   ( 2287):     #11 pc 0008a981  /system/lib/libmedia.so (android::BnAudioPolicyService::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+1164)01-01 16:16:14.380 F/DEBUG   ( 2287):     #12 pc 00019999  /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+60)01-01 16:16:14.380 F/DEBUG   ( 2287):     #13 pc 0001ecf9  /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+560)01-01 16:16:14.390 F/DEBUG   ( 2287):     #14 pc 0001ee51  /system/lib/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+64)01-01 16:16:14.390 F/DEBUG   ( 2287):     #15 pc 0001eeb5  /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+48)01-01 16:16:14.390 F/DEBUG   ( 2287):     #16 pc 00001bbb  /system/bin/mediaserver01-01 16:16:14.390 F/DEBUG   ( 2287):     #17 pc 00017359  /system/lib/libc.so (__libc_init+44)01-01 16:16:14.390 F/DEBUG   ( 2287):     #18 pc 00001e0c  /system/bin/mediaserver01-01 16:16:14.520 E/SurfaceFlinger( 2146): ro.sf.lcd_density must be defined as a build property
这时定位问题就变的比较重要了。

gsc@gsc-250:/media/gsc/31269c00-69bd-4eed-814e-bade5758e213/7420_ext$ prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-addr2line -f -e out/target/product/phoenix/symbols/system/lib/libaudiopolicymanagerdefault.so 0001bb95_ZN7android18AudioPolicyManager22checkOutputForStrategyENS_16routing_strategyE/media/gsc/31269c00-69bd-4eed-814e-bade5758e213/7420_ext/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp:3835 (discriminator 1)

临时动态推库调试:

 1906  . build/envsetup.sh  1907  lunch 1908  mmm frameworks/av/services/audiopolicy/ 1909  adb remount 1910  adb push out/target/product/phoenix/system/lib/libaudiopolicymanagerdefault.so /system/lib/ 1911  adb push out/target/product/phoenix/system/lib64/libaudiopolicymanagerdefault.so /system/lib64/ 1912  adb push out/target/product/phoenix/system/lib64/libaudiopolicyservice.so /system/lib64/ 1913  adb push out/target/product/phoenix/system/lib/libaudiopolicyservice.so /system/lib/ 1926  mmm frameworks/av/services/audiopolicy/ 1927  adb remount 1928  adb push out/target/product/phoenix/system/lib64/libaudiopolicyenginedefault.so /system/lib64/ 1929  adb push out/target/product/phoenix/system/lib/libaudiopolicyenginedefault.so /system/lib/ 1954  mmm frameworks/av/services/audiopolicy/enginedefault/ 1955  adb push audio_policy.conf /system/etc/ 1956  adb push out/target/product/phoenix/system/lib64/libaudiopolicyenginedefault.so /system/lib64/ 1957  adb push out/target/product/phoenix/system/lib/libaudiopolicyenginedefault.so /system/lib/ 1960  mmm hardware/libhardware/modules/usbaudio/ 1961  mmm frameworks/av/services/audiopolicy/ 1962  adb remount 1963  adb push out/target/product/phoenix/system/lib/hw/audio.usb.default.so /system/lib/ 1964  adb push out/target/product/phoenix/system/lib64/hw/audio.usb.default.so /system/lib64/hw/ 1965  adb push out/target/product/phoenix/system/lib/hw/audio.usb.default.so /system/lib/hw/ 1966  adb push out/target/product/phoenix/system/lib/libaudiopolicymanagerdefault.so /system/lib/ 1967  adb push out/target/product/phoenix/system/lib64/libaudiopolicymanagerdefault.so /system/lib64/ 1968  adb reboot 1969  mmm hardware/libhardware/modules/usbaudio/ 1970  adb remount 1971  adb push out/target/product/phoenix/system/lib/hw/audio.usb.default.so /system/lib/hw/ 1972  adb push out/target/product/phoenix/system/lib64/hw/audio.usb.default.so /system/lib64/hw/ 1973  adb reboot

一点有用的代码分析

class AudioPolicyManager:<frameworks/av/services/audiopolicy/manager/default/AudioPolicyManager.h>

     class AudioPolicyInterface: <frameworks/av/services/audiopolicy/AudioPolicyInterface.h>

    class AudioPolicyManagerObserver

    

AudioPolicyService创建:
<frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp>
在所有实际的操作前其会调用void AudioPolicyService::onFirstRef()
该函数调用了hardware层一些函数,也引用了hardware层一些函数,其定义在如下的函数中。
./hardware/libhardware/include/hardware/hardware.h

84行,未定义USE_LEGACY_AUDIO_POLICY,执行else语句分支。
114行~115行:

mAudioPolicyClient = new AudioPolicyClient(this);mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

<AudioPolicyService.h>

AudioPolicyInterface *mAudioPolicyManager;AudioPolicyClient *mAudioPolicyClient;

<frameworks/av/services/audiopolicy/AudioPolicyInterface.h>
336~337行如下代码:

​extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface);

上述函数的实现位置是

<./frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp>

 21 extern "C" AudioPolicyInterface* createAudioPolicyManager( 22         AudioPolicyClientInterface *clientInterface) 23 { 24     return new AudioPolicyManager(clientInterface); 25 }​​

AudioPolicyManager函数定义在<frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp>

 2712 AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
2713     :2714 #ifdef AUDIO_POLICY_TEST2715     Thread(false),2716 #endif //AUDIO_POLICY_TEST2717     mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),2718     mA2dpSuspended(false),2719     mSpeakerDrcEnabled(false),2720     mAudioPortGeneration(1),2721     mBeaconMuteRefCount(0),2722     mBeaconPlayingRefCount(0),2723     mBeaconMuted(false),2724     mTtsOutputAvailable(false)2725 {2726     audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();2727     if (!engineInstance) {2728         ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);2729         return;2730     }2731     // Retrieve the Policy Manager Interface2732     mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();2733     if (mEngine == NULL) {2734         ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);2735         return;2736     }2737     mEngine->setObserver(this);2738     status_t status = mEngine->initCheck();2739     ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);2740 2741     mUidCached = getuid();2742     mpClientInterface = clientInterface;2743 2744     mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);2745     if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE,2746                  mHwModules, mAvailableInputDevices, mAvailableOutputDevices,2747                  mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) {2748         if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE,2749                                   mHwModules, mAvailableInputDevices, mAvailableOutputDevices,2750                                   mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) {2751             ALOGE("could not load audio policy configuration file, setting defaults");2752             defaultAudioPolicyConfig();2753         }2754     }2755     // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices2756 2757     // must be done after reading the policy (since conditionned by Speaker Drc Enabling)2758     mEngine->initializeVolumeCurves(mSpeakerDrcEnabled);2759 2760     // open all output streams needed to access attached devices2761     audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();2762     audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;2763     for (size_t i = 0; i < mHwModules.size(); i++) {2764         mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);2765         if (mHwModules[i]->mHandle == 0) {2766             ALOGW("could not open HW module %s", mHwModules[i]->mName);2767             continue;2768         }2769         // open all output streams needed to access attached devices2770         // except for direct output streams that are only opened when they are actually2771         // required by an app.2772         // This also validates mAvailableOutputDevices list2773         for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)2774         {2775             const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];。。。2813             status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),2814                                                             &output,2815                                                             &config,2816                                                             &outputDesc->mDevice,2817                                                             String8(""),2818                                                             &outputDesc->mLatency,2819                                                             outputDesc->mFlags);2820 2821             if (status != NO_ERROR) {2822                 ALOGW("Cannot open output stream for device %08x on hw module %s",2823                       outputDesc->mDevice,2824                       mHwModules[i]->mName);2825             } else {2826                 outputDesc->mSamplingRate = config.sample_rate;2827                 outputDesc->mChannelMask = config.channel_mask;2828                 outputDesc->mFormat = config.format;2829 2830                 for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {2831                     audio_devices_t type = outProfile->mSupportedDevices[k]->type();2832                     ssize_t index =2833                             mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);2834                     // give a valid ID to an attached device once confirmed it is reachable2835                     if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {2836                         mAvailableOutputDevices[index]->attach(mHwModules[i]);2837                     }2838                 }2839                 if (mPrimaryOutput == 0 &&2840                         outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {2841                     mPrimaryOutput = outputDesc;2842                 }2843                 addOutput(output, outputDesc);2844                 setOutputDevice(outputDesc,2845                                 outputDesc->mDevice,2846                                 true);2847             }2848         }2849         // open input streams needed to access attached devices to validate2850         // mAvailableInputDevices list2851         for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)2852         {2853             const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];2854 2855             if (inProfile->mSupportedDevices.isEmpty()) {2856                 ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);2857                 continue;2858             }2859             // chose first device present in mSupportedDevices also part of2860             // inputDeviceTypes2861             audio_devices_t profileType = AUDIO_DEVICE_NONE;2862             for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {2863                 profileType = inProfile->mSupportedDevices[k]->type();2864                 if (profileType & inputDeviceTypes) {2865                     break;2866                 }2867             }2868             if ((profileType & inputDeviceTypes) == 0) {2869                 continue;2870             }2871             sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);2872 2873             inputDesc->mInputSource = AUDIO_SOURCE_MIC;2874             inputDesc->mDevice = profileType;2875 2876             // find the address2877             DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);2878             //   the inputs vector must be of size 1, but we don't want to crash here2879             String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress2880                     : String8("");2881             ALOGV("  for input device 0x%x using address %s", profileType, address.string());2882             ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");2883 2884             audio_config_t config = AUDIO_CONFIG_INITIALIZER;2885             config.sample_rate = inputDesc->mSamplingRate;2886             config.channel_mask = inputDesc->mChannelMask;2887             config.format = inputDesc->mFormat;2888             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;2889             status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),2890                                                            &input,2891                                                            &config,2892                                                            &inputDesc->mDevice,2893                                                            address,2894                                                            AUDIO_SOURCE_MIC,2895                                                            AUDIO_INPUT_FLAG_NONE);2896 2897             if (status == NO_ERROR) {2898                 for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {2899                     audio_devices_t type = inProfile->mSupportedDevices[k]->type();2900                     ssize_t index =2901                             mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);2902                     // give a valid ID to an attached device once confirmed it is reachable2903                     if (index >= 0) {2904                         sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];2905                         if (!devDesc->isAttached()) {2906                             devDesc->attach(mHwModules[i]);2907                             devDesc->importAudioPort(inProfile);2908                         }2909                     }2910                 }2911                 mpClientInterface->closeInput(input);2912             } else {2913                 ALOGW("Cannot open input stream for device %08x on hw module %s",2914                       inputDesc->mDevice,2915                       mHwModules[i]->mName);2916             }2917         }2918     }2919     // make sure all attached devices have been allocated a unique ID2920     for (size_t i = 0; i  < mAvailableOutputDevices.size();) {2921         if (!mAvailableOutputDevices[i]->isAttached()) {2922             ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->type());2923             mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);2924             continue;2925         }2926         // The device is now validated and can be appended to the available devices of the engine2927         mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],2928                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE);2929         i++;2930     }2931     for (size_t i = 0; i  < mAvailableInputDevices.size();) {2932         if (!mAvailableInputDevices[i]->isAttached()) {2933             ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());2934             mAvailableInputDevices.remove(mAvailableInputDevices[i]);2935             continue;2936         }2937         // The device is now validated and can be appended to the available devices of the engine2938         mEngine->setDeviceConnectionState(mAvailableInputDevices[i],2939                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE);2940         i++;2941     }2942     // make sure default device is reachable2943     if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {2944         ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());2945     }2946 2947     ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");2948 2949     updateDevicesAndOutputs();2950 2951 #ifdef AUDIO_POLICY_TEST2952     if (mPrimaryOutput != 0) {2953         AudioParameter outputCmd = AudioParameter();2954         outputCmd.addInt(String8("set_id"), 0);2955         mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString());2956 2957         mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;2958         mTestSamplingRate = 44100;2959         mTestFormat = AUDIO_FORMAT_PCM_16_BIT;2960         mTestChannels =  AUDIO_CHANNEL_OUT_STEREO;2961         mTestLatencyMs = 0;2962         mCurOutput = 0;2963         mDirectOutput = false;2964         for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {2965             mTestOutputs[i] = 0;2966         }2967 2968         const size_t SIZE = 256;2969         char buffer[SIZE];2970         snprintf(buffer, SIZE, "AudioPolicyManagerTest");2971         run(buffer, ANDROID_PRIORITY_AUDIO);2972     }2973 #endif //AUDIO_POLICY_TEST2974 }
2748行会解析/system/etc/audio_policy.conf配置文件,这是在找不到vendor定义的配置文件后的执行动作。

经过这个解析后,mAvailableOutputDevices和mAvailableInputDevices包括了所有的输出和输入设备。

2763行针对每一个设备进行加载。

2764行加载Hwmodule。

<frameworks/av/services/audioplolicy/AudioPolicyInterface.h>

class  ​ AudioPolicyClientInterface {...// loads a HW module.    virtual audio_module_handle_t loadHwModule(const char *name) = 0;...}

<./frameworks/av/services/audioflinger/AudioFlinger.cpp>

 ​1561 audio_module_handle_t AudioFlinger::loadHwModule(const char *name)1562 {1563     if (name == NULL) {1564         return 0;1565     }1566     if (!settingsAllowed()) {1567         return 0;1568     }1569     Mutex::Autolock _l(mLock);1570     return loadHwModule_l(name);1571 }1572 1573 // loadHwModule_l() must be called with AudioFlinger::mLock held1574 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)1575 {...1583     audio_hw_device_t *dev;1584 1585     int rc = load_audio_interface(name, &dev);1643     audio_module_handle_t handle = nextUniqueId();1644     mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));1649     return handle;}

load_audio_interface也定义在AudioFlinger函数里的定义如下:

 
140 static int load_audio_interface(const char *if_name, audio_hw_device_t **dev) 141 { 142     const hw_module_t *mod; 143     int rc; 144  145     rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod); 151     rc = audio_hw_device_open(mod, dev); 167 }

145行查看这类型的hw module是否存在,如果存在则会调用151行的open函数打开设备。

<./hardware/libhardware/include/hardware/audio.h>

 ​680 static inline int audio_hw_device_open(const struct hw_module_t* module,
681                                        struct audio_hw_device** device)682 {683     return module->methods->open(module, AUDIO_HARDWARE_INTERFACE,684                                  (struct hw_device_t**)device);685 }

实际上的open函数定义于具体声卡类型的文件中,针对与usb audio设备,其定义于

<hardware/libhardware/modules/usbaudio/audio_hal.c>

 ​1076 static struct hw_module_methods_t hal_module_methods = {1077     .open = adev_open,1078 };1079 1080 struct audio_module HAL_MODULE_INFO_SYM = {1081     .common = {1082         .tag = HARDWARE_MODULE_TAG,1083         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,1084         .hal_api_version = HARDWARE_HAL_API_VERSION,1085         .id = AUDIO_HARDWARE_MODULE_ID,1086         .name = "USB audio HW HAL",1087         .author = "The Android Open Source Project",1088         .methods = &hal_module_methods,1089     },1090 };

不出意外,这个open应该是成功的。接着打开流程loadHwModule的1644行。创建了一个硬件设备。该类的构造函数如下:

 ​    AudioHwDevice(audio_module_handle_t handle,                  const char *moduleName,                  audio_hw_device_t *hwDevice,                  Flags flags)        : mHandle(handle)        , mModuleName(strdup(moduleName))        , mHwDevice(hwDevice)        , mFlags(flags) { }

设备打开和添加的操作是完成了,接下来是打开对应的stream。AudioPolicyManager的2773行。

<./frameworks/av/services/audioflinger/AudioFlinger.cpp>

1775 sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,1776                                                             audio_io_handle_t *output,1777                                                             audio_config_t *config,1778                                                             audio_devices_t devices,1779                                                             const String8& address,1780                                                             audio_output_flags_t flags)1781 {1782     AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);1787     audio_hw_device_t *hwDevHal = outHwDev->hwDevice();1816     status_t status = outHwDev->openOutputStream(1817             &outputStream,1818             *output,1819             devices,1820             flags,1821             config,1822             address.string());...}​1848 status_t AudioFlinger::openOutput(audio_module_handle_t module,1849                                   audio_io_handle_t *output,1850                                   audio_config_t *config,1851                                   audio_devices_t *devices,1852                                   const String8& address,1853                                   uint32_t *latencyMs,1854                                   audio_output_flags_t flags)1855 {1870     sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
关键函数是1816行,打开stream。

<./frameworks/av/services/audioflinger/AudioHwDevice.cpp>

 34 status_t AudioHwDevice::openOutputStream(
 35         AudioStreamOut **ppStreamOut, 36         audio_io_handle_t handle, 37         audio_devices_t devices, 38         audio_output_flags_t flags, 39         struct audio_config *config, 40         const char *address) 41 {​  44     AudioStreamOut *outputStream = new AudioStreamOut(this, flags);status_t status = outputStream->open(handle, devices, config, address);
AudioStreamOut类的作用是管理对HAL层output Stream的操作。

<./frameworks/av/services/audioflinger/AudioStreamOut.cpp>

112 status_t AudioStreamOut::open(113         audio_io_handle_t handle,114         audio_devices_t devices,115         struct audio_config *config,116         const char *address)117 {118     audio_stream_out_t *outStream;119     int status = hwDev()->open_output_stream(120             hwDev(),121             handle,122             devices,123             flags,124             config,125             &outStream,126             address);127     ALOGV("AudioStreamOut::open(), HAL open_output_stream returned "128             " %p, sampleRate %d, Format %#x, "129             "channelMask %#x, status %d",130             outStream,131             config->sample_rate,132             config->format,133             config->channel_mask,134             status);135 136     if (status == NO_ERROR) {137         stream = outStream;138         mHalFormatIsLinearPcm = audio_is_linear_pcm(config->format);139         ALOGI("AudioStreamOut::open(), mHalFormatIsLinearPcm = %d", (int)mHalFormatIsLinearPcm);140         mHalFrameSize = audio_stream_out_frame_size(stream);141     }142 143     return status;144 }

AudioStreamOut.cpp文件里的绝大多数函数是调用HAL层代码完成其工作的。

上面的函数119行调用hardware/libhardware/modules/usbaudio/audio_hal.c的adev_open_output_stream完成实际的打开动作。

engin函数会对设备的类型和config参数进行相应的设置。

0 0