AAC编码详解

嵌入式音视频开发------AAC编码

1. AAC 编码概述

在嵌入式音视频开发中,AAC(Advanced Audio Coding,高级音频编码)是一种非常常见的有损音频压缩技术,广泛应用于手机、机顶盒、车机、智能摄像头、会议终端、对讲设备以及各类流媒体系统中。AAC 属于 MPEG 音频标准体系的一部分,核心思想是:利用人耳听觉特性,在尽量不明显损伤主观音质的前提下,减少音频数据量

从工程实现上看,AAC 不是单一格式,而是一个编码家族。常见的包括:

  • AAC-LC:最常见,复杂度较低,兼容性最好;
  • HE-AAC v1:在 AAC-LC 基础上增加 SBR(频带复制),适合较低码率;
  • HE-AAC v2:进一步增加 PS(参数化立体声),适合更低码率立体声;
  • AAC-LD / AAC-ELD:面向双向通信和低时延场景;
  • xHE-AAC:覆盖更宽码率范围,并强化响度控制与自适应流媒体能力。

对于嵌入式系统来说,AAC 编码的真正难点通常不是"能不能编码",而是:

  • 能否在有限 CPU 下实时编码;
  • 能否在有限内存下稳定运行;
  • 能否满足端到端时延要求;
  • 能否在目标平台上保持可接受音质;
  • 能否兼顾封装、传输、兼容性和授权成本。

2. 为什么需要进行 AAC 音频压缩处理

2.1 减少存储空间占用

PCM 是未压缩音频,数据量非常大。以 CD 音质音频为例:

  • 采样率:44.1 kHz
  • 位宽:16 bit
  • 声道:2

则码率约为:

text 复制代码
44,100 × 16 × 2 = 1,411,200 bps ≈ 1411 kbps

文件大小计算公式为:

text 复制代码
文件大小(Byte) = 比特率(bps) × 时间(s) / 8

简化写法:

text 复制代码
文件大小(MB) ≈ 比特率(kbps) × 时间(s) / (8 × 1000)

因此,5 分钟未压缩 PCM 音频体积非常可观,而 AAC 在 128 kbps 左右即可获得较好的听感,大幅降低存储压力。AAC 的收益来自"在主观可接受音质下显著降低码率",而不是单纯追求压缩倍数

2.2 节省传输带宽

在直播、点播、语音通信和远程监控中,网络带宽通常是硬约束。AAC 压缩后可显著降低传输码率,减少网络抖动带来的播放卡顿,并提高多路并发时的系统承载能力。对于流媒体系统而言,音频并不只是"附属数据",它的稳定性直接影响整体体验。

2.3 在较低码率下保持较好音质

AAC 相比更早期的 MP3,在同等码率下通常能提供更好的主观音质,这是它长期成为移动互联网音频主流格式的重要原因之一。其本质在于 AAC 使用了更先进的滤波器组、量化和熵编码机制,并结合心理声学模型去掉听觉上不敏感的信息。

2.4 适配嵌入式产品的功耗与资源约束

嵌入式开发往往需要在以下约束中平衡:

  • MCU/SoC 主频有限;
  • SRAM/DDR 容量有限;
  • 音频链路要求持续实时;
  • 功耗预算严格;
  • 可能还要与视频编码、网络传输、AI 算法共用资源。

因此,AAC 的意义不仅在于"压小文件",更在于为系统级资源分配创造空间


3. AAC 的核心特点与优势

3.1 更高的压缩效率

AAC 在相同听感目标下,通常比 MP3 需要更低的码率。这也是它在流媒体、广播和移动端广泛普及的原因。

3.2 更好的主观音质

AAC 对中高频细节、瞬态信息和立体声场的保持通常优于早期格式,尤其是在中低码率下优势更明显。

3.3 支持多种编码工具

AAC 不是只靠"量化压缩"在工作,它通常会配合多个编码工具:

  • MDCT:把时域信号变换到频域;
  • TNS:时域噪声整形;
  • PNS:感知噪声替代;
  • SBR:高频重建;
  • PS:参数化立体声;
  • Huffman 编码:进一步减少比特冗余。

3.4 兼容性强,生态成熟

AAC 已被广泛支持于:

  • MP4 / M4A 容器;
  • Android MediaCodec;
  • Apple AudioToolbox / CoreAudio;
  • 广播与流媒体系统;
  • 各类软硬件播放器。

4. AAC 标准谱系与常见规格

4.1 AAC-LC(Low Complexity)

AAC-LC 是最常见的 AAC 配置,特点是:

  • 复杂度适中;
  • 音质和兼容性平衡较好;
  • 最适合中高码率音频;
  • 几乎是"默认 AAC"代名词。

适用场景:

  • 本地录音;
  • 视频文件音轨;
  • 普通流媒体;
  • 对兼容性要求高的嵌入式播放系统。

4.2 HE-AAC(v1)

HE-AAC 在 AAC-LC 上增加了 SBR(Spectral Band Replication),通过低频编码加高频重建方式,在较低码率下仍然保持较好的听感。它特别适合带宽有限场景。

适用场景:

  • 网络广播;
  • 中低码率音频直播;
  • 对带宽敏感的移动端业务。

4.3 HE-AAC v2

HE-AAC v2 在 HE-AAC 基础上增加 PS(Parametric Stereo),进一步压缩立体声信息,在超低码率立体声音频中效果更好。

适用场景:

  • 超低码率立体声流媒体;
  • 带宽更紧张的移动网络环境。

4.4 AAC-LD(Low Delay)

AAC-LD 不是为"音乐文件压缩"设计的,而是为实时通信设计的。其重点不再是压得多小,而是尽量降低算法时延。研究资料表明,AAC-LD 通过缩短帧长、减少 look-ahead 和削弱 bit reservoir,可以把算法时延压缩到适合双向通话的范围。

适用场景:

  • 语音会议;
  • 双向对讲;
  • 音视频互动系统。

4.5 AAC-ELD(Enhanced Low Delay)

AAC-ELD 可以理解为 AAC-LD 的增强版,进一步引入低时延 SBR 和更适合低时延场景的滤波器组。在较低码率下仍能保持较好通话质量。Fraunhofer 的资料中明确提到,AAC-ELD 相比 AAC-LD 能在更低码率下保持高质量通信体验。

适用场景:

  • 高质量语音会议;
  • 低时延互动直播;
  • 音视频对讲系统。

4.6 xHE-AAC

xHE-AAC 更偏向"现代流媒体工程方案",强调:

  • 极宽的码率覆盖范围;
  • 对语音和音乐都友好;
  • 与自适应码率流媒体结合;
  • 强制包含 MPEG-D DRC(动态范围控制)能力。

适用场景:

  • 自适应流媒体;
  • 广播与OTT音频;
  • 复杂终端生态的大规模内容分发。

5. AAC 编码的基本原理

AAC 编码流程大致如下:

text 复制代码
PCM输入
  ↓
分帧
  ↓
加窗
  ↓
MDCT频域变换
  ↓
心理声学分析
  ↓
量化与比特分配
  ↓
熵编码(Huffman)
  ↓
封装为 AAC 比特流

5.1 分帧

AAC 是基于帧的编码体系。不同 profile 的帧长度不同:

  • AAC-LC:通常 1024 个采样点;
  • AAC-LD / ELD:通常 480 或 512 个采样点;
  • HE-AAC:内部处理粒度还会更复杂。

这意味着在嵌入式系统中,采集线程、环形缓冲区和编码线程必须围绕"每帧样本数"设计,否则就会引入额外缓存等待与不可控时延。

5.2 频域变换

AAC 通常使用 MDCT(Modified Discrete Cosine Transform) 将时域信号映射到频域。频域表示更适合分析哪些频段"值得保留",哪些频段"可以近似"。MDCT 是 AAC 压缩的核心数学基础之一

5.3 心理声学模型

AAC 会利用人耳的掩蔽效应:

  • 强信号会掩蔽邻近频率的弱信号;
  • 某些高频成分对主观听感贡献较小;
  • 某些噪声在特定频段内不易被察觉。

因此编码器不会平均对待所有频率成分,而是把有限比特优先给"人耳更敏感"的部分。

5.4 量化与比特分配

编码器需要决定:

  • 每个频带分多少比特;
  • 哪些频带可以更粗量化;
  • 是否启用 TNS/PNS 等工具;
  • 在目标码率下怎样平衡失真与复杂度。

5.5 熵编码与比特流封装

量化后的频谱系数会通过 Huffman 编码进一步压缩,然后打包成 AAC 原始数据块,再依据不同封装方式输出为 ADTS、LATM/LOAS,或写入 MP4 中。


6. AAC 文件格式与封装形式

AAC 编码后的数据,本质上是按照 AAC 标准生成的压缩音频帧数据。但在实际使用中,这些数据并不会总是以完全相同的形式保存或传输,而是会根据场景的不同,采用不同的封装方式。

在工程中,经常会听到下面几个概念:

  • AAC 裸流(Raw AAC)
  • ADIF
  • ADTS
  • LATM / LOAS
  • MP4 / M4A 中的 AAC

很多初学者容易把它们混在一起。实际上,它们的关系可以理解为:

AAC 是编码方式,ADIF/ADTS/LATM/MP4 是 AAC 数据的组织或封装方式。

也就是说,AAC 解决的是"怎么压缩音频",而 ADIF、ADTS 等解决的是"压缩后的数据怎么存、怎么传"。

6.1 AAC 裸流(Raw AAC)

AAC 裸流指的是仅包含 AAC 原始编码数据块的比特流,不包含额外的文件头或传输头信息。

它的特点是:

  • 数据最精简;
  • 只保留编码后的音频有效载荷;
  • 如果没有额外的上下文信息,解码器往往无法直接知道采样率、声道数、Profile 等参数;
  • 更适合嵌入在其他容器或协议中使用。

所以,裸 AAC 一般不会单独拿来做通用文件分发,而是常作为底层有效负载存在。


6.2 ADIF 格式

ADIF 的全称是:Audio Data Interchange Format

它是一种面向文件存储的 AAC 数据组织方式。

ADIF 的特点是:

  • 整个文件只有一个统一的头部
  • 头部中保存了 AAC 解码需要的重要信息;
  • 音频数据紧跟在头部之后连续存放;
  • 解码时通常需要从文件开头开始解析

这意味着 ADIF 更适合:

  • 本地文件存储;
  • 一次性完整读取的场景;
  • 不强调随机接入和中途同步的系统。

但它也有明显限制:

  • 如果从流中间开始接收数据,往往无法直接解码;
  • 一旦文件前部损坏,整个流的可解析性会受到影响;
  • 不适合网络实时传输。

所以,ADIF 更偏"文件交换格式",不适合流媒体实时传输场景。


6.3 ADTS 格式

ADTS 的全称是:Audio Data Transport Stream

它是一种面向传输的 AAC 数据封装方式,也是嵌入式音视频开发中最常见的 AAC 裸流封装形式之一。

ADTS 的最大特点是:

每一帧 AAC 数据前面都会带一个 ADTS Header。

也就是说,ADTS 文件或数据流是由很多"ADTS Header + AAC Raw Data"这样的结构连续组成的。

它的优点非常明显:

  • 每一帧都有同步信息;
  • 可以从流中任意位置尝试同步;
  • 非常适合边收边播;
  • 适合网络传输、直播、TS 流、RTP 等实时场景;
  • 调试时也更方便,容易从码流中定位帧边界。

这也是为什么在实际开发中,我们经常会看到 .aac 文件其实就是 ADTS 封装的 AAC 数据流


6.4 ADIF 与 ADTS 的区别

ADIF 和 ADTS 的本质区别,可以概括为:

对比项 ADIF ADTS
头部数量 整个文件只有一个头 每一帧都有头
适用场景 文件存储 流式传输
是否支持中途加入 不适合 适合
随机访问能力 较弱 较强
容错性 前部出错影响大 单帧出错影响相对局部
嵌入式开发常见程度 较少 很常见

从嵌入式工程角度看:

  • 做本地文件归档时,可以使用更高层容器;
  • 做实时传输、推流、抓包分析、边采边播时,ADTS 更实用。

6.5 LATM / LOAS

除了 ADIF 和 ADTS,在一些广播、数字电视和特定传输协议中,还会见到 LATM / LOAS 这种封装方式。

它们同样是 AAC 的传输封装方式,但更多出现在:

  • 数字广播;
  • MPEG-TS 相关系统;
  • 某些专用流媒体协议。

对于一般的嵌入式音视频开发入门来说,最常接触的仍然是 ADTS。因此在初期学习阶段,重点掌握 ADTS 即可。


6.6 MP4 / M4A 中的 AAC

很多人看到 .mp4.m4a 文件中是 AAC 音频,就误以为它们等同于 ADIF 或 ADTS,其实并不是。

MP4 / M4A 属于容器格式 ,AAC 只是其中的音频编码格式之一。

也就是说:

  • AAC 负责压缩音频;
  • MP4 / M4A 负责把音频、视频、时间戳、索引等数据组织起来。

在 MP4/M4A 中,AAC 一般不会直接以 ADTS 形式存储,而是通过容器中的配置信息描述编码参数。

所以要区分两个层次:

  • 编码格式:AAC
  • 封装容器:MP4/M4A/TS 等

6.7 工程中的理解方式

可以把几种形式简单理解为:

text 复制代码
PCM 原始音频
   ↓
AAC 编码
   ↓
AAC 原始压缩帧
   ├─ ADIF 封装(单文件头)
   ├─ ADTS 封装(每帧头)
   ├─ LATM/LOAS 封装
   └─ 封入 MP4 / M4A / TS 等容器

因此,在实际开发里看到"AAC音频",你需要进一步问清楚两件事:

  1. 它的编码 Profile 是什么?

    比如 AAC-LC、HE-AAC、AAC-LD。

  2. 它是怎么封装的?

    比如 ADTS、MP4、TS、LATM。

只有把"编码"和"封装"分开理解,后面分析码流、写头、做封装、调播放器时才不会混乱。


7. ADIF 与 ADTS 详解

在 AAC 的各种封装方式中,ADIF 和 ADTS 是最基础、也最容易在学习阶段接触到的两种形式。其中,ADTS 在嵌入式开发中尤为常见,因此值得单独展开说明。


7.1 ADIF 详解

ADIF(Audio Data Interchange Format)是一种面向文件存储的 AAC 数据格式。

它的核心特点是:

整个 AAC 文件只在最开始位置包含一个 ADIF Header,后续紧跟连续的 AAC 音频数据。

也就是说,ADIF 的组织形式更接近:

text 复制代码
ADIF Header + AAC Data + AAC Data + AAC Data + ...
ADIF 的优点
  1. 结构相对紧凑

    只保存一个头部,不需要每帧重复保存控制信息。

  2. 适合完整文件存储

    当文件是完整读取、完整解码时,ADIF 是可行的。

ADIF 的缺点
  1. 必须从头开始解码

    如果只拿到中间的一段数据,由于缺少前部头信息,通常无法直接解码。

  2. 不适合流式传输

    网络中途加入、丢包恢复、随机定位都不方便。

  3. 鲁棒性较差

    头部一旦损坏,后面整个数据流都可能无法正确解析。

所以,ADIF 更适合作为"静态文件交换格式",而不是"实时音频传输格式"。


7.2 ADTS 详解

ADTS(Audio Data Transport Stream)是 AAC 在流式传输中最常用的一种封装方式。

ADTS 的结构可以表示为:

text 复制代码
ADTS Header + AAC Frame
ADTS Header + AAC Frame
ADTS Header + AAC Frame
...

也就是说,每一帧 AAC 原始数据前,都有一个固定格式的 ADTS Header

这种设计带来几个明显优势:

1)便于同步

每帧头部中都包含同步字(syncword),解码器可以通过同步字快速找到帧边界。

2)适合流式传输

因为每帧都是独立可识别的,所以:

  • 可以从中途开始接收;
  • 可以较容易从错误中恢复;
  • 更适合直播、推流、边采边播。
3)便于调试分析

抓到一段 AAC 数据流时,只要找 0xFFF 同步头,就可以尝试定位帧结构,因此 ADTS 对开发调试非常友好。

这也是为什么在实际项目中,我们经常把 AAC 编码器输出直接组织成 ADTS 流,送给文件保存模块、推流模块或播放器测试。


7.3 ADTS 帧结构

一个完整的 ADTS 帧通常由两部分组成:

text 复制代码
ADTS Header + AAC Raw Data

其中:

  • ADTS Header:描述这一帧的参数和长度;
  • AAC Raw Data:真正的 AAC 压缩音频数据。

ADTS Header 通常长度为:

  • 7 字节:无 CRC
  • 9 字节:有 CRC

实际开发中,大多数情况下使用的是 7 字节头


7.4 ADTS Header 结构说明

ADTS Header 可分为两部分:

  • 固定头(Fixed Header)
  • 可变头(Variable Header)

这种划分方式非常重要,因为:

  • 固定头中的很多字段在整段音频流里通常是不变的;
  • 可变头中的一些字段会随着每一帧变化,比如帧长度。

7.5 ADTS Fixed Header(固定头)

固定头主要描述 AAC 流的基本属性,例如:

  • 编码对象类型
  • 采样率
  • 声道数
  • 是否有 CRC

常见字段如下:

字段 位数 含义
syncword 12 同步字,固定为 0xFFF
ID 1 MPEG 标识
layer 2 固定为 00
protection_absent 1 是否省略 CRC,1 表示无 CRC
profile 2 AAC Profile 类型
sampling_frequency_index 4 采样率索引
private_bit 1 私有位
channel_configuration 3 声道配置
original/copy 1 原始/复制标志
home 1 Home 标志

这些字段中,最常需要关注的是:

1)syncword

固定为 0xFFF,这是解码器进行帧同步的关键标志。

2)profile

用于表示 AAC 的对象类型,常见值可理解为:

  • 0:Main
  • 1:LC
  • 2:SSR
  • 3:保留

在实际工程中,最常见的是 AAC-LC

3)sampling_frequency_index

它不是直接写采样率数值,而是写一个索引值。常见关系如下:

索引值 采样率
0 96000
1 88200
2 64000
3 48000
4 44100
5 32000
6 24000
7 22050
8 16000
9 12000
10 11025
11 8000
12 7350

因此,开发时如果采样率是 44100Hz,那么这个字段写的不是 44100,而是索引值 4

4)channel_configuration

用于标识声道布局,常见值例如:

  • 1:单声道
  • 2:双声道

7.6 ADTS Variable Header(可变头)

可变头中包含与当前帧更强相关的信息,常见字段如下:

字段 位数 含义
copyright_identification_bit 1 版权标识位
copyright_identification_start 1 版权标识开始
aac_frame_length 13 当前 AAC 帧总长度
adts_buffer_fullness 11 缓冲区满度
number_of_raw_data_blocks_in_frame 2 帧中原始数据块数量

这里最重要的是:

1)aac_frame_length

表示当前完整 ADTS 帧的长度,注意这里的长度包括:

  • ADTS Header 长度
  • AAC Raw Data 长度

也就是说:

text 复制代码
aac_frame_length = ADTS头长度 + AAC数据长度

如果这个字段写错,播放器往往就无法正确切帧。

2)adts_buffer_fullness

这个字段主要与码率控制和缓冲状态有关。很多 VBR 场景下经常看到特定默认值,工程调试时通常不会首先关注它,但做完整实现时仍要按规范填写。

3)number_of_raw_data_blocks_in_frame

表示当前 ADTS 帧里包含几个 AAC Raw Data Block。

通常最常见的是:0

它表示这一帧只包含 1 个 AAC 原始数据块

相关推荐
跃龙客12 天前
常见音视频编码二进制分析笔记(H264,H265,AAC,OPUS,G711A,G711U)
aac·h264·h265·opus·g711
TEC_INO2 个月前
Linux_22:音频AAC编码
音视频·aac
JMchen1232 个月前
Android音频编码原理与实践:从AAC到Opus,深入解析音频编码技术与移动端实现
android·经验分享·学习·kotlin·android studio·音视频·aac
weixin_465790913 个月前
S7-200自由口协议实现英威腾GD200变频器控制与数据读取
aac
Lueeee.3 个月前
如果在调试音频的时候(音频标准编码是aac),发现声音有异常,比如有电流滋滋或者其他不正常的声音该怎么去排查
音视频·aac
无敌最俊朗@3 个月前
音频格式全解析:PCM到AAC
pcm·aac
qq19226384 个月前
DL00187:多模型LSTM用于基于窗口数据分段的步态识别完整实现附数据集python
aac
海阔天空任鸟飞~4 个月前
杰理-7012-添加AAC播放格式
aac
咨询QQ:4877392784 个月前
MATLAB四旋翼自适应控制仿真simulink simscape,可更换成自己的无人机sol...
aac