目录
1 APP层
2 JAVA框架层
1.计算满足最小要求的缓冲区大小
2. 分析new AudioTrack
3.分析start函数
4.分析write函数
3 Audio本地API--JNI层
4 c/c++框架层
1 APP层所涉及的代码路径:
录音APK:\packages\apps\SoundRecorder\src\com\android\soundrecorder\*.*
播放APK:\packages\apps\Music\src\com\android\music\*.*
电话APK:\packages\apps\Phone\src\com\android\phone\*.*
所涉及的主要代码:
录音APK:SoundRecorder.java
播放APK:MediaPlaybackService.java
电话APK:PhoneApp.java
APP应用层简略实例一:
我们使用audiotrack 和 audiorecord 来播放和记录声音。
public class TestAudio extends Activity implements OnClickListener{
private AudioRecord m_in_rec;
private AudioTrack m_out_trk;
protected void onCreate(Bundle savedInstanceState) {
init();
record = new Thread(new recordSound());
play = new Thread(new playRecord());
record.start();
play.start();}
private void init(){
m_in_buf_size=AudioRecord.getMinBufferSize(
8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT);
m_in_rec = new AudioRecord(
MediaRecorder.AudioSource.MIC,8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,m_in_buf_size) ;
m_out_buf_size = AudioTrack.getMinBufferSize(
8000,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
m_out_trk = new AudioTrack(
AudioManager.STREAM_MUSIC, 8000,AudioFormat.CHANNEL_CONFIGURATION_MONO
}
APP层应用简略实例二:
应用程序通过调用Audio的JAVA层透露给上层的部分接口:setDataSource(),prepare(),start()等来实现MP3的播放。
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// 得到从activity传来的歌曲URI
String uri = intent.getStringExtra("data");
player = new MediaPlayer();
try {
player.setDataSource(uri);
player.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
player.start();
}
2 JAVA框架层
所涉及的代码路径:
\frameworks\base\media\java\android\media\*.*
所涉及的主要代码:
MediaPlayer.java
MediaRecorder.java
AudioRecord.java
AudioTrack.java
AudioSystem.java
AudioService.java
AudioManager.java
代码路径: \frameworks\base\media\java\android\media
图表 3 Audio JAVA层框架图
与Audio相关的Java包是android.media,主要包含文件:
AudioManager.java:主要负责Audio系统的管理,向下会调用AudioService.java
AudioService.java:主要负责Audio系统的相关服务,向下会调用AudioSystem.java
AudioSystem.java:主要负责Audio系统的总体控制
AudioTrack.java:主要负责Audio系统的输出环节
AudioRecord.java:主要负责Audio系统的输入环节
1.计算满足最小要求的缓冲区大小getMinBufferSize(audiotrack.java)
=>native_get_min_buff_size(audiotrack.java)
=>android_media_AudioTrack_get_min_buff_size(android_media_audiotrack.cpp)
=>getMinFrameCount(audiotrack.cpp)
2. 分析new AudioTrack
AudioTrack(audiotrack.java)
=> native_setup(audiotrack.java)
=>android_media_AudioTrack_native_setup(android_media_audiotrack.cpp)
=> new AudioTrack()(android_media_audiotrack.cpp)
=>set(audiotrack.cpp)
=>createTrack(audiotrack.cpp)
=>audioFlinger->createTrack(audiotrack.cpp)
=> createTrack(audioflinger.cpp)
=> new AudioTrackThread(audiotrack.cpp)
=>AudioTrackThread(audiotrack.cpp)
=>start()(audiotrack.cpp)
=>threadLoop()(audiotrack.cpp)
=>processAudioBuffer(audiotrack.cpp)
=>mCbf(audiotrack.cpp)
=>audioCallback(android_media_audiotrack.cpp)
3.分析start函数
play(audiotrack.java)
=>native_start(audiotrack.java)
=>android_media_AudioTrack_start(android_media_audiotrack.cpp)
=>start(audiotrack.cpp)
4.分析write函数
write(audiotrack.java)
=>native_write_short(audiotrack.java)
=>android_media_AudioTrack_native_write_short(android_media_audiotrack.cpp)
=>android_media_AudioTrack_native_write(android_media_audiotrack.cpp)
=>writeToTrack(android_media_audiotrack.cpp)
=>write(audiotrack.cpp)
=>obtainBuffer(audiotrack.cpp)
=>releaseBuffer(audiotrack.cpp)
通过这一次的分析,我自己觉得有AudioTrack的工作原理,尤其是数据的共享内存,进程的同步等,也能解释不少疑惑了。看起来,最重要的工作是在AudioFlinger中做的。通过给后续深入分析AudioFlinger提供了一个切入点流程嘛,再说一次好了,JAVA层就看最前面那个AudioTrack被new出来,然后set了一堆信息,同时会通过Binder机制调用另外一端的AudioFlinger,得到IAudioTrack对象,通过它和AudioFlinger交互。调用start函数后,会启动一个线程专门做回调处理,代码里边也会有那种数据贝的回调,但是JNI层的回调函数实际并没有往里边写数据,大家只要看write就可以了用户一次可想而知,AudioFlinger那一定有一个线程在memcpy数据到音频设备中去。我们拭目以待。
3 Audio本地API--JNI层所涉及的代码路径:
\frameworks\base\media\jni\*.*
\frameworks\base\core\jni\*.*
所涉及的主要代码:
android_media_MediaPlayer.cpp
android_media_MediaRecorder.cpp
android_media_AudioRecord.cpp
android_media_AudioTrack.cpp
android_media_AudioSystem.cpp
4 c/c++框架层在文件AudioTrack.java中new AudioTrack()
=>在文件android_media_audioTrack.cpp中调用android_media_AudioTrack_native_setup
=>在文件AudioTrack.cpp中调用set函数中存在mAudioTrackThread = new AudioTrackThread
然后分析如何启动AudioTrackThread线程
=>分析AudioTrack.cpp中的AudioTrack::start()函数会调用mAudioTrack->start()
=>实际上会调用AudioTrack.cpp中AudioFlinger::TrackHandle::start()
=>在AudioTrack.cpp中的AudioFlinger::TrackHandle::start()实际上会调用mTrack->start()
=>然后会调用AudioFlinger.cpp中的AudioFlinger::PlaybackThread::Track::start()函数
=>然后分析AudioFlinger::ThreadBase::TrackBase,因为Track继承自TrackBase
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)