Android Audio架构学习总结

目录

 主要类

Audio 播放流程

Track构建

getoutput流程

Audio播放流程



 主要类

AudioTrack(输出)和AudioRecorder,MediaPlayerService内部的实现就是通过它们来完成的,只不过MediaPlayer/MediaRecorder提供了更强大的控制功能,相比前者也更易于使用。
以前是基于ALSA,后来改为tinyalsa。

Audio Application Framework:音频应用框架
    AudioTrack:负责回放数据的输出,属 Android 应用框架 API 类
    AudioRecord:负责录音数据的采集,属 Android 应用框架 API 类
    AudioSystem: 负责音频事务的综合管理,属 Android 应用框架 API 类
Audio Native Framework:音频本地框架
    AudioTrack:负责回放数据的输出,属 Android 本地框架 API 类
    AudioRecord:负责录音数据的采集,属 Android 本地框架 API 类
    AudioSystem: 负责音频事务的综合管理,属 Android 本地框架 API 类
Audio Services:音频服务
    AudioPolicyService:音频策略的制定者,负责音频设备切换的策略抉择、音量调节策略等,包含各种command线程。
    AudioFlinger:音频策略的执行者,负责输入输出流设备的管理及音频流数据的处理传输。openOutput中会针对输出设备的类型创建了一个PlaybackThread。  PlaybackThread有几种,比较常见有MixerThread,蓝牙耳机设备需要外放(比如ring类型的流需要同时从耳机与喇叭出来)的时候使用DuplicatingThread。
Audio HAL:音频硬件抽象层,负责与音频硬件设备的交互,由 AudioFlinger 直接调用。

与 Audio 强相关的有 MultiMedia,MultiMedia 负责音视频的编解码,MultiMedia 将解码后的数据通过 AudioTrack 输出,而 AudioRecord 采集的录音数据交由 MultiMedia 进行编码。


Audio 播放流程

Track构建

AudioTrack---native_setup---android_media_AudioTrack_setup
具体可参考:createTrack_l流程

getoutput流程

audio_io_handle_t 是与 PlaybackThread 是一一对应的(一对键值对),由已知的 audio_io_handle_t 就能找到对应的 PlaybackThread。audio_io_handle_t 在创建 PlaybackThread 时由系统分配,这个值是全局唯一的。


    AudioTrack的moutput初始化 ---(c语言中把output用传址的方式,在里面赋值)
        AudioSystem::getOutputForAttr
        AudioPolicyService::getOutputForAttr
        AudioPolicyManager::getOutputForAttr
        AudioPolicyManager::getOutputForDevice  //根据device打开output,获取实例
        AudioPolicyService::AudioPolicyClient::openOutput
        AudioFlinger::openOutput
        AudioFlinger::openOutput_l

服务端:
启动main_mediaserver.main|main_audioserver.main---AudioFlinger|AudioPolicyService---AudioPolicyService::AudioPolicyClient::openOutput---AudioFlinger::openOutput---PlaybackThread


Audio播放流程

客户端:AudioTrack(.java).play---native_start----android_media_AudioTrack.android_media_AudioTrack_start---AudioTrack(.cpp).start----TrackHandle(服务端的Track代理) 的start(这步跳转逻辑不清楚),最后会调用到服务端Track的start即Tracks文件中的AudioFlinger::PlaybackThread::Track::start---addTrack_l---onAddNewTrack_l---broadcast_l(mWaitWorkCV.broadcast,使用Condition原理)。接着会触发AudioTrack.java.write写数据--
    android_media_AudioTrack.android_media_AudioTrack_write_byte
        releaseBuffer--AudioTrackClientProxy.releaseBuffer


服务端写数据:

参考:

Android O(8.0)音频write数据流程变化(HIDL)

Audio PCM输出流程  "/dev/snd/pcmC%uD%u%c"  
Threads.PlaybackThread::threadLoop---
    threadLoop_mix (混音)
    threadLoop_write(写到音频设备)---NormalSink->write---AudioStreamOutSink.write---StreamOutHalHidl::write---audio_hw(HIDL).out_write---

Audio_outputPath

Android音频流的从PCM到输出的路线。首先,我们的PCM音频数据一般会在用户端,而混音会在AudioFlinger端,因此需要把PCM数据传送给AudioFlinger,因此需要开辟出一块内存用于数据传送;数据到了AudioFlinger之后,可以给PCM数据调节音量,增加音效等(即混音),因此还需要一块内存用于音效处理,这块buffer在getOutput内已经开辟;混音完成后即可把PCM数据输出给音频设备进行播放。

猜你喜欢

转载自blog.csdn.net/lanmengfenghe/article/details/111866398