专业治疗白癜风医院 http://pf.39.net/bdfyy/bjzkbdfyy/190501/7107858.htmlAndroid音频框架概述
Audio是整个Android平台非常重要的一个组成部分,负责音频数据的采集和输出、音频流的控制、音频设备的管理、音量调节等,主要包括如下部分:
AudioApplicationFramework:音频应用框架
AudioTrack:负责回放数据的输出,属Android应用框架API类
AudioRecord:负责录音数据的采集,属Android应用框架API类
AudioSystem:负责音频事务的综合管理,属Android应用框架API类
AudioNativeFramework:音频本地框架
AudioTrack:负责回放数据的输出,属Android本地框架API类
AudioRecord:负责录音数据的采集,属Android本地框架API类
AudioSystem:负责音频事务的综合管理,属Android本地框架API类
AudioServices:音频服务
AudioPolicyService:音频策略的制定者,负责音频设备切换的策略抉择、音量调节策略等
AudioFlinger:音频策略的执行者,负责输入输出流设备的管理及音频流数据的处理传输
AudioHAL:音频硬件抽象层,负责与音频硬件设备的交互,由AudioFlinger直接调用
与Audio强相关的有MultiMedia,MultiMedia负责音视频的编解码,MultiMedia将解码后的数据通过AudioTrack输出,而AudioRecord采集的录音数据交由MultiMedia进行编码。
本文分析基于Android7.0-Nougat。
AudioTrackAPI概述播放声音可以使用MediaPlayer和AudioTrack,两者都提供JavaAPI给应用开发者使用。两者的差别在于:MediaPlayer可以播放多种格式的音源,如mp3、flac、wma、ogg、wav等,而AudioTrack只能播放解码后的PCM数据流。从上面Android音频系统架构图来看:MediaPlayer在Native层会创建对应的音频解码器和一个AudioTrack,解码后的数据交由AudioTrack输出。所以MediaPlayer的应用场景更广,一般情况下使用它也更方便;只有一些对声音时延要求非常苛刻的应用场景才需要用到AudioTrack。
AudioTrackJavaAPIAudioTrackJavaAPI音频流类型:
Android为什么要定义这么多的流类型?这与Android的音频管理策略有关,例如:
音频流的音量管理,调节一个类型的音频流音量,不会影响到其他类型的音频流
根据流类型选择合适的输出设备;比如插着有线耳机期间,音乐声(STREAM_MUSIC)只会输出到有线耳机,而铃声(STREAM_RING)会同时输出到有线耳机和外放
这些属于AudioPolicyService的内容,本文不展开分析了。应用开发者应该根据应用场景选择相应的流类型,以便系统为这道流选择合适的输出设备。
一个AudioTrackJavaAPI的测试例子(MODE_STREAM模式):
详细说明下getMinBufferSize()接口,字面意思是返回最小数据缓冲区的大小,它是声音能正常播放的最低保障,从函数参数来看,返回值取决于采样率、采样深度、声道数这三个属性。MODE_STREAM模式下,应用程序重点参考其返回值然后确定分配多大的数据缓冲区。如果数据缓冲区分配得过小,那么播放声音会频繁遭遇underrun,underrun是指生产者(AudioTrack)提供数据的速度跟不上消费者(AudioFlinger::PlaybackThread)消耗数据的速度,反映到现实的后果就是声音断续卡顿,严重影响听觉体验。
可见最小缓冲区的大小=最低帧数声道数采样深度,(采样深度以字节为单位),到这里大家应该有所明悟了吧,在视频中,如果帧数过低,那么画面会有卡顿感,对于音频,道理也是一样的。最低帧数如何求得,我们到native层再解释。
关于MediaPlayer、AudioTrack,更多更详细的API接口说明请参考AndroidDeveloper:
MediaPlayer: