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()读取相应设备数据。