Android P的音频架构(一)

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

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
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值