Android音频架构总结

 

一.音频总体的架构:

 

 

二.Audio Policy

•Stream类型选择合适的device :

•音频管理策略管理音频的输入输出,它决定各种类型的声音优先送往系统哪个输出设备,或使用哪个输入设备进行采样。

•比如,如果有蓝牙耳机或者耳机,将优先使用他们作为输入输出设备。

•创建AudioTrack的时候会传入一个Stream类型,根据这个类型获得strategy,然后根据strategy获得一个device。

 

•Stream类型选择合适的Strategy类型 :

•第一栏是流的类型,第二栏是音频策略

•从表中可以看出,某些流可以使用相同的音频策略进行输入或者输出。

 

•Strategy类型选择合适的device :

•第一栏是Strategy的类型,第二栏是device。

•按照一定的优先级顺序,检查哪些可用的输入输出设备,然后选择一个设备用来输入输出。

 

 

三.Audio使用

•比如音乐播放器,录音机APK进行录音或播放。

•播放声音能够用MediaPlayer和AudioTrack,MediaRecorder和AudioRecord进行录音。

•MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack。AudioTrack再传递给 AudioFlinger进行混音,然后才传递给硬件播放,所以是MediaPlayer包括了AudioTrack。

 

 

四.Audio播放流程

•Android的播放架构图

 

•播放流程一般分为三个部分:

 

1.AudioTrack构造;

•Framework或者APP层通过JNI创建AudioTrack (JAVA)对象;

•调用到android_media_AudioRecord_setup(JNI),然后创建一个AudioRecord(C++);

•AudioRecord(C++)会调用getOutputForAttr,这个函数会调用到AudioPolicy,根据策略选择输出设备;

•AudioTrack(C++)通过binder机制调用AudioFlinger的createTrack()创建Track,同时分配共享内存。

•AudioFlinger拥有多个工作线程,每一个线程拥有多个Track。

•每一个音频流对应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到 AudioFlinger中,由AudioFlinger把所有的AudioTrack进行混合(Mixer),然后输送到AudioHardware中进行播放。

目前Android同时最多可以创建32个音频流,也就是说,Mixer最多会同时处理32个AudioTrack的数据流

2.AudioTrack的Start;

•Framework或者APP层调用AudioTrack(java)的play()进行音频播放的准备;

•play()会调用jni的native_start(),对应的函数是android_media_AudioTrack_start();

•android_media_AudioTrack_start()只是做了转发,最后会调用 AudioTrack(C++)的start();

•AudioTrack的start()进过转发,最后会调用PlaybackThread的start();

•PlaybackThread的start()的又会调用addTrack_l();

•PlaybackTread的addTrack_l主要工作是添加track到mActiveTracks, 并激活沉睡的PlaybackTread线程。

 

3.AudioTrack的Write。

•Framework或者APP层调用AudioTrack(java)的AudioTrack(java)的write()写入音频数据;

•调用jni的android_media_AudioTrack_write_byte(),主要是获取java传下来的数据,并调用writeToTrack()来向共享内存写入数据;

•writeToTrack()调用AudioTrack(c++)的write(),AudioTrack(C++)会使用obtainBuffer获取一块共享内存, 并写入数据,写完后用releaseBuffer释放共享内存。

•服务端读取共享内存的音频数据是在PlaybackThread的threadLoop()中进行的,调用threadLoop_mix()进行混音;

•完成混音后,调用 threadLoop_write(),它会调用mOutput->stream->write()写入,这里会调用到HAL层;

•HAL层的调用tiny_alsa的pcm_open()打开相应的录音设备,再通过pcm_write()写入音频数据到linux系统,再到硬件。

 

四.Audio录音流程

•Android的录音架构图

 

 

1.AudioRecord构造过程:

•Framework或者APP层通过JNI创建AudioRecord (JAVA)对象;

•调用到android_media_AudioRecord_setup(JNI),然后创建一个AudioRecord(C++);

•AudioRecord会通过AudioSystem::getInputForAttr,这个函数会调用到AudioPolicy,根据策略选择输出设备;

•AudioRecord通过binder机制调用AudioFlinger的createRecordTrack_l()创建RecordTrack,同时分配共享内存 。

 

2.AudioRecord的Start :

•Framework或者APP层调用AudioTrack(java)的startRecording()进行音频播放的准备;

•startRecording()会调用jni的native_start(),对应的函数是android_media_AudioRecord_start();

•android_media_AudioRecord_start()只是做了转发,最后会调用 AudioRecord(c++)的start();

•AudioRecord的start又会调用TrackHandle(服务端的Track代理) 的start,最后会调用到RecordThread的start();

•RecordThread的start()会激活沉睡的RecordThread 。

3.AudioRecord的Read :

•Framework或者APP层调用AudioRecord(java)的AudioTrack(java)的read读取音频数据;

•调用jni的android_media_AudioRecord_readInByteArray ,调用AudioTrack(c++)的read读取数据;

•AudioTrack(C++)会使用obtainBuffer获取一块共享内存, 并读取数据;

•服务端读取共享内存的音频数据是在RecordThread的threadLoop()中进行;

•调用 mInput->stream->read读取,这里会调用到HAL层;

•HAL层的调用tiny_alsa的pcm_open打开设备,然后通过pcm_read()读取相应设备数据。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值