前言
不同的分机端使用的语音编码格式各不相同,asterisk需要进行相应的转换,然后再进行语音数据的传输处理。比如fxs使用G729的语音编码,当fxs拨号呼叫sip分机时(假设该sip分机只能支持ulaw格式语音),asterisk需要把fxs收到的语音数据转换成ulaw,再发送给sip分机。若不进行转换,直接把G729格式的语音数据发送给sip分机,sip分机端就会听到杂音。同样的,asterisk需要把sip分机收到的语音数据转换成G729,再发送给fxs分机。完成一次语音交换。
目前asterisk支持的语音编解码较多,包括:G711(u/alw),G729(pcm),G722(adpcm),G726, gsm等等。一般的,压缩比高的编解码,编解码后的语音数据量比较小,利于网络传输,但语音失真就比较严重。
代码实现
asterisk的语音编解码代码放置在codecs目录下,每一种编解码编写自己的.c文件,注册编码转换的结构。如:
static struct ast_translator lintog729 = {
.name ="lintog729",
.srcfmt = AST_FORMAT_SLINEAR,
.dstfmt = AST_FORMAT_G729A,
.newpvt = lintog729_new,
.framein =lintog729_framein,
.frameout =lintog729_frameout,
.destroy =lintog729_release,
.sample = lintog729_sample,
.desc_size = sizeof(structg729_coder_pvt),
.buf_size = 1000 };
该指明把源格式AST_FORMAT_SLINEAR 转换成目标格式 AST_FORMAT_G729A,
收到语音数据时调用lintog729_framein 函数
生成语音数据时调用lintog729_frameout函数
通话时,上层的调用在translate.c的ast_translate函数中。
#0 g722tolin_framein(pvt=0x9794368, f=0x94d665c)at codec_g722.c:110
#1 0x08160592 in framein (path=0x9794368, f=0x94d665c, consume=0) at translate.c:176
#2 ast_translate (path=0x9794368, f=0x94d665c, consume=0) at translate.c:322
#3 0x080a6457 in ast_write (chan=0x9788f38, fr=0x94d665c) at channel.c:3850
#4 0x080a85eein ast_generic_bridge (c0=0x94dca78, c1=0x9788f38,config=0xb6eb53e8, fo=0xb6eb50e0, rc=0xb6eb50dc) at channel.c:5331
#5 ast_channel_bridge (c0=0x94dca78, c1=0x9788f38, config=0xb6eb53e8,fo=0xb6eb50e0, rc=0xb6eb50dc) at channel.c:5669
#6 0x080cfcc8 inast_bridge_call (chan=0x94dca78, peer=0x9788f38,config=0xb6eb53e8) at features.c:3053
#7 0x00e19894 in dial_exec_full (chan=<value optimized out>,data=<value optimized out>, peerflags=0xb6eb5c68, continue_exec=0x0) at app_dial.c:2317
#8 0x00e1b21d in dial_exec (chan=0x94dca78,data=0xb6eb7f5c) at app_dial.c:2400
#9 0x08110a65 in pbx_exec (c=0x94dca78,app=0xb753da48, data=0xb6eb7f5c) at pbx.c:1359
#100x0811d857 inpbx_extension_helper (c=0x94dca78, con=<value optimized out>,context=<value optimized out>, exten=0x94dcd3c "s", priority=11, label=0x0,callerid=0x94d5d58 "500", action=E_SPAWN,
found=0xb6eba25c, combined_find_spawn=1) at pbx.c:3726
#110x008ba47d in _macro_exec (chan=0x94dca78, data=<value optimized out>,exclusive=0) at app_macro.c:398
#12 0x08110a65 in pbx_exec (c=0x94dca78, app=0xb753a160, data=0xb6ebd00c) at pbx.c:1359
#130x0811d857 inpbx_extension_helper (c=0x94dca78, con=<value optimized out>,context=<value optimized out>, exten=0x94dcd3c "s", priority=2, label=0x0,callerid=0x94d5d58 "500", action=E_SPAWN,