Android Audio系统变化都有哪些

发布时间:2021-11-26 10:37:12 作者:柒染
来源:亿速云 阅读:265

今天就跟大家聊聊有关Android  Audio系统变化都有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

先从Java层AudioTrack类说起

一 AudioTrack Java类变化说明

二 AudioTrack JNI层变化说明

这一层包括JNI层和AudioTrack本身

typedef enum {

AUDIO_OUTPUT_FLAG_NONE = 0x0, // no attributes

AUDIO_OUTPUT_FLAG_DIRECT = 0x1, // this output directly connects a track

// to one output stream: no software mixer

AUDIO_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of

// the device. It is unique and must be

// present. It is opened by default and

// receives routing, audio mode and volume

// controls related to voice calls.

AUDIO_OUTPUT_FLAG_FAST = 0x4, // output supports "fast tracks", 《==什么叫fast track?太难理解了!目前,java层的audiotrack只会使用第一个标志。

// defined elsewhere

AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8 // use deep audio buffers 《==deep buffer是个什么玩意?这个马赛克是不是太大了点?现在完全看不清楚啊??!

} audio_output_flags_t;

OK,上面有好几个马赛克,平常看看日本大片的时候也就撸过去了,但分析Audio可不行。把去马赛克的希望寄托在下一步AudioFlinger的分析上吧!

三 AudioFlinger变化说明

我们将根据AF工作的主要流程来介绍下变化情况:

3.1 AF创建和onFirstRef

恩,没什么太大变化。有三个点:

3.2 openOutput函数

openOutput  函数比较关键,其中会见到以前的老朋友MixerThread,AudioStreamOutput等。整个流程包括加载Audio相关的硬件so。这部  分工作在4.0的时候就有了,谈不上太多的变化。但物是人非,老朋友已经发生巨大变化了。先来看MixerThread家族。

Android  Audio系统变化都有哪些

图1 PlaybackThread家族

图1稍加解释:

再来看ThreadBase的一个重要子类PlaybackThread,这个类应该是做过大整容了。

接下来看图2。

Android  Audio系统变化都有哪些

图2 MixerThread和它的弟兄们

图2,简单介绍一下:

以上的内容已经比较复杂了,下面来介绍下MixerThread对象创建中碰到的其他内容:

3.3 MixerThread创建

通  过图1和图2,应该对AF的几个主要成员有了认识。可惜啊,上面MixerThread中还有一个mOutputSink成员,没看到吧?它就和我们前面  提到的NBAIO(Non-block Audio I/O   )有重大关系。NBAIO的存在,是为了想实现非阻塞的音频输入输出操作。下面是这个类的注释:

NBAIO注释:

// This header file has the abstract interfaces only. Concrete implementation classes are declared

// elsewhere. Implementations _should_ be non-blocking for all methods, especially read() and

// write(), but this is not enforced. In general, implementations do not need to be multi-thread

// safe, and any exceptions are noted in the particular implementation.

NBAIO只是定义了一个接口,需要去实现具体的实现类。当然,它要求read/write函数是非阻塞的,真实实现到底是不是阻塞,由实现者去控制。

个人感觉这部分框架还没有完全成熟,但NBIO的引入,需要同学们小心,相对而言,难度也比较大。下面我们通过图3来看看NBAIO的一些内容。

Android  Audio系统变化都有哪些

图3 NBAIO相关内容

图3解释如下:

switch (kUseFastMixer) { //kUseFastMixer用于控制FastMixer的使用情况,一共4种:

case FastMixer_Never: //永远不使用FastMixer,这个选项用于调试,即关闭FastMixer的情况

case FastMixer_Dynamic: //根据情况,动态使用。根据注释,这个功能似乎还没有完全实现好

mNormalSink = mOutputSink;

break;

case FastMixer_Always: //永远使用FastMixer,调试用

mNormalSink = mPipeSink;

break;

case FastMixer_Static://静态。默认就是这个。但具体是否使用mPipeSink,将收到initFastMixer的控制

mNormalSink = initFastMixer ? mPipeSink : mOutputSink;

break;

}

由上所述,kUseFastMixer默认是FastMixer_Static,但mNormalSink是否指向mPipeSink,还由initFastMixer控制。这个变量本身又有mFrameCount和

mNormalFrameCount的大小决定,只有mFrameCount小于mNormalFrameCount时,initFastMixer才为真。晕了....这两个frameCount由PlaybackThread的

readOutputParameters得到。请同学们自己研究这段代码吧,就是一些简单的计算。想要搞明白的话,最好带着参数进去,把值都算出来。

好了,MixerThread的创建就分析到此,最好还是把这段代码多研究研究。了解几个兄弟对象是做什么的....

3.4 createTrack和start说明

createTrack  中最大的变化就是新增了对MediaSyncEvent同步机制的处理。MediaSyncEvent的目的很简单,其Java   API的解释如下:startRecording(MediaSyncEvent) is used to start capture only   when the playback on a particular audio session is complete. The audio   session ID is retrieved from a player (e.g MediaPlayer, AudioTrack or   ToneGenerator) by use of the getAudioSessionId() method.   简单点讲,就是必须等上一个player工作完毕了,才能开始下一个播放或者录制。这个机制解决了Android长久以来的声音经常混着出来的问题(目前  一个恶心但却实效的方法就是加一个sleep,以错开多个player不同步的问题。)。注意,iPhone上就没有这个问题。

另外,这个机制的潜在好处就是解放了做AudioPolicy AudioRoute工作的同学们,似乎(个人感觉是可以解决这个问题的)可以不用再去琢磨到底sleep多少时间,在哪加sleep的问题了

在AF中,MediaSyncEvent机制的代表是SyncEvent。大家自己看看就好。

start函数的变化不大,其中加了对SyncEvent的处理。

另外,createTrack中还涉及到FastMixer和TimedTrack处理。核心在PlaybackThread的createTrack_l和Track构造函数中。尤其是和FastMixer的关系。

根据图2,FM(FastMixer简写)内部用得数据结构是FastTrack,而MT用得是Track,所以这里存在一一对应的关系。FM的FastTrack是保存在数组中的,所以

使用FM的Track将通过mFastIndex来指向这个FastTrack。

现在搞清楚FastTrack和Track之间的关系即可,后续的数据流动还需要详细讨论

下面来看看MixerThread的工作流程。这部分是重头戏!

3.5 MixerThread的工作流程

这部分难的还是在FastMixer的工作原理上。不过这里提前和大家说:目前这个功能还没有做完,代码里边一堆的FIXME...。但屌丝们不要happy太早了,

估计马上、很快、必须得下个版本就好了。现在看看这个不成熟的东西,可以缓解以后看到成熟的东西的心理压力。

MT是一个线程,其工作内容主要在threadLoop中完成,而这个函数是由其基类PlaybackThread定义的,大体变化如下:

另外,DulicatingThread,DirectOuptutThread没有太大变化。

四 FastMixer工作原理简单说明

我以前想得是:混音工作由FastMixer线程和MixerThread线程共同完成,但输出工作依然在MixerThread做。从上面MonoPipe的分析来看,这个判断可能不准。

既  有可能是输出工作也交给FastMixer来做,而MixerThread仅做一部分混音工作,然后把数据通过MonoPipe传给FastMixer线  程。FastMixer线程将自己的FastTrack的混音结果和MT的混音结果再做一次混音,然后再由FastMixer输出。

FM定义在FastMixer.cpp中,核心就是一个ThreadLoop。由于AF所有Track的预备工作由MT线程来做,所以FM的threadLoop基本上就是根据状态来做对应处理。

这 里的同步使用了LINUX中很底层的futex(Fast Userspace Mutex)。晕,futex是POSIX   Mutex的实现基础。不知道写这段代码的人为何不直接用Mutex(估计还是嫌效率的问题,但是   妈的,用了Mutex效率能差多少?代码是写给人看的,太B4我们了...)。玩多线程玩到这种地步,佩服啊!不懂多线程编程的屌丝们,请仔细研究  Posix MultiThread Programming吧

这里是FM的简单说明,详细内容,没有拿个真机给我,我也没法整啊....欢迎乐善好施的兄弟们刷个4.1的机器,然后借给我研究下...

(这玩意,个人感觉也不是太难。东西嘛,耐不住琢磨,总能搞透的)。兄弟们今天知道FM和MT的大体工作流程就可以了。

五 其他变化

其他变化包括:

六 总结

我记得在研究2.2 AF的时候,AudioFlinger才3k多行,而JB已经有9K多行了。还没算其他的辅助类。从整体上看,JB变化趋势为:

看完上述内容,你们对Android  Audio系统变化都有哪些有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

推荐阅读:
  1. 【音视频】Android CallLib 开发指南
  2. android声音服务

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android audio

上一篇:css如何设置链接不显示鼠标小手

下一篇:C#如何实现基于Socket套接字的网络通信封装

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》