amrnb和amrwb的编解码

目的

最近在公司开发一个amrnb/amrwb的转码工具,在网上看了很多资料,主要是这篇AMR在IP域中的编码(rfc3267,4867) 对我帮助很大。 这里补充一下缺少和我自己的理解。

AMR编码介绍

AMR是3GPP组织的一个音频编码规范,目前的手机都使用AMR, 比如公司的测试机华为、小米只支持amrnb/amrwb。amrnb是对窄带信号进行编码(200–3400 Hz),amrwb是对更宽的频率范围进行编码(50–7000 Hz)。
根据香农理论,采样频率要是目标频率的两倍,所以向上取整的amrnb的采样频率是8000Hz, amrwb的采样频率是16000Hz。

bitrate

amrnb和amrwb有多种编码速率(bitrate),并支持在通话过程中通过CMR(codec mode request)协商来变化编码速率,不同于一般的编码器固定一种比特率。除此之外,还有没有人声时的SID(舒适噪音)模式。这时只需要发送一个Mode而不是发送无声的包,从而来降低带宽占用。

amrnb 不同比特率时的语音帧大小

Index Mode Class A bits total speech bits
0 4.75 42 95
1 5.15 49 103
2 5.9 55 118
3 6.7 58 134
4 7.4 61 148
5 7.95 75 159
6 10.2 65 204
7 12.2 81 244

amrwb 不同比特率的语音帧大小

Index AMR-WB codec mode Total number of bits Class A Class B Class C
0 6.60 132 54 78 0
1 8.85 177 64 113 0
2 12.65 253 72 181 0
3 14.25 285 72 213 0
4 15.85 317 72 245 0
5 18.25 365 72 293 0
6 19.85 397 72 325 0
7 23.05 461 72 389 0
8 23.85 477 72 405 0

payload type

amrnb和amrwb使用的动态payload type, 所以在用wireshark分析时,需要经常调整payload-type值

align mode

amrnb和amrwb在SIP协商中有两种align mode,对齐模式和节省带快模式。总结有几个区别

  • 对齐模式下CMR占8位,每个TOC占8位,然后每个语音帧补齐为整字节。
  • 节省带宽模式下,CMR占4位,每个TOC占6位,然后CMR + TOC + 所有语音帧加起来,最后补齐为整字节。

以单帧的12.2kbps为例

  • 语音帧为244位,对齐之后为(244 + 8 - 1)/8 = 31字节。加上1字节的CMR和1字节的TOC, 一共33字节。
  • 语音帧为244位,加上4位CMR和6位TOC,一共为254位,对齐后为(254 + 8-1)/8,一种32字节字节。

以两帧的12.2kbps为例

  • 两个语音帧分别占用31字节,加上1字节的CMR和2字节的TOC, 一共 65字节。
  • 两个语音帧分别占用244位, 加上4位的CMR和6 * 2位的TOC, 对齐后为( 488 + 4 + 12 + 8 - 1)/8,一共63字节。

总之,对齐模式是先对齐成字节再求和,节省带宽模式是先计算位和再对齐成字节。特别是多帧的时候,节省带宽模式算起来更复杂。好在实际情况都是1帧。

基于opencore-amr的编解码

开始用FFmpeg的库来做转码和推流,后来发现不支持节省带宽模式,而且还有个BUG,所以后面自己基于opencore的库写的转码功能。