本文梳理了 Android 原生音频架构的核心问题,并给出具体改进方案和实现代码。
一、Android 原生音频架构
1.1 整体架构一览
Android 音频系统从顶层 App 到硬件,大致分为四层:
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (App Layer) │
│ AudioTrack / AudioRecord / MediaPlayer │
└────────────────────────────┬────────────────────────────────┘
│ Java API (AudioTrack.write())
┌────────────────────────────▼────────────────────────────────┐
│ 框架层 (Framework Layer) │
│ ┌──────────────────┐ ┌───────────────────────────┐ │
│ │ AudioFlinger │ ←→ │ AudioPolicyService │ │
│ │ (播放/混音/调度) │ │ (路由/音频策略/设备管理) │ │
│ └──────────────────┘ └───────────────────────────┘ │
│ ↑ ↑ │
│ ┌─────────┴────────────────────────┴────────┐ │
│ │ Native Layer │ │
│ │ AudioTrack / AudioRecord / AudioEffect │ │
│ └─────────────────────┬─────────────────────┘ │
└────────────────────────────┼────────────────────────────────┘
│ Binder IPC
┌────────────────────────────▼────────────────────────────────┐
│ Audio HAL Layer │
│ (IAudioFlinger.hal / IAudioPolicy.hal / IEffect.hal) │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────┐
│ 音频硬件 │
│ DAC / DSP / I2S / 扬声器 / 蓝牙 A2DP │
└─────────────────────────────────────────────────────────────┘
每一层都通过 HIDL/AIDL HAL 接口解耦,厂商只需实现 HAL,无需改动上层。
1.2 AudioFlinger vs AudioPolicyService
很多人搞不清楚这两个服务的关系:
AudioFlinger:负责"怎么播放" → 管理 PlaybackThread 和 RecordThread → 实际的混音、调度、共享内存管理 → 把混音后的数据写入 HAL AudioPolicyService:负责"能不能播放"和"播到哪里" → 设备选型(speaker/headset/bt) → 路由策略(插耳机切输出源) → Audio Focus 管理(谁打断谁) → 音量管理(不同 Zone 的音量曲线)
1.3 关键音频路径
媒体播放路径:
MediaPlayer.decode()
→ AudioTrack.write() [44.1kHz PCM]
→ AudioFlinger
→ PlaybackThread
→ 重采样 → [48kHz]
→ 混音
→ Output Effects → [均衡器/低音增强]
→ HAL.open_output_stream()
→ DAC → 扬声器
导航播报路径:
NavigationApp
→ AudioTrack.write() [低延迟,FLAG_AUDIBILITY_ENFORCED]
→ AudioFlinger
→ PlaybackThread (高优先级)
→ 高优先级 Track 抢占 Mixer
→ 直接输出 → [压低媒体音量]
→ HAL → 扬声器
1.4 原架构的核心问题
| 问题 | 描述 |
|——|——|
| 单点瓶颈 | 所有 Track 共用一个 MixerThread,高优先级抢占时低优先级被连带影响 |
| Focus 粒度粗 | 只有 4 种状态,无法精细控制 Duck Level 和恢复时间 |
| 无 Zone 支持 | 标准 Android 无多区域音频概念,车载需要 CarAudioService 在上层模拟 |
| HAL 碎片化 | 不同厂商 HAL 性能差异大,延迟不可预期 |
| Effects 局限 | 第三方 App 无法 attach Effect 到自己的 Track |
二、改进后的音频架构
2.1 新架构全景
┌─────────────────────────────────────────────────────────────────┐
│ 应用层 (App Layer) │
│ AudioTrack / AudioRecord / MediaPlayer │
└─────────────────────────────┬─────────────────────────────────┘
│ Java/Native API
┌─────────────────────────────▼─────────────────────────────────┐
│ 框架层 (Framework Layer) │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ AudioFlinger │ ←→ │ AudioPolicyService │ │
│ │ + PriorityGroup│ │ + ExtendedAudioFocus │ │
│ │ + AudioZone │ │ + ZoneManager │ │
│ └────────┬─────────┘ └──────────────────────────────┘ │
│ │ │
│ ┌────────┴──────────────────────────────────┐ │
│ │ PriorityPlaybackThread │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────┐│ │
│ │ │CRITICAL │ │IMPORTANT│ │ NORMAL │ │BG ││ │
│ │ │ Group │ │ Group │ │ Group │ │Group││ │
│ │ │(ADAS) │ │(Nav) │ │(Media) │ │(Notif)│ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┘│ │
│ │ └───────────┼───────────┼─────────────┘ │
│ │ ↓ ↓ │
│ │ ┌────────────┐ │
│ │ │ FinalMixer │ ← 各 Group 汇总 │
│ │ └─────┬──────┘ │
│ │ ↓ │
│ │ ┌────────────┐ ┌─────────────┐ │
│ │ │ZoneEffects │ ←→ │TrackEffects │ │
│ │ └─────┬──────┘ └─────────────┘ │
│ └───────────────────┼────────────────────────────────────────────┘
│ ↓
┌─────────────────────────▼────────────────────────────────────────┐
│ Audio HAL Layer │
│ ┌──────────────────────┐ ┌──────────────────────────────┐ │
│ │ StreamOut + Performance │ │ IStreamOutPerformanceExt │ │
│ │ (带 PerformanceClass) │ │ (新增性能等级查询接口) │ │
│ └──────────────────────┘ └──────────────────────────────┘ │
└──────────────────────────────┼─────────────────────────────────────┘
↓
音频硬件 (带性能等级标注)
2.2 Priority Group 分组混音机制
原架构:所有 Track → [单 Mixer] → HAL
↓ 问题:高优先级抢占时低优先级被连带影响
改进后:Track → [PriorityGroup 分类] → [各自独立 Mixer] → [FinalMixer] → HAL
↓ 优势:高优先级独立混音,不影响低优先级调度
PriorityPlaybackThread 内部流程: ① 高优先级 Track 写数据 ↓ ② CRITICAL Group 独立混音(5ms buffer,无 Effects bypass) ↓ ③ IMPORTANT Group 独立混音(10ms buffer) ↓ ④ NORMAL Group 混音(20ms buffer) ↓ ⑤ BACKGROUND Group 混音(50ms buffer,Duck 时降到 10%) ↓ ⑥ FinalMixer 汇总所有 Group 输出 ↓ ⑦ Zone Effects 处理 ↓ ⑧ 写入 HAL
2.3 AudioZone 多区域原生支持
原架构:无 Zone 概念,所有输出共享单音量控制
改进后:AudioZone 原生支持,每个 Zone 独立运行
AudioZoneManager ──┬── Zone[DRIVER] { PriorityGroups + Focus }
├── Zone[FRONT_PASSENGER] { ... }
├── Zone[REAR_LEFT] { ... }
├── Zone[REAR_RIGHT] { ... }
└── Zone[CENTER] { 导航/ADAS 语音 }
Zone 间隔离:
- 驾驶座导航播报 → 只在 DRIVER Zone 内打断媒体
- 后排音乐 → 不受驾驶座 Focus 变化影响
- Center Zone 的 ADAS 警示音 → 可配置是否压低其他 Zone
2.4 改进后的 AudioFocus 流程
原流程:
App 请求 Focus → 返回 GAIN/LOSS → 固定行为
改进后流程:
App 请求 Focus → ExtendedAudioFocus → 返回精细化 FocusInfo
├── duckLevel: 0.0~1.0
├── resumeDelayMs: 0~5000
├── affectedUsages: [...]
└── zoneId: 隔离 Zone
Focus 变化回调:
GAIN → 正常播放
LOSS_TRANSIENT → pause() 等 resumeDelayMs 后自动恢复
LOSS_TRANSIENT_MAY_DUCK → volume = duckLevel (可配置 30%)
LOSS → pause()
2.5 HAL Performance Class 选择路径
AudioFlinger 查询 HAL PerformanceClass: ┌─────────────────┐ │ PERFORMANCE_A │ → FastMixer 直连(< 20ms) │ (延迟 < 20ms) │ 适用于:ADAS 警示、卡拉OK、实时监听 └─────────────────┘ ┌─────────────────┐ │ PERFORMANCE_B │ → 标准路径 + 优化(< 50ms) │ (延迟 < 50ms) │ 适用于:导航播报、游戏音效 └─────────────────┘ ┌─────────────────┐ │ PERFORMANCE_C │ → 大 Buffer 稳定(< 100ms) │ (延迟 < 100ms) │ 适用于:后台音乐、通知音 └─────────────────┘ ┌─────────────────┐ │ UNSPECIFIED │ → 按最坏情况处理(加额外缓冲) └─────────────────┘
三、改进方案与代码实现
1. Priority Group 分组混音
// PriorityGroup.h
enum audio_priority_group_t : int32_t {
PRIORITY_GROUP_CRITICAL = 0, // ADAS 警示音,FLAG_AUDIBILITY_ENFORCED
PRIORITY_GROUP_IMPORTANT = 1, // 导航播报、语音通话
PRIORITY_GROUP_NORMAL = 2, // 媒体播放、游戏音效
PRIORITY_GROUP_BACKGROUND = 3, // 通知音、Touch Sound
};
struct PriorityGroupConfig {
audio_priority_group_t groupId;
size_t maxTracks;
uint32_t bufferSizeMs; // CRITICAL 用小 buffer 低延迟
int32_t resamplerQuality;
bool effectsBypass; // CRITICAL 通常 bypass Effects
};
// 默认配置
PriorityGroupConfig::defaultConfigs[PRIORITY_GROUP_COUNT] = {
{ CRITICAL, 8, 5ms, HIGH, true }, // 5ms,无 Effects
{ IMPORTANT, 16, 10ms, MEDIUM, false },
{ NORMAL, 32, 20ms, MEDIUM, false },
{ BACKGROUND,16, 50ms, LOW, true }, // 大 buffer 稳定
};
// PriorityPlaybackThread.cpp — 核心混音逻辑
bool PriorityPlaybackThread::threadLoop() {
// Phase 1: 按 Group 独立混音
memset(mFinalMixBuffer.data(), 0, bufferBytes);
for (int i = 0; i < PRIORITY_GROUP_COUNT; i++) {
auto& group = mPriorityGroups[i];
if (!group->hasActiveTracks()) continue;
std::vector<float> groupBuffer(frameCount * channels);
group->mixTracks(mSampleRate, mChannelMask, frameCount,
groupBuffer.data(), frameCount);
for (size_t j = 0; j < frameCount * channels; j++) {
mFinalMixBuffer[j] += groupBuffer[j]; // 汇总
}
}
// Phase 2: Ducking — 高优先级 Group 活跃时降低低优先级音量
if (mIsDucking) {
mPriorityGroups[BACKGROUND]->setVolume(mDuckingLevel * 0.5f); // 10%
mPriorityGroups[NORMAL]->setVolume(mDuckingLevel); // 20%
}
writeToHal(mFinalMixBuffer.data(), frameCount);
return true;
}
2. AudioZone 原生支持
// AudioZone.h — 多区域音频核心定义
enum audio_zone_id_t : int32_t {
AUDIO_ZONE_ID_DEFAULT = 0,
AUDIO_ZONE_ID_DRIVER = 0,
AUDIO_ZONE_ID_FRONT_PASSENGER = 1,
AUDIO_ZONE_ID_REAR_LEFT = 2,
AUDIO_ZONE_ID_REAR_RIGHT = 3,
AUDIO_ZONE_ID_CENTER = 4, // 中央通道,导航/ADAS
};
class AudioZone : public RefBase {
audio_zone_id_t getZoneId() const { return mConfig.zoneId; }
// Zone 内按 PriorityGroup 分组,各自独立混音
std::vector<sp<PriorityGroup>> mPriorityGroups;
// Zone 级音量 + Focus 隔离
float mVolume;
sp<AudioFocusManager> mFocusManager;
};
class AudioZoneManager : public RefBase {
std::vector<sp<AudioZone>> mZones; // 所有 Zone
// 全局混音入口
status_t mixAllZones(void* halOutput, uint32_t halFrames);
// Zone 路由配置
status_t setZoneRoute(audio_zone_id_t zoneId, audio_io_handle_t halOutput);
};
3. AudioFocus 精细化控制
// AudioFocusRequest.java — 扩展 Focus 请求
public static class Builder {
/** Ducking Level(0.0 ~ 1.0),原来只能 0 或 0.2 */
public @NonNull Builder setDuckingLevel(float level) {
mDuckingLevel = level; // 可设 0.3 即 30%
return this;
}
/** 延迟恢复时间(ms)*/
public @NonNull Builder setResumeDelayMs(int delayMs) {
mResumeDelayMs = delayMs; // 被打断后等2秒再恢复
return this;
}
/** 受影响的 Usage(只影响指定的,不影响其他)*/
public @NonNull Builder setAffectedUsages(@NonNull AudioUsage[] usages) {
mAffectedUsages = Arrays.copyOf(usages, usages.length);
return this;
}
/** Zone 隔离(驾驶座的 Focus 不打断后排音乐)*/
public @NonNull Builder setZoneId(int zoneId) {
mZoneId = zoneId;
return this;
}
}
// 使用示例
AudioFocusRequest request = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN)
.setDuckingLevel(0.3f) // duck 到 30%
.setResumeDelayMs(2000) // 2秒后恢复
.setAffectedUsages(MEDIA, GAME) // 只压低媒体和游戏
.setZoneId(DRIVER_ZONE) // 只在驾驶 Zone 生效
.build();
4. HAL Performance Class 标准
// StreamOut.h — 定义 HAL 性能等级
enum audio_hal_performance_class_t : int32_t {
PERFORMANCE_CLASS_A = 0, // 延迟 < 20ms,必须 FastMixer
PERFORMANCE_CLASS_B = 1, // 延迟 < 50ms
PERFORMANCE_CLASS_C = 2, // 延迟 < 100ms
};
struct audio_hal_performance_info_t {
audio_hal_performance_class_t performanceClass;
uint32_t latencyMs; // 实测端到端延迟
uint32_t halBufferMs; // HAL 内部缓冲
bool supportsFastMixer;
bool supportsLowLatency;
};
class IStreamOutPerformanceExtension {
virtual int getPerformanceClass(audio_hal_performance_info_t* info) = 0;
virtual bool supportsLatency(uint32_t targetLatencyMs) = 0;
};
// AudioFlinger 根据等级选择路径
if (performanceClass == PERFORMANCE_CLASS_A) {
useFastMixerPath(streamOut); // < 20ms
} else if (performanceClass == PERFORMANCE_CLASS_B) {
useOptimizedMixerPath(streamOut); // < 50ms
} else {
useStabilizedPath(streamOut); // < 100ms
}
5. Track Effects 开放 API
// AudioTrack.java — 扩展 Builder
public static class Builder extends AudioTrack.Builder {
private ArrayList<Integer> mEffectIds = new ArrayList<>();
public @NonNull Builder setAttachEffect(int effectId) {
mEffectIds.add(effectId); // 支持多个 Effect 串行
return this;
}
}
AudioTrack track = new AudioTrack.Builder()
.setAudioAttributes(...)
.setAttachEffect(effectId1) // 附加 Effect 到 Track
.setAttachEffect(effectId2)
.build();
track.attachEffect(effectId3); // 动态 attach
track.detachEffect(effectId1); // 动态 detach
四、总结
| 不足 | 改进方案 | 核心变化 |
|------|----------|----------|
| 单点瓶颈 | Priority Group 分组混音 | 按优先级独立 Mixer,互不影响 |
| Focus 太粗 | 多级 Focus + ResumeDelay | 精细化 Duck Level + 延迟恢复 |
| 多 Zone 太弱 | AudioZone 原生支持 | Zone 间 Focus 隔离 |
| HAL 碎片化 | Performance Class | 按性能等级选择最优路径 |
| Effects 局限 | Track Effects 开放 | App 可 attach Effect |
五、后续工作
- 优先级分类规则和 AudioPolicyService 联动完善
- AudioZone 的 HAL 路由需要和 CarAudioHAL 对接
- Track Effects 的 native 层实现 binder 通信
- Performance Class 在 HAL CTS 测试中验证
- 完整的测试用例(CTS/VTS)
完整的实现代码已上传到 GitHub,可作为内部设计文档或概念验证的基础。
配套代码仓库:
GitHub: fryduck/android-audio-architecture-improvement