转:ANDROID音频系统散记之四:4.0音频系统HAL初探

本文深入探讨Android 4.0音频系统的HAL(硬件抽象层),包括代码位置变化、AudioFlinger加载HAL的过程、legacy和current HAL接口、A2dp Audio HAL的实现。介绍了AudioFlinger如何通过`hw_get_module_by_class`加载音频模块,并分析了Audio Hardware HAL的结构和接口定义。此外,还提及了Audio Hardware HAL的legacy实现以及a2dp Audio HAL在bluez中的实现。
摘要由CSDN通过智能技术生成

https://www.cnblogs.com/albert1017/p/3949398.html

转:ANDROID音频系统散记之四:4.0音频系统HAL初探

昨天(2011-11-15)发布了Android4.0的源码,今天download下来,开始挺进4.0时代。简单看了一下,发现音频系统方面与2.3的有较多地方不同,下面逐一描述。

 

一、代码模块位置

1、AudioFlinger

 

  1. frameworks/base/services/audioflinger/  
  2. +-- Android.mk  
  3. +-- AudioBufferProvider.h  
  4. +-- AudioFlinger.cpp  
  5. +-- AudioFlinger.h  
  6. +-- AudioMixer.cpp  
  7. +-- AudioMixer.h  
  8. +-- AudioPolicyService.cpp  
  9. +-- AudioPolicyService.h  
  10. +-- AudioResampler.cpp  
  11. +-- AudioResamplerCubic.cpp  
  12. +-- AudioResamplerCubic.h  
  13. +-- AudioResampler.h  
  14. +-- AudioResamplerSinc.cpp  
  15. +-- AudioResamplerSinc.h  

AudioFlinger相关代码,好像这部分与2.3相差不大,至少接口是兼容的。值得注意的是:2.3位于这里的还有AudioHardwareGeneric、AudioHardwareInterface、A2dpAudioInterface等一系列接口代码,现在都移除了。实际上,这些接口变更为legacy(有另外更好的实现方式,但也兼容之前的方法),取而代之的是要实现hardware/libhardware/include/hardware/audio.h提供的接口,这是一个较大的变化。

 

两种Audio Hardware HAL接口定义:

1/ legacy:hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.h

2/ current:hardware/libhardware/include/hardware/audio.h
 

2、audio_hw

 

  1. hardware/libhardware_legacy/audio/  
  2. +-- A2dpAudioInterface.cpp  
  3. +-- A2dpAudioInterface.h  
  4. +-- Android.mk  
  5. +-- AudioDumpInterface.cpp  
  6. +-- AudioDumpInterface.h  
  7. +-- AudioHardwareGeneric.cpp  
  8. +-- AudioHardwareGeneric.h  
  9. +-- AudioHardwareInterface.cpp  
  10. +-- AudioHardwareStub.cpp  
  11. +-- AudioHardwareStub.h  
  12. +-- audio_hw_hal.cpp  
  13. +-- AudioPolicyCompatClient.cpp  
  14. +-- AudioPolicyCompatClient.h  
  15. +-- audio_policy_hal.cpp  
  16. +-- AudioPolicyManagerBase.cpp  
  17. +-- AudioPolicyManagerDefault.cpp  
  18. +-- AudioPolicyManagerDefault.h  

上面提及的AudioHardwareGeneric、AudioHardwareInterface、A2dpAudioInterface等都放到libhardware_legacy里。

事实上legacy也要封装成current中的audio.h,确切的说需要一个联系legacy interface和not legacy interface的中间层,这里的audio_hw_hal.cpp就充当这样的一个角色了。因此,我们其实也可以把2.3之前的alsa_sound这一套东西也搬过来。

 

  1. hardware/libhardware/modules/audio/  
  2. +-- Android.mk  
  3. +-- audio_hw.c  
  4. +-- audio_policy.c  

这是一个stub(类似于2.3中的AudioHardwareStub),大多数函数只是简单的返回一个值,并没有实际操作,只是保证Android能得到一个audio hardware hal实例,从而启动运行,当然声音没有输出到外设的。在底层音频驱动或audio hardware hal还没有实现好的情况下,可以使用这个stub device,先让Android跑起来。

 

  1. device/samsung/tuna/audio/  
  2. +-- Android.mk  
  3. +-- audio_hw.c  
  4. +-- ril_interface.c  
  5. +-- ril_interface.h  

这是Samsung Tuna的音频设备抽象层,很有参考价值,计划以后就在它的基础上进行移植。它调用tinyalsa的接口,可见这个方案的底层音频驱动是alsa。

 

3、tinyalsa

 

  1. external/tinyalsa/  
  2. +-- Android.mk  
  3. +-- include  
  4. |   +-- tinyalsa  
  5. |       +-- asoundlib.h  
  6. +-- mixer.c      ##类alsa-lib的control,作用音频部件开关、音量调节等  
  7. +-- pcm.c        ##类alsa-lib的pcm,作用音频pcm数据回放录制  
  8. +-- README  
  9. +-- tinycap.c    ##类alsa_arecord  
  10. +-- tinymix.c    ##类alsa_amixer  
  11. +-- tinyplay.c   ##类alsa_aplay  

在2.3时代,Android还隐晦把它放在android2.3.1-gingerbread/device/samsung/crespo/libaudio,现在终于把alsa-lib一脚踢开,小三变正室了,正名tinyalsa。

这其实是历史的必然了,alsa-lib太过复杂繁琐了,我看得也很不爽;更重要的商业上面的考虑,必须移除被GNU GPL授权证所约束的部份,alsa-lib并不是个例。

注意:上面的hardware/libhardware_legacy/audio/、hardware/libhardware/modules/audio/、device/samsung/tuna/audio/是同层的。之一是legacy audio,用于兼容2.2时代的alsa_sound;之二是stub audio接口;之三是Samsung Tuna的音频抽象层实现。调用层次:AudioFlinger -> audio_hw -> tinyalsa。

 

二、Audio Hardware HAL加载

 

1、AudioFlinger

 

  1. //加载audio hardware hal  
  2. static int load_audio_interface(const char *if_name, const hw_module_t **mod,  
  3.                                 audio_hw_device_t **dev)  
  4. {  
  5.     int rc;  
  6.       
  7.     //根据classid和if_name找到指定的动态库并加载,这里加载的是音频动态库,如libaudio.primary.tuna.so  
  8.     rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, mod);  
  9.     if (rc)  
  10.         goto out;  
  11.   
  12.     //加载好的动态库模块必有个open方法,调用open方法打开音频设备模块  
  13.     rc = audio_hw_device_open(*mod, dev);  
  14.     LOGE_IF(rc, "couldn't open audio hw device in %s.%s (%s)",  
  15.             AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));  
  16.     if (rc)  
  17.         goto out;  
  18.   
  19.     return 0;  
  20.   
  21. out:  
  22.     *mod = NULL;  
  23.     *dev = NULL;  
  24.     return rc;  
  25. }  
  26.   
  27. //音频设备接口,hw_get_module_by_class需要根据这些字符串找到相关的音频模块库  
  28. static const char *audio_interfaces[] = {  
  29.     "primary", //主音频设备,一般为本机codec  
  30.     "a2dp",    //a2dp设备,蓝牙高保真音频  
  31.     "usb",     //usb-audio设备,这个东东我2.3就考虑要实现了,现在终于支持了  
  32. };  
  33. #define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))  
  34.   
  35. // ----------------------------------------------------------------------------  
  36.   
  37. AudioFlinger::AudioFlinger()  
  38.     : BnAudioFlinger(),  
  39.         mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),  
  40.         mBtNrecIsOff(false)  
  41. {  
  42. }  
  43.   
  44. void AudioFlinger::onFirstRef()  
  45. {  
  46.     int rc = 0;  
  47.   
  48.     Mutex::Autolock _l(mLock);  
  49.   
  50.     /* TODO: move all this work into an Init() function */  
  51.     mHardwareStatus = AUDIO_HW_IDLE;  
  52.   
  53.     //打开audio_interfaces数组定义的所有音频设备  
  54.     for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {  
  55.         const hw_module_t *mod;  
  56.         audio_hw_device_t *dev;  
  57.   
  58.         rc = load_audio_interface(audio_interfaces[i], &mod, &dev);  
  59.         if (rc)  
  60.             continue;  
  61.   
  62.         LOGI("Loaded %s audio interface from %s (%s)", audio_interfaces[i],  
  63.              mod->name, mod->id);  
  64.         mAudioHwDevs.push(dev); //mAudioHwDevs是一个Vector,存储已打开的audio hw devices  
  65.   
  66.         if (!mPrimaryHardwareDev) {  
  67.             mPrimaryHardwareDev = dev;  
  68.             LOGI("Using '%s' (%s.%s) as the primary audio interface",  
  69.                  mod->name, mod->id, audio_interfaces[i]);  
  70.         }  
  71.     }  
  72.   
  73.     mHardwareStatus = AUDIO_HW_INIT;  
  74.   
  75.     if (!mPrimaryHardwareDev || mAudioHwDevs.size() == 0) {  
  76.         LOGE("Primary audio interface not found");  
  77.         return;  
  78.     }  
  79.   
  80.     //对audio hw devices进行一些初始化,如mode、master volume的设置  
  81.     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {  
  82.         audio_hw_device_t *dev = mAudioHwDevs[i];  
  83.   
  84.         mHardwareStatus = AUDIO_HW_INIT;  
  85.         rc = dev->init_check(dev);  
  86.         if (rc == 0) {  
  87.             AutoMutex lock(mHardwareLock);  
  88.   
  89.             mMode = AUDIO_MODE_NORMAL;  
  90.             mHardwareStatus = AUDIO_HW_SET_MODE;  
  91.             dev->set_mode(dev, mMode);  
  92.             mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值