Android Audio:AudioTrack构造函数分析

Android Audio:AudioTrack构造函数分析,第1张

概述分析AudioTrack之前先分析一下AudioTrack和MediaPlayer的区别:AudioTrack只能播放pcm原始数据,不能播放视频。MediaPlayer可以播放视频和音频。AudioTrack只支持pcm原始音频数据。MediaPlayer支持mp3,wav,aac…MediaPlayer在底层会创建指定的格式的 分析AudioTrack之前先分析一下AudioTrack和MediaPlayer的区别:

AudioTrack 只能播放 pcm 原始数据,不能播放视频。

MediaPlayer 可以播放视频和音频。

AudioTrack 只支持 pcm 原始音频数据。

MediaPlayer 支持 mp3,wav,aac…

MediaPlayer 在底层会创建指定的格式的解码器,将音频数据转化为 pcm 然后再交给 pcm
去播放。MediaPlayer底层会创建 AudioTrack,将解码后的数据交给 AudioTrack 播放。

每一个音频流对应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到
audioflinger中,由audioflinger把所有的AudioTrack进行混合(mixer),然后输送到AudioHarDWare中进行播放,目前AndroID同时最多可以创建32个音频流,也就是说,mixer最多会同时处理32个AudioTrack的数据流。

个人感觉AudioTrack梳理起来的过程是非常痛苦的,中间可能也有很多问题,参考了很多博客,还有实习师傅的指导,整理一篇AndroID P的AudioTrack流程初文出来,以后工作用的多了熟悉了,再修改。AudioTrack的构造函数分析:

androID\frameworks\base\media\java\androID\media\AudioTrack.java

走private的构造函数。


获取主线程的Looper,异步消息通信的机制。


获取采样率,声道掩码,编码类型,然后验证参数是否合法


调用native层的native_setup


native_setup()


androID\frameworks\base\core\jni\androID_media_AudioTrack.cpp


进入JNI层


创建native层的AudioTrack。


androID\frameworks\av\media\libaudioclIEnt\AudioTrack.cpp

进到lib层,通过set()方法将参数设置进去


status_t AudioTrack::set()


创建IAudioTrack.


获取音频策略服务。


frameworks\av\media\libaudioclIEnt\AudioSystem.cpp
通过binder机制绑定服务。


androID\frameworks\av\media\libaudioclIEnt\AudioTrack.cpp
进入audioflinger


androID\frameworks\av\services\audioflinger\audioflinger.cpp


依据播放线程ID号查找出相应的PlaybackThread,依据客户端进程pID查找是否已经为该客户进程创建了ClIEnt对象。假设没有,则创建一个ClIEnt对象。


依据进程pID。为请求播放音频的clIEnt创建一个ClIEnt对象。


audioflinger的成员变量mClIEnts以键值对的形式保存pID和ClIEnt对象。这里首先取出pID相应的ClIEnt对象,假设该对象为空。则为clIEnt进程创建一个新的ClIEnt对象。MemoryDealer是个工具类。用于分配共享内存。每个ClIEnt都拥有一个MemoryDealer对象,这就意味着每个clIEnt进程都是在自己独有的内存空间中分配共享内存。


创建了如同所示的内存大小。


返回继续看audioflinger::createTrack()


frameworks\av\services\audioflinger\Threads.cpp
创建Track对象


前面进行一系列的参数赋值,最后返回一个track对象。


进入Track的构造函数,由图可见,继承于TrackBase,因此先进入TrackBase的构造函数进行分析。


TrackBase()
thread,所属播放线程,clIEnt所属的客户端,sampleRate,采样率,format音频格式,channelMask,声道,frameCount,音频帧个数。sharedBuffer,共享内存。


得到应用进程ID


计算存放音频的buffer大小。


ClIEnt不为空。就通过ClIEnt来分配buffer,为空,则通过mallc动态分配。


由此可见,TrackBase构造过程主要是为音频播放分配共享内存。
接着进入Track的构造函数进行分析。

为0创建AudioTrackServerProxy代理对象,不为0,创建StaticAudioTrackServerProxy代理对象;


接下来我们返回audioflinger的createTrack函数中,来看这个track对象到底做了什么事情。

androID\frameworks\av\services\audioflinger\audioflinger.cpp

创建Track的binder对象TrackHandle,Track由于需要通过binder返回给AudioTrack,因此是个binder对象,该对象会包含share buffer的信息。由于share buffer不止会在audioflinger这端被读取,还会在AudioTrack这端被写入,因此创建出来的Track需要被传送回AudioTrack。而在binder间传送对象只有binder对象,因此需要构建binder对象TrackHandle,返回给AudioTrack。


frameworks\av\services\audioflinger\Tracks.cpp
至此,createTrack_l在audioflinger这端的工作基本完成了。

ps:这里我绕的不太清楚:可参考其他博客:[Android] createTrack_l

frameworks\av\media\libaudioclIEnt\AudioTrack.cpp

返回AudioTrack.cpp中的creatTrack中。


构造函数暂时分析至此。

点赞1收藏分享文章举报

猫鸷发布了38 篇原创文章 · 获赞 12 · 访问量 1万+私信 关注 总结

以上是内存溢出为你收集整理的Android Audio:AudioTrack构造函数分析全部内容,希望文章能够帮你解决Android Audio:AudioTrack构造函数分析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1067310.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存