海瑞两千
发表于 2005-1-31 05:08:00
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?快速注册
x
音频的编解码及其优化方法和经验
! r3 i$ M o2 j9 L- S1 |3 L0 p) F; {* z g3 R; l, J
音频的编解码(codec)根据应用场景的不同主要由几大技术组织制定,分别是ITU-T、3GPP、MPEG。当然也有一些公司或者公司的联合体等制定,如微软的WMA。他们不仅制定了codec的规范,同时还提供软件实现的reference code,这样便于普及制定的codec的使用。本文先谈谈这些codec,然后讲怎么样根据reference code去优化codec(主要是减少CPU load)。
5 w4 |4 O4 D3 [, ?4 V7 ]9 d- d2 t" }3 |6 l" N) H" v& D! e2 P" M
0 \* P$ K1 q) R# z0 z
+ n, P# M1 F+ G- ~1,codec 规范) v. g. k% Z8 h2 C) u+ s8 I6 ^
2 Y/ X3 F& i# u6 x4 @9 i# m
1)ITU-T
, K1 `+ x: N9 K. M: l. S( b& ?4 o/ j0 F: }+ G' h
ITU-T制定的是有线语音的codec标准,即G系列,主要有G.711、G.722、G.726、G.728、G.729等。采样率窄带是8KHz,宽带是16KHz。码率从64kbps到8kbps不等。下表列出了具体的采样率和码率。
& k* ]0 v B& X8 [+ O; ?# p1 @ X+ T4 \, r
/ P1 {+ w, x2 u' U/ |$ I4 H. ^+ d( n: [- m& l/ `
2)3GPP
$ N3 x, U2 v; ~" |' \& r* m; S( ~: A6 t
3GPP制定的是移动语音的codec标准,主要是AMR(adaptive multi-rate,自适应多码率)系列等,能根据网络状况自适应的调整码率。采样率窄带是8KHz,宽带是16KHz。近年来为了应对互联网的竞争(互联网公司提出了涵盖语音和音乐的OPUS codec),3GPP出台了EVS(enhanced voice service)音频编解码规范。EVS也涵盖了语音和音乐,能在两者之间灵活切换,支持多种采样率和码率。具体如下表。
, J; I$ ?; T& r$ T1 i; w Z& o/ X7 A: c: r% k
8 L9 P E" h/ @4 l. x" o
: k: I4 A" @8 P4 ^3)MPEG2 e- g* l) i7 D6 [; x0 ~
f/ |. u7 e# W* b
MPEG制定的主要是音乐的编解码规范,主要有MP3、AAC等。MP3大家都很熟悉,是近二十年来听音乐的最主要的格式,AAC是MP3的继承者,下一代的最主要的音乐编解码规范。音乐中采样率一般是44100HZ,也有的用48000HZ。码率在一个范围内,码率越大,音质越好。
Y- M# r, c K" ?- r
5 b+ y% o# i# c9 P4 q9 x8 q
0 T4 |- O2 P% O
$ D! y. j- m4 v) Z! J" K4)公司或公司联合体$ {( I' x! M# `
9 ]$ w- w7 r2 ?% M8 g7 K! N一些公司或者公司联合体根据需要制定音频的编解码规范,比如微软的WMA,Skype的SILK,GIPS(GIPS在2011年被谷歌收购,谷歌基于GIPS的音视频解决方案推出了webRTC并开源出来,影响巨大)的ILBC等。还有一个不得不提的就是OPUS,它是由非盈利的Xiph.org 基金会、Skype 和Mozilla 等共同主导开发的,全频段(8kHZ到48kHZ),支持语音和音乐(语音用SILK, 音乐用CELT),已被IETF接纳成为网络上的声音编解码标准(RFC6716)。5 e/ `2 l# s9 s+ w$ C0 u( I; T- h
* ], a3 p6 r) r' d$ w% T4 q ! M" l6 D7 c; }" U3 B2 L( _" y
9 k8 s% b3 }3 e我用过的codec从语音到音乐分别有G.711/G.722/G.726/G.728/G.729/AMR-NB/AMR-WB/ILBC/OPUS/MP3/AAC/WMA/APE/Vorbis/ALAC/FLAC等。
* E6 X1 Q! y' X E& k( h: D; W( D# e
/ _3 B: w1 ]. q T. h# ~1 z; k5 @8 n0 Z; I$ N1 Y6 K) U
2,codec的优化
1 ~6 w1 C8 y8 R1 u* o) U( y
( p! G* n r$ S7 K8 N! Y这里讲的优化主要是指CPU load的优化,即优化后运行codec占用更少的CPU,在具体的硬件平台上运行的更流畅。优化到什么程度算结束这依赖需求而定。如果优化后给所在项目用,就要看项目给你多长时间优化以及项目能接受的优化后的CPU load,一般情况下项目用上优化后的codec后在最复杂的场景下能流畅运行又不影响其他功能就可以了,因为项目上要腾出人手做其他事情,毕竟项目进度和质量是最重要的。如果优化后作为库卖给客户用,就要尽量优化到极致,因为这是用户选择用哪家公司库的重要指标,是卖点,这种情况下就会有更多的优化方法和技巧。我做过的优化都是给项目用,没有作为库给客户用,因而技巧不是特别多。# k0 A) B2 {; a/ q: H+ h$ c
- K) q8 g |/ Y" _( K) i- w
1)优化前的准备工作( f W% n* f5 i, o3 e
( r$ C3 a- r- @& S
a) 通读一下要优化的codec的代码,尽量读懂,即使没懂也要搞清楚函数是干什么的,这有利于后面优化。
7 K' U" j: P) W( Y, D& ]2 l: h; W
0 u: |8 l3 v: }& ?b) 准备好profiling工具,profiling工具就是测量运行某个函数花了多少clock。有现成的profiling工具最好,如果没有就根据具体OS和硬件平台(ARM/MIPS等)自己做工具。) p$ U7 n+ Q$ N) [7 `
. I# F) g# g8 C" e+ K
c) 准备好test vector,即测试的音源,一般codec制定的官方会提供,通常是多个vector, 对应于不同的场景。优化的原则是在减少CPU load的同时算法运算结果不被改变,所以在做优化时每优化一些就要用test vector跑一下,看结果有没有改变,如果改变了,就要退回到上一个版本。我做优化时每天至少保留一个版本,有时两个或者三个,就是为了出问题时好回溯,尽快查出哪个地方的优化出了问题。
4 D7 l9 L/ V: j$ B8 D$ h0 ? d* Z- A" u- i% f
7 k5 F" `0 U& w2 A" c8 ~( ~
& Z3 A4 U+ I }& _" b2)优化步骤与方法
5 a" }/ z# v; Z( y5 v4 `! |! B
" v& o8 K% x" v% I8 Da) 将编译器的优化选项从-o0改为-o3
% C+ |! e7 S3 `& _
2 ~8 L% m" Y* r8 Y! ^, zb) 给代码中那些经常被调用的又短小的函数加上inline
: L: Y6 \1 W1 k5 N: h y. `
$ ^7 Q0 T5 |# B+ ~0 o4 v通常情况下做完a,b后load会下来一大截,如同挤泡沫一样,会挤掉很大一部分。
( T) _+ ~) E. k0 ?& J" t. i: N8 ?, ~; p( t. l: u
c) ITU-T或者3GPP的codec reference code中有好多基本运算(加减乘除)的函数,这些函数都写的特别严谨,同时调用的频次又非常高,因而加大了运算复杂度。这些函数中有些在保证正确的前提下可以简化(如一些防饱和就可以不要),这样处理后load会降下来一些。
. k: V3 ]& x6 H2 l5 V7 |4 @, l+ ^% c1 q w
d) 用profiling工具一步步排查看到底哪个函数花的load多,明白这个函数是干什么的,然后具体问题具体分析,看怎么样来优化。- p8 B4 x9 ~1 \' U* b" @4 N
; Q3 d* T" r+ V, Y5 D
e) 有些函数就是一个小算法,reference code中写的比较复杂,调用频次又比较高。要去找有没有简单的实现可以替代,有的话替代了load就会降下来一些。比如codec中经常有求平方根的计算,reference code中通常写的比较复杂。我们知道用牛顿迭代法也可以求平方根,就可以用牛顿迭代法去替换将load降下来。6 f5 r: D- E+ e J$ ?: {
: h* a! c. ~! e% \+ E2 P! M
f) 用汇编优化。如果在C级别能解决问题就不要用汇编了。各个处理器都有自己的汇编指令集,需要去学并且掌握其中的思想和技巧。通常是用的频次较高的又比较占load的函数用汇编去写,即用C和汇编混合编程。汇编优化花的时间会相对长一些。
, M; h. \3 `3 K5 Q! B8 t- _- f
3 h& @( r/ x5 W# X当然还有一些小的技巧比如展开for循环、用指针替代数组等,这里就不一一说了。 |
|
中国hifi音响网
|
|
|