1.Android audio_policy_configuration.xml
2.Android Audioç®è¿°
3.Android音频模块启动流程分析
4.Android音频(1)_AudioTrack::createTrack
Android audio_policy_configuration.xml
åè¨Androidçaudioserver è¿ç¨å¯å¨æ¶ï¼ä¼å建AudioPolicyManagerï¼å¨æé å½æ°ä¸ï¼é¦å ä¼å»è§£æaudio_policy_configuration.xmlæ件ã
audioé³é¢æ°æ®ä»ä¸ä¸ªæºèµ°å°ä¸ä¸ªç®çé½æ¯éè¦æ ¹æ®é ç½®æ件audio_policy_configuration.xmlæ¥å³å®ï¼æ以ç解configurationé ç½®æ件ä¸å个æ ç¾é¡¹è½¬å为c++å®ä½ç±»çååæåè³å ³éè¦ã
audio_policy_configuration.xml为é³é¢audioç设å¤ãæµä»¥åè·¯ç±çé ç½®æ件ï¼éé¢åæäºaudioé³é¢é¨åæåªäºè®¾å¤ãåªäºæµä»¥åå®ä»¬æ¯æçç¼ç ãæ ¼å¼ä»¥åééåå¨å¸å±çç
audio_policy_configuration.xmlä¸ ç<modules>对åºæ¯ä¸ä¸ªaudio hal çsoï¼moduleä¸ååºçmixPortsï¼devicePortsåroutes解æä¹åå®æ´çæè¿°äºé³é¢çè·¯ç±è§å
module name
æ¯æâprimaryâ (ç¨äºè½¦è½½ä½¿ç¨åºæ¯),源码 "A2DP", "remote_submix"å"USB"ã模åå称åç¸åºé³é¢é©±å¨ç¨åºåºç¼è¯å° audio.primary.$(variant).so ä¸
devicePorts
å å«å¯ä»æ¤æ¨¡å访é®çææè¾å ¥åè¾åºè®¾å¤ï¼å æ¬æ°¸ä¹ è¿æ¥ç设å¤åå¯ç§»é¤è®¾å¤ï¼ç设å¤æ述符å表ã设å¤çoutputåinputï¼ä¸æ¯åmixporté£æ ·ä»¥roleæ¥åï¼èæ¯ä»¥typeä¸æå ³é®åâINâåâOUTâæ¥åºå
mixPorts
å å«ç±é³é¢ HAL æä¾çææè¾åºæµåè¾å ¥æµçå表ãæ¯ä¸ª mixPort å®ä¾é½å¯è¢«è§ä¸ºä¼ è¾å° Android AudioService çç©çé³é¢æµï¼streamé ç½®äºèªå·±çæ ¼å¼ãéæ ·ç以åmaskï¼å¹¶ä¸å为è¾åºãè¾å ¥æµãä¸ä¸ªmixPortæ ç¾å¯è½æå¤ä¸ªprofileå±æ§ï¼ä¹å°±æ¯æ¯æå¾å¤ç¼ç æ ¼å¼å±æ§
routes
å®ä¹è¾å ¥åè¾åºè®¾å¤ä¹é´æé³é¢æµå设å¤ä¹é´å¯è½åå¨çè¿æ¥çå表ãrouteæ¯ædeviceportåmixportè¿æ¥èµ·æ¥çè·¯ç±ï¼æ°æ®ç±ä¸ä¸ªstreamè¾åºå°å¦ä¸ä¸ªdeviceï¼æè ä»ä¸ä¸ªdeviceè¾åºå°å¦ä¸ä¸ªstreamã
Android Audioç®è¿°
audioæ¯Androidç³»ç»æ¯æ¯è¾éè¦çä¸ä¸ªæ¨¡åï¼æ¬äººä¹æ¶è¶³æ¶é´ä¸æ¯å¾é¿ï¼ç»éªè¿æ¯å¾å°çï¼åªæ¯æèªå·±å¨å·¥ä½ä¸æéå°çé®é¢è®°å½ã
Audio å³é³é¢ï¼ ä¹å°±æ¯æ§å¶çææºä¸çåç§å£°é³çè¾åºï¼æ¯å¦è¯´ï¼é³ä¹çææ¾ï¼é³é大å°ï¼æé®é³ï¼æå ¥è³æºï¼å£°é³ä»è³æºææ¾ï¼è¿æ¥èçï¼å£°é³ä»èçè³æºä¸ææ¾ãè¿æä¸äºHiFiææ¾ï¼ offloadææ¾ï¼é«æ¸ ææ¾ã
常è§çé®é¢å¦ä¸ï¼
POPé³ï¼æ¼é³ï¼å£°é³å¡é¡¿ï¼è³æºæ æ³è¯å«ï¼è¿æä¸äºé³é¢éè·¯çé®é¢ï¼è¿æä¸äºç¨³å®æ§çé®é¢å¦ï¼ANRãCRASHãtombstoneãè¿æä¸äºå®å ¨æ¼æ´çé®é¢ï¼ä¸»è¦æ¯æ ¸å¿åºé£éï¼ã
åå½æ£é¢
-------å丽çåå²çº¿-------
audioå为 åºç¨å±ï¼fwkå±ï¼native fwkï¼ halå±ã
常è§çæ件æMediaPlayer.javaã AudioSystem.javaã AudioService.javaãAudioManager.java æ件路å¾(framework/base/media)
AudioFlinger.cppãAudioTrack.cppã AudioPolicyManager.cppã Threads.cppãTracks.cppã Engine.cppã Audiosystem.cpp æ件路å¾(framework/av)
audio_hw.c æ件路å¾ï¼vendor/ï¼
javaæ件æå¨è¿éå°±ä¸è¿å¤ç说äºï¼æ²¡å¥å¥½è®²çï¼ä¸»è¦è¯´ä¸ä¸c++æ件å§ã
AudioFlinger æ¯é³é¢çç¥çæ§è¡è ï¼ AudioPolicyManageræ¯å¶ä½é³é¢çç¥çï¼AudioTrackæ¯è´è´£ææ¾ä»ä¸å±ä¼ è¿æ¥çPCMæ°æ®ï¼ç®åç说就æ¯è´è´£ææ¾çã
audio_hw æ¯æ¯ä¸ªHALå±çæ件ï¼æ¯ä¸ªææºååèªå·±å®å¶çæ件ãå½ç¶Googleä¹æã
ä¸è¬å¢ï¼æ们å¤çé³é¢ç¸å ³çé®é¢å¢ï¼æä¸äºç¹å®çå¥è·¯ï¼éè¦AP 侧çlogï¼ ææ¶è¿éè¦kernel çlogï¼ å½ç¶æ主è¦çæ¯éè¦é³é¢æ°æ®ãä¹å°±æ¯åºç°é®é¢æ¶ï¼ç声é³æ°æ®ï¼è®©æ们å¯ä»¥å¿«éçå®ä½åºç°é®é¢çä½ç½®ã
ç®åç说ä¸ææ¾ä¸é¦ææ²çæµç¨ï¼ï¼ä»¥Android O 为ä¾ï¼
ä¸å±å建ä¸ä¸ªMediaPlayer对象ï¼ç¶åè°ç¨NuPlayeræ¡æ¶ï¼ææ¾å¨ï¼ï¼NuPlayerå å°å½åææ²çæ件信æ¯è¯»åï¼éæ ·çï¼æ¯ç¹çï¼çä¹ç±»çä¸è¥¿ãç¶åå¼å§è°ç¨audio decoder ï¼é³é¢è§£ç å¨ï¼ å°è§£ç åºæ¥çPCMæ°æ®ä¼ ç»AudioTrackï¼ Audiotrack ä¼å建ä¸ä¸ªTrackï¼ï¼æ¯ä¸ä¸ªææ¾é½ä¼å建ä¸ä¸ªå±äºèªå·±çtrackï¼ä¸ç¨äºå°±éæ¯ï¼æå¤å¯ä»¥åæ¶å建个ï¼ï¼ç»è¿AudioFlingerééæ ·ä¹åï¼éå°HALå±ï¼HALå±å¨ç»è¿ä¸äºæ··é³ï¼éåªä¹ç±»çå¤çï¼å°å£°é³éå°Codecï¼ç¶åéç»ç¡¬ä»¶è¾åºï¼è¿è¡ææ¾ã
è¿ä¸ªæ¯ä¸ä¸ªå¤§æ¦çææ¾æµç¨ï¼å¦ææ们å¨ææ¾è¿ç¨ä¸éå°äºä¸äºé®é¢ï¼æ¯å¦è¯´æ¯fwkå±çé®é¢ï¼æ们就å¨AudioTrackä¸AudioFlingerä¹é´å¯»é®é¢çåå ã
æ¯å¦è¯´ï¼ææ¾æ 声ï¼æ们éè¦çAudioPolicyManagerä¸çä¸äºçç¥æ¯ä¸æ¯å°å½åçtrackç»muteäºãæè æ¯ä¸äºå ¶ä»çåå çã
è¿éåªæ¯ç®åçä»ç»ä¸Audioï¼Audioç®æ¯ä¸ä¸ªè¾ä¸ºå¤æç模åï¼è¿éè¦å¥½å¥½çç 究ã
Android音频模块启动流程分析
设备开机后,系统启动时,源码执行位于 /system/etc/init/audioserver.rc 的源码内容,启动 audioserver 服务。源码audioserver 会依次实例化 AudioFlinger、源码AudioPolicyService、源码freemarker 案例源码RadioService、源码SoundTriggerHwService。源码若设备集成了杜比音效,源码则会实例化 DolbyMemoryService。源码audioserver.rc 的源码关键代码在 frameworks/av/media/audioserver/main_audioserver.cpp 的 main() 函数中。
AudioFlinger 进行初始化,源码挂饰源码包括创建 MIXER 和 DUPLICATING 类型的源码 playback 线程被创建后的等待延时时间,初始化 PatchPanel 对象,源码并将音频模式设置为 AUDIO_MODE_NORMAL。源码关键代码位于 frameworks/av/services/audioflinger/audioflinger.cpp。
AudioPolicyService 初始化,创建 AudioPolicyManager 对象。为了兼容老版本,系统提供了两种创建 AudioPolicyManager 的方式,通常使用新方式。关键代码在 frameworks/av/services/audiopolicy/AudioPolicyService.cpp 的 AudioPolicyService::onFirstRef() 函数中。
在 frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp 文件中,加密币源码createAudioPolicyManager() 函数调用 AudioPolicyManager 的构造函数,解析音频策略配置文件,获取设备支持的音频设备信息,加载所有 HwModule,创建所有非 direct 输出类型的 outputStream 和所有 inputStream,并创建 playbackThread 或 recordThread 线程。Android 7.0 的音频策略配置文件使用 XML 格式,文件名为 audio_policy_configuration.xml。关键代码在 frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 中。
至此,Android 系统中的指标源码dma音频模块启动完成。AudioFlinger 和 AudioPolicyService 创建并运行,设备支持的音频硬件信息由 AudioPolicyManager 解析。插入耳机或 APP 播放音乐时,AudioPolicyService 会接收底层通知,切换 Audio Route。设备播放声音时,音频数据从 AudioTrack 传输到 AudioFlinger,经过 Audio HAL,最终写入硬件。对于此过程的了解,可参考 zyuanyun 的口罩监测源码文章《Android 音频系统:从 AudioTrack 到 AudioFlinger》,文章内容已清晰阐述。
Android音频(1)_AudioTrack::createTrack
AudioTrack是Android系统中用于播放音频数据的关键类,它是应用与音频引擎之间的接口。通过使用AudioTrack,开发者可以将解码后的音频数据发送至音频引擎进行播放。AudioTrack的核心操作之一是createTrack,这是在播放音频前必须执行的步骤,用于选择和建立音频通道,并开辟数据传送的内存空间。具体实现中,createTrack操作会创建一个share buffer,该缓冲区既能被AudioTrack写入数据,也能被AudioFlinger读取以进行混音处理。
在介绍AudioTrack的创建流程时,以MediaPlayerService为例进行详细阐述。这一过程中,首先会设置相关标志,并创建一个名为AudioTrackThread的线程。该线程在暂停状态下运行,直到被调用start()方法后才开始活动。AudioTrack的创建涉及一系列关键步骤,包括与AudioFlinger的交互、获取输出设备、以及最终创建实际的AudioTrack实例。
在获取输出设备的过程中,AudioPolicyService的getOutputForAttr方法发挥着核心作用。这一方法根据特定属性获取对应输出,实际上是在AudioPolicy的服务范畴内进行操作。在汽车等特定应用场景中,如果系统支持动态路由,这一过程会通过AudioPolicyMix处理。通常情况下,通过AudioSystem调用AudioPolicyService的getOutputForAttr方法,最终将selectedDeviceId属性赋值。
之后,Audio系统通过AudioPolicyManager的getOutputForAttr方法获取输出设备。在播放音乐的场景中,最终选择的输出设备是AUDIO_DEVICE_OUT_SPEAKER。获取设备之后,Audio系统会进一步调用getOutputForDevice方法,从当前存在的设备集合中选择一个符合策略和格式要求的输出。在播放音乐的例子中,这里会设置flags为AUDIO_OUTPUT_FLAG_DEEP_BUFFER,以优化音频播放体验。
在选择输出设备后,Audio系统会根据提供的输出设备ID获取对应的PlaybackThread,这一过程发生在AudioPolicy初始化时。之后,Audio系统创建匿名共享内存,分配大小通常基于配置的audio buffer大小,例如A设备可能会分配大约7M的共享内存。然后,通过构造MemoryDealer和heap()及allocate()操作,系统从共享内存中获取所需大小的内存块。
创建AudioTrack的关键步骤包括TrackBase构造函数的调用,该函数首先计算音频缓冲区的大小,并分配相应的内存空间。Audio buffer的结构包括头部的audio_track_cblk_t和后续的音频PCM数据。从已创建的共享内存中获取大小匹配的内存空间,并通过构造共享内存的句柄完成分配过程。最终,通过MemoryDealer和heap()及allocate()操作,AudioTrack得以成功创建,从而实现在Android系统中的音频播放。