音频应用

 找回密码
 快速注册

QQ登录

只需一步,快速开始

搜索
查看: 306|回复: 1

[音频] 音频的编解码及其优化方法和经验

[复制链接]

37

帖子

0

听众

905

积分

Audioapp新手上路

Rank: 1

积分
905
QQ
发表于 2018-5-8 14:38:59 | 显示全部楼层 |阅读模式
音频的编解码及其优化方法和经验
+ M" c- Z: d2 t! @
# s! A: Q7 y) u: ~' T& i音频的编解码(codec)根据应用场景的不同主要由几大技术组织制定,分别是ITU-T、3GPP、MPEG。当然也有一些公司或者公司的联合体等制定,如微软的WMA。他们不仅制定了codec的规范,同时还提供软件实现的reference code,这样便于普及制定的codec的使用。本文先谈谈这些codec,然后讲怎么样根据reference code去优化codec(主要是减少CPU load)。
) O5 R7 \+ ^9 S& V9 L# h
& V/ Z' r" J; j/ s" A# G9 w, c0 C
9 b" i# d, X$ b: p6 g) {" T4 X% J0 [. w7 s
1,codec 规范- I2 }' V! w  J" n& w4 V( Z

) Z5 c# h) @" l2 t3 g% Y* \1)ITU-T9 o( @' W( ]$ J+ `! G2 F

- t9 O+ x2 ?! _$ nITU-T制定的是有线语音的codec标准,即G系列,主要有G.711、G.722、G.726、G.728、G.729等。采样率窄带是8KHz,宽带是16KHz。码率从64kbps到8kbps不等。下表列出了具体的采样率和码率。" n  |) M) m6 V% j  \( D8 ]; H* H% x
) Q7 r: _$ z) G9 A6 I* ~. W) e
   1181527-20170910202814179-1578742137.png                                                          " v) r. Z2 H5 l+ B+ m# H# q
4 a" Q0 x( t5 F# i% Z
2)3GPP
% p( ^& Z9 W/ j/ }: F
2 f( W6 Q! d3 ^3GPP制定的是移动语音的codec标准,主要是AMR(adaptive multi-rate,自适应多码率)系列等,能根据网络状况自适应的调整码率。采样率窄带是8KHz,宽带是16KHz。近年来为了应对互联网的竞争(互联网公司提出了涵盖语音和音乐的OPUS codec),3GPP出台了EVS(enhanced voice service)音频编解码规范。EVS也涵盖了语音和音乐,能在两者之间灵活切换,支持多种采样率和码率。具体如下表。
8 z7 U$ K  b2 j! O3 Z 1181527-20170910203032038-1508053091.png
( ?; _2 I* u7 _. S- e( x6 V                                       
4 }# h6 y  g( |7 I2 m6 k* x& }8 ?
7 K2 D- i8 Q6 A  z0 K  X. D3)MPEG
* t+ \* R6 R, v3 l! G% v9 i* I7 T/ }, V: }
MPEG制定的主要是音乐的编解码规范,主要有MP3、AAC等。MP3大家都很熟悉,是近二十年来听音乐的最主要的格式,AAC是MP3的继承者,下一代的最主要的音乐编解码规范。音乐中采样率一般是44100HZ,也有的用48000HZ。码率在一个范围内,码率越大,音质越好。
! T, b5 ?" n2 c8 n+ m% D2 l! b" @$ ]: g0 d5 I3 B4 V7 _
$ ?- p0 h/ s( y* F, d, I% @
: J# }" J4 o' m# u  k
4)公司或公司联合体
+ E* U, F' A/ b) v6 h  S/ @8 H
1 ]* R* N3 W7 O) U一些公司或者公司联合体根据需要制定音频的编解码规范,比如微软的WMA,Skype的SILK,GIPS(GIPS在2011年被谷歌收购,谷歌基于GIPS的音视频解决方案推出了webRTC并开源出来,影响巨大)的ILBC等。还有一个不得不提的就是OPUS,它是由非盈利的Xiph.org 基金会、Skype 和Mozilla 等共同主导开发的,全频段(8kHZ到48kHZ),支持语音和音乐(语音用SILK, 音乐用CELT),已被IETF接纳成为网络上的声音编解码标准(RFC6716)。2 H& N' t! s& ?' _0 e- B* J+ B
. i5 l3 k* i" b7 g
, L2 _8 l0 \: `% \) F& f

4 A( v5 O/ Y% t' T% D# U. M我用过的codec从语音到音乐分别有G.711/G.722/G.726/G.728/G.729/AMR-NB/AMR-WB/ILBC/OPUS/MP3/AAC/WMA/APE/Vorbis/ALAC/FLAC等。
1 t3 \& H! C1 w  z6 ?, A7 D, p1 {! j- a; Q" J- {3 V* N
# Y1 d3 E+ [% W" d) d+ e- Q
4 R% c4 t8 n5 u, i" `
2,codec的优化
# E: `" k# @, R* C/ C
! @4 v: A2 B# z6 f) P( g这里讲的优化主要是指CPU load的优化,即优化后运行codec占用更少的CPU,在具体的硬件平台上运行的更流畅。优化到什么程度算结束这依赖需求而定。如果优化后给所在项目用,就要看项目给你多长时间优化以及项目能接受的优化后的CPU load,一般情况下项目用上优化后的codec后在最复杂的场景下能流畅运行又不影响其他功能就可以了,因为项目上要腾出人手做其他事情,毕竟项目进度和质量是最重要的。如果优化后作为库卖给客户用,就要尽量优化到极致,因为这是用户选择用哪家公司库的重要指标,是卖点,这种情况下就会有更多的优化方法和技巧。我做过的优化都是给项目用,没有作为库给客户用,因而技巧不是特别多。9 o. P  e$ y$ m5 q# a  X

2 j/ _' ?9 j5 d' D9 u/ m1 M1)优化前的准备工作  X5 h0 e* N) N1 G, ?- c) I0 o
& G% e5 ^5 J% g' ]5 j+ k2 c% W4 P2 ]
a)    通读一下要优化的codec的代码,尽量读懂,即使没懂也要搞清楚函数是干什么的,这有利于后面优化。
, K3 B! ?# j' ^: a* v; Y5 B
$ F4 s4 Y, A8 s: j" xb)    准备好profiling工具,profiling工具就是测量运行某个函数花了多少clock。有现成的profiling工具最好,如果没有就根据具体OS和硬件平台(ARM/MIPS等)自己做工具。
6 N3 S/ d1 I) p" c. q5 c
) ]* T1 Z; c% g5 U; qc)    准备好test vector,即测试的音源,一般codec制定的官方会提供,通常是多个vector, 对应于不同的场景。优化的原则是在减少CPU load的同时算法运算结果不被改变,所以在做优化时每优化一些就要用test vector跑一下,看结果有没有改变,如果改变了,就要退回到上一个版本。我做优化时每天至少保留一个版本,有时两个或者三个,就是为了出问题时好回溯,尽快查出哪个地方的优化出了问题。
8 }! r( o% `, x& H' ?% ]6 v6 ~- ~( e% [. A! w& \( a/ \# `
: o4 _+ W7 G! K2 u3 ]

8 U0 A* b( m6 _( t  O' G2 @6 K+ x; _2)优化步骤与方法
# B. F% W& u/ p4 e7 n2 O) N* K9 a$ |" y0 D+ X3 \
a)    将编译器的优化选项从-o0改为-o32 t4 ~) S* O2 j9 z" @% h
+ l4 v% c8 R* v3 Z7 X( J
b)    给代码中那些经常被调用的又短小的函数加上inline& c4 Q" N& V2 X+ C: ?
+ D' {4 B- G+ z
通常情况下做完a,b后load会下来一大截,如同挤泡沫一样,会挤掉很大一部分。
9 @; |8 P  y! B$ A% w
: i6 e7 W2 O# c/ `9 ^6 m. rc)     ITU-T或者3GPP的codec reference code中有好多基本运算(加减乘除)的函数,这些函数都写的特别严谨,同时调用的频次又非常高,因而加大了运算复杂度。这些函数中有些在保证正确的前提下可以简化(如一些防饱和就可以不要),这样处理后load会降下来一些。
8 i+ }, E2 W$ Q8 a# h
: y/ \* U& L2 |3 }9 l: ^d)    用profiling工具一步步排查看到底哪个函数花的load多,明白这个函数是干什么的,然后具体问题具体分析,看怎么样来优化。* f- ~+ }8 j) j- x
7 g- `" U; y  f2 c2 o: V
e)    有些函数就是一个小算法,reference code中写的比较复杂,调用频次又比较高。要去找有没有简单的实现可以替代,有的话替代了load就会降下来一些。比如codec中经常有求平方根的计算,reference code中通常写的比较复杂。我们知道用牛顿迭代法也可以求平方根,就可以用牛顿迭代法去替换将load降下来。
0 n. }! z: M* h' `6 s! R: |1 C9 U/ G- N; g* M0 G6 \8 d* j
f)     用汇编优化。如果在C级别能解决问题就不要用汇编了。各个处理器都有自己的汇编指令集,需要去学并且掌握其中的思想和技巧。通常是用的频次较高的又比较占load的函数用汇编去写,即用C和汇编混合编程。汇编优化花的时间会相对长一些。/ a' C( D; p& D$ i/ X1 s
6 [& w: L. Y/ k2 s( r# Q
当然还有一些小的技巧比如展开for循环、用指针替代数组等,这里就不一一说了。
音频应用 Audio app

13

帖子

0

听众

314

积分

Audioapp新手上路

Rank: 1

积分
314
发表于 2018-5-15 07:50:39 | 显示全部楼层
不错!辛苦了,好文章,我学习了啊
音频应用 Audio app
高级模式 自动排版
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

QQ|小黑屋|手机版|Archiver|中国原创歌词网|音频应用 ( 鄂ICP备16002437号-6 )

GMT+8, 2018-10-22 19:41 , Processed in 1.046875 second(s), 9 queries , File On.

Powered by Audioapp X3.3

© 2018 Audioapp Inc.

快速回复 返回顶部 返回列表