Android 音频系统(三)之 AudioTrack实例
接着前面的《Android 音频系统(二)之 AudioFlinger》
4. AudioTrack 实例创建
现在我们开始分析 AudioTrack 的创建过程,
特别留意 AudioTrack 与 AudioFlinger 如何建立联系、用于 AudioTrack 与 AudioFlinger 交换数据的匿名共享内存如何分配。
4.1. AudioTrack & AudioFlinger 相关类
首先看一下 AudioTrack & AudioFlinger 的类图,理一下 AudioFlinger 的主要类及其关系、AudioTrack 与 AudioFlinger 之间的联系,后面将以该图为脉络展开分析。
-
AudioFlinger::PlaybackThread:回放线程基类,
不同输出标识的音频流对应不同类型的 PlaybackThread 实例
(分为四种:MixerThread、DirectOutputThread、DuplicatingThread、OffloadThread),
具体见 3.4. AudioFlinger 回放录制线程 小节,所有的 PlaybackThread 实例都会添加到 AudioFlinger.mPlaybackThreads 向量中;
这个向量的定义:
DefaultKeyedVector< audio_io_handle_t, sp > mPlaybackThreads;,
可见 audio_io_handle_t 是与 PlaybackThread 是一一对应的,
由已知的 audio_io_handle_t 就能找到对应的 PlaybackThread;
audio_io_handle_t 在创建 PlaybackThread 时由系统分配,这个值是全局唯一的 -
AudioFlinger::PlaybackThread::Track:音频流管理类
创建一块匿名共享内存用于 AudioTrack 与 AudioFlinger 之间的数据交换(方便起见,这块匿名共享内存,以后均简单称为 FIFO),
同时实现 start()、stop()、pause() 等音频流常用控制手段;注意,多个 Track 对象可能都注册到同一个 PlaybackThread 中(尤其对于 MixerThread 而言,一个 MixerThread 往往挂着多个 Track 对象),这多个 Track 对象都会添加到 PlaybackThread.mTracks 向量中统一管理
-
AudioFlinger::TrackHandle:Track 对象只负责音频流管理业务
对外并没有提供跨进程的 Binder 调用接口,而应用进程又需要对音频流进行控制,所以需要一个对象来代理 Track 的跨进程通讯,这个角色就是 TrackHandle,AudioTrack 通过它与 Track 交互 -
AudioTrack:Android 音频系统对外提供的一个 API 类,负责音频流数据输出
每个音频流对应着一个 AudioTrack 实例,不同输出标识的 AudioTrack 会匹配到不同的 AudioFlinger::PlaybackThread;
AudioTrack 与 AudioFlinger::PlaybackThread 之间通过 FIFO 来交换音频数据,AudioTrack 是 FIFO 生产者,AudioFlinger::PlaybackThread 是 FIFO 消费者 -
AudioTrack::AudioTrackThread:
数据传输模式为 TRANSFER_CALLBACK 时,需要创建该线程
它通过调用 audioCallback 回调函数主动从用户进程处索取数据并填充到 FIFO 上;数据传输模式为 TRANSFER_SYNC 时,则不需要创建这个线程,因为用户进程会持续调用 AudioTrack.write() 填充数据到 FIFO;
数据传输模式为 TRANSFER_SHARED 时,也不需要创建这个线程,因为用户进程会创建一块匿名共享内存,并把要播放的音频数据一次性拷贝到这块匿名共享内存上了
-
IAudioTrack:IAudioTrack 是链结 AudioTrack 与 AudioFlinger 的桥梁
它在 AudioTrack 端的对象是 BpAudioTrack,在 AudioFlinger 端的对象是 BnAudioTrack,从图中不难看出,AudioFlinger::TrackHandle 继承自 BnAudioTrack,
而 AudioFlinger::TrackHandle 恰恰是AudioFlinger::PlaybackThread::Track 的代理对象,所以 AudioTrack 得到 IAudioTrack 实例后,就可以调用 IAudioTrack 的接口与 AudioFlinger::PlaybackThread::Track 交互
本文学习自: https://blog.****.net/zyuanyun/article/details/60890534