Android P的音频架构
音频架构图
谷歌官网:https://source.android.com/devices/audio
在谷歌官网介绍的音频架构中,我们可以看到下面的架构图:

android p音频处理流程
通过用AudioTrack来播放pcm格式音乐的流程,来讲解整个音频架构处理的流程。
android p音频播放从app开始,在framework层创建播放器,在audio library层做音频流和输出流控制,在Hal层将音频数据写入到输出设备进行声音输出。其中audio library层是音频处理的核心。
App --> Frameworks --> Audio Library --> HAL
一、App层
上层应用,包括各种音乐播放器,语音播报等声音输出软件。在app层,应用播放不同的音频文件。播放音频文件主要有两种方式,MediaPlayer和AudioTrack,这两者都提供了Java API供应用开发者使用,虽然都可以播放音频,但他们还是有区别:
1.MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。MediaPlayer会在framework层创建对应的音频解码器。
2.AudioTrack只能播放已经解码的PCM流,如果对比支持的文件格式的话则是AudioTrack只支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,所以只能播放不需要解码的wav文件。
3.MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,AudioTrack再传递给AudioFlinger进行混音,然后才传递给硬件播放,所以是MediaPlayer包含了AudioTrack。
总结:MediaPlayer 更加适合在后台长时间播放本地音乐文件或者在线的流式资源;AudioTrack 则更接近底层,提供了非常强大的控制能力,支持低延迟播放,适合流媒体和VoIP语音电话等场景。
本文主要讲解使用AudioTrack播放pcm或者wav格式音频文件:
// 一个使用AudioTrack播放音频的简单例子
public class MainActivity extends Activity {
private Button mPlayBtn; //播放按钮
private Button mPauseBtn; //暂停按钮
private byte[] mAudioData; //音频数据
private AudioTrack mAudioTrack; //AudioTrack对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlayBtn = findViewById(R.id.play);
mPauseBtn = findViewById(R.id.pause);
mPlayBtn.setEnabled(false);
//按下播放按钮后做的处理
mPlayBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPlayBtn.setEnabled(false);
if(mAudioTrack != null){
mAudioTrack.play();
}else{
// android p之前的版本初始化AudioTrack的方式,在android p中遗弃了该方式,但是兼容这种写法。
// mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,mAudioData.length, AudioTrack.MODE_STATIC);
// android p初始化AudioTrack的方式
/* 音频参数(音频参数如果跟音频文件参数不一致,声音播放会出现异常):
* streamType:音频流类型 AudioManager.STREAM_MUSIC,音乐(不同的声音分类为不同的音频流类型)
* encoding:位宽 AudioFormat.ENCODING_PCM_16BIT,16bit音频文件
* sampleRate:采样率 8000,8k的音频文件
* channelMask:通道数 AudioFormat.CHANNEL_OUT_MONO,单声道
*/
AudioAttributes.Builder attr = (new AudioAttributes.Builder())
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.setUsage(AudioAttributes.USAGE_MEDIA);
AudioFormat.Builder format = (new AudioFormat.Builder())
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(8000)
.setChannelMask( AudioFormat.CHANNEL_OUT_MONO);
/* AudioTrack 创建模式mode
* AudioTrack.MODE_STATIC:播放音频前一次性将全部的音频数据从java传递到native层
* AudioTrack.MODE_STREAM:播放音频时将音频数据用数据流的方式从java传递到native层
*/
mAudioTrack = new AudioTrack(attr.build(), format.build(), mAudioData.length, AudioTrack.MODE_STATIC

本文深入剖析了AndroidP的音频架构,从应用层(App)、框架层(Frameworks)、音频库层(AudioLibrary)到硬件抽象层(HAL),详细讲解了音频处理流程,特别是AudioTrack与AudioFlinger的交互原理及其在不同层的实现。
最低0.47元/天 解锁文章
1889





