1. 车载音频系统架构与开发环境搭建
目标与范围
本案例在 Ubuntu 主机上搭建 Android Automotive 音频开发环境:拉取源码、编译 frameworks/av 音频模块、用 dumpsys media.audio_flinger 与 dumpsys media.audio_policy 观察 AudioFlinger / AudioPolicy 运行状态,并通过一个最小 Audio HAL 桩验证 HAL 接口被正确加载。核心是理解三者职责与调用链,而非完整车机产品编译。
环境与依赖
- Ubuntu 20.04/22.04,内存 ≥16GB,磁盘 ≥250GB
- 依赖:
sudo apt install git curl openjdk-11-jdk python3 repo - Android 源码(Automotive 分支,示例用
android-13.0.0_r)
核心模块职责与交互
App 通过 AudioTrack 写入 PCM;AudioFlinger 负责混音与输出线程;AudioPolicyService 决定路由与设备选择;Audio HAL 把数据交给硬件。三者通过 Binder 与 HAL 接口解耦。
搭建步骤
# 1. 拉取源码(Automotive 分支)
repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r1
repo sync -j8
# 2. 初始化编译环境
source build/envsetup.sh
lunch aosp_car_x86_64-userdebug
# 3. 只编译音频相关模块,加快验证
m -j8 libaudioflinger libaudiopolicyservice libaudiohal
最小 Audio HAL 桩(验证接口被加载)
在 hardware/interfaces/audio/ 下新增一个最小 AIDL HAL 实现,仅实现 getSupportedDevices 返回空列表,用于确认 HAL 被 AudioFlinger 加载。
// hardware/interfaces/audio/aidl/default/AudioStub.cpp
#include <aidl/android/hardware/audio/core/IModule.h>
#include <android/binder_interface_utils.h>
using ::aidl::android::hardware::audio::core::IModule;
using ::ndk::ScopedAStatus;
class AudioStub : public IModule::BnModule {
public:
ScopedAStatus getSupportedDevices(
std::vector<::aidl::android::hardware::audio::core::AudioDevice>* out) override {
out->clear(); // 桩:不声明任何设备
return ScopedAStatus::ok();
}
};
int main() {
auto stub = ndk::SharedRefBase::make<AudioStub>();
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_joinThreadPool();
return 0;
}
运行与验证
# 启动模拟器(Automotive 镜像)
emulator -avd car_api33 -no-snapshot -no-audio
# 观察 AudioFlinger 状态
adb shell dumpsys media.audio_flinger | head -40
# 观察 AudioPolicy 路由
adb shell dumpsys media.audio_policy | grep -A5 "Output devices"
# 确认 HAL 服务注册
adb shell lshal | grep audio
通过条件:dumpsys media.audio_flinger 输出包含 Output thread 与采样率信息;dumpsys media.audio_policy 能列出默认输出设备;lshal 中出现 android.hardware.audio.core.IModule/default。若 HAL 未注册,AudioFlinger 会打印 Failed to load audio HAL,据此定位接口实现或 .rc 注册问题。
常见问题
lunch报错:确认已source build/envsetup.sh且分支与 lunch 目标匹配。- HAL 未加载:检查
Android.bp中cc_binary的init_rc与vintf_fragments是否声明。 - 模拟器无音频:加
-no-audio仅用于验证服务,真实音频需物理设备或带音频后端镜像。