Audio系统调用流程

本文详细介绍了Android系统中AudioTrack和AudioRecord的调用流程,包括播放和录制的步骤。Audio系统分为三个进程:Audio客户端、main_mediaserver和servicemanager,涉及AudioFlinger和AudioPolicyService两个服务。通过Binder通信,AudioTrack和AudioRecord与AudioFlinger交互,实现音频的播放和录制。此外,还提到了AudioManager、AudioPlayer和JetPlayer等应用实例。

播放接口:AudioTrack

录制接口:AudioRecord

系统控制接口:AudioSystem

Audio系统框架分为三个进程:Audio客户端、main_mediaserver和servicemanager,两个服务:AudioFlinger和AudioPolicyservice;真正干活的都是在两个服务中。

 

流程介绍

播放流程:

1AudioTrack::AudioTrack-->native_setup-->JNI-->android_media_AudioTrack_native_setup(+native_start)--> {AudioTrack* lpTrack = new AudioTrack()} gAudioFlinger=AudioSystem::get_audio_policy_service-->defaultServiceManager::getService(String16("media.audio_policy"))-->lpTrack->set-->AudioTrack::set-->AudioTrack::createTrack_l-->mAudioTrack=BpaudioFlinger->createTrack--

    续上--BpAudioFlinger::Transact<==Binder==>BnAudioFlinger::onTransact-->AudioFlinger::createTrack-->track = PlaybackThread *thread->createTrack_l-->trackHandle = new TrackHandle(track)[trackHandle返回给binder]-->mTrack=track

      2AudioTrack::play-->native_start-->android_media_AudioTrack_native_start-->AudioTrack::start 

--> BpAudioTrack::Transact<====>BnAudioTrack::onTransact-->TrackHandle::start-->

     <

在Android系统中,`AudioTrack` 是用于播放音频的核心类之一,其 `write()` 方法负责将音频数据写入音频硬件进行播放。理解 `AudioTrack.write()` 调用的流程,需要从 Java 层一直深入到 Native 层,涉及 Binder 通信、本地对象管理以及音频数据的最终写入。 ### AudioTrack.write() 的调用流程 #### Java 层调用 开发者在 Java 层调用 `AudioTrack.write()` 时,通常会传入一个字节数组或缓冲区。该方法是 `AudioTrack` 类的一个 native 方法,用于将音频数据传递到 Native 层进行处理。 ```java int bytesWritten = audioTrack.write(audioData, 0, audioData.length); ``` #### JNI 层调用 Java 层的 `write()` 方法最终调用到 JNI 层的 `android_media_AudioTrack_write` 函数。该函数根据传入的数据类型(byte[]、short[] 或 direct buffer)选择不同的处理路径。 - 如果是 `byte[]`,则调用 `env->GetByteArrayRegion()` 将数据复制到本地缓冲区。 - 如果是 `direct buffer`,则直接获取其地址进行操作。 JNI 层随后调用 Native 层的 `AudioTrack::write()` 方法[^1]。 #### Native 层处理 在 Native 层,`AudioTrack::write()` 方法定义在 `AudioTrack.cpp` 中,路径为 `frameworks/av/media/libaudioclient/AudioTrack.cpp`。该方法主要完成以下任务: 1. **参数验证**:确保传入的缓冲区不为空,且大小合法。 2. **数据写入**: - 如果是 `STREAM` 模式,直接将数据写入底层音频硬件。 - 如果是 `STATIC` 模式,则将数据写入共享缓冲区(shared buffer)供后续播放使用。 3. **同步机制**:处理写入过程中的同步问题,确保多线程环境下数据一致性。 4. **错误处理**:在写入失败时返回相应的错误码。 ```cpp ssize_t AudioTrack::write(const void* buffer, size_t userSize) { if (mSharedBuffer == 0) { // Stream mode: write data directly to the audio hardware return mAudioTrack->write(buffer, userSize); } else { // Static buffer mode: copy data into shared buffer memcpy(mSharedBuffer->pointer(), buffer, userSize); return userSize; } } ``` #### 音频硬件交互 最终,`mAudioTrack->write()` 调用的是 `IAudioTrack` 接口的实现,该接口通过 Binder 机制与 `AudioFlinger` 服务通信。`AudioFlinger` 是 Android 音频系统的核心服务,负责音频数据的混音、路由和硬件访问。 在 `AudioFlinger` 中,音频数据最终被写入到音频硬件抽象层(HAL),由 HAL 负责实际的音频播放。 ### 实现步骤总结 1. **Java 层调用**:`AudioTrack.write()` 方法被调用。 2. **JNI 层处理**:调用本地函数,将数据从 Java 层复制到 Native 层。 3. **Native 层执行**: - 验证参数。 - 根据模式(`STREAM` 或 `STATIC`)决定数据写入方式。 - 调用底层 `IAudioTrack` 的 `write()` 方法。 4. **Binder 通信**:与 `AudioFlinger` 服务进行交互。 5. **音频播放**:`AudioFlinger` 将数据传递给音频 HAL,最终播放音频。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值