Android音频子系统分析-音量设置

调节音量大小,通常有两种方式:1. 通过硬件调节:放大电流。2. 通过软件调节:调整pcm振幅。这里主要说一下通过软件调节音量的流程,基于Android12。我们知道音频流是通过AudioFlinger处理并输出的,那软件调节的音量设置信息肯定需要传递到AudioFlinger中。

Android中调节音量可以通过直接设置音量值的方式,也可以通过音量键进行逐步调节。

音量键调节

Android中通过InputFlinger捕获到按键后,会层层上传,最终区分音量键、主页键等逻辑处理在PhoneWindowManager.java

interceptKeyBeforeDispatching

dispatchDirectAudioEvent

接着转到AudioService中处理,上层所有音频相关的逻辑基本上都是AudioManager提供接口,AudioService实现。这里由于PhoneWindowManager属于Framework,所以直接调用AudioService。

AudioService.java

  • handleVolumeKey
  • adjustSuggestedStreamVolume     //这里会取到作用于当前音量调节的streamType
  • adjustStreamVolume
  • sendMsg
  • setDeviceVolume
  • applyDeviceVolume_syncVSS
  • setStreamVolumeIndex

接下来传到AudioSystem。AudioSystem全是static函数,基本上就是接口传递,cpp层的最后一步。

AudioSystem.java

  • setStreamVolumeIndexAS
  • setStreamVolumeIndex

然后是JNI

android_media_AudioSystem.cpp

  • android_media_AudioSystem_setStreamVolumeIndex

Navive层同样有一个AudioSystem对应

AudioSystem.cpp

  • setStreamVolumeIndex

然后就转到了AudioPolicyService处理,这里在找代码的时候我一直以为在AudioPolicyService.cpp中,结果在AudioPolicyInterfaceImpl.cpp,从文件内容中可以看出AudioPolicyInterfaceImpl.cpp并不是一个单独的类,也是AudioPolicyService类一些函数的实现。我的理解是从AudioSystem调用过来的接口就在这个文件实现。

AudioPolicyInterfaceImpl.cpp

  • setStreamVolumeIndex

然后进入AudioPolicyManager.cpp。这里的命名跟实际的逻辑有点让人混淆,Binder调用我们一般接口喜欢命名为XXXManager,服务命名为XXXService。而AudioPolicyService中,接口为IAudioPolicyService,实现为AudioPolicyService,在实现中再调用AudioPolicyManager,所以这里的AudioPolicyManager需要理解为AudioPolicyService中的一个manager。

AudioPolicyManager.cpp

  • setStreamVolumeIndex
  • setVolumeIndexForAttributes
  • checkAndSetVolume                   //将volume index转为了float

继续调用AudioOutputDescriptor,AudioOutputDescriptor有两个子类,SwAudioOutputDescriptor和HwAudioOutputDescriptor。这里会走SwAudioOutputDescriptor。

AudioOutputDescriptor.cpp

  • setVolume

AudioPolicyClientImpl.cpp

  • setStreamVolume

饶了一圈回来,又进入到AudioPolicyService,和第一次不同,这次的实现逻辑在AudioPolicyService.cpp中。

AudioPolicyService.cpp

  • setStreamVolume
  • volumeCommand
  • sendCommand
  • threadLoop                 //threadloop中处理SET_VOLUME msg

又到AudioSystem里,不过这里主要是通过AudioSystem与AudioFlinger通信了。

AudioSystem.cpp

  • setStreamVolume

这里终于传到AudioFlinger中了。

AudioFlinger.cpp

  • setStreamVolume

Thread分为好几种,混音MixerThread和不混音DirectOutputThread等,不管是哪种都需要处理音量。PlaybackThread是它们的基类,并且又继承至VolumeInterface,VolumeInterface提供了setStreamVolume接口,AudioFlinger通过这个接口设置到Thread中,并保存起来。

Threads.cpp

  • setStreamVolume

至此从上到下的音量设置流程就结束了。

这里再补充下音量实际被使用的地方。这里会将传进来的音量进一步进行计算,如果AudioTrack单独设置过音量,也需要乘上它的音量系数。

Threads.cpp

  • prepareTracks_l

将左右声道的音量值传到AudioMixer进行混音计算。

AudioMixer.cpp

  • setParameter

改变音量值调节

Android提供了AudioManager接口,支持直接改变音量值。

AudioManager.java

  • setStreamVolume

AudioService.java

  • setStreamVolume
  • onSetStreamVolume
  • setStreamVolumeInt
  • sendMsg

再后面的逻辑就与音量键调节一致了。

另外说明一下,在car android系统中,音量设置逻辑又不一样,参考:

音量管理  |  Android Open Source Project

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值