VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务

VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务

最近在Windows上开发一套用于处理多种音频数据的解码服务,大致原理是输入不同格式的源码数据 ,通过解码模块,输出原始的音频数据,原始音频数据经过二次生成,可用wav格式的文件保存为音频文件。
利用到的开源库:pcmu\pcma\编解码以及转换代码、bcg729、	opencore-amr-0.1.5	

pcmu\pcma(g711编码)VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第1张图片

  1. wireshark抓包数据如上;

  2. 打包时间标签为160ms,rtp整包长度216,实际PayloadType=8,真正的payload长度为160;

  3. 处理方法,我这边是将PCMA的数据转成PCMU的数据,然后交由PCMU的解码器一起解码;
    BOOL G711AlawToUlaw(unsigned char *pG711aData,int iG711aDataLen)
    {
    int i = 0;
    for (i = 0; i < iG711aDataLen; i++)
    {
    pG711aData[i] = alaw2ulaw(pG711aData[i]);
    }
    return TRUE;
    }

  4. PCMA和PCMU生成的数据为320个字节的音频数据,也可以用 ushort *160 表示;解码的函数网上有很多,在CSDN中也能找到很多的例子,这里就不详细说了。

G729解码

  1. 使用G729解码库;VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第2张图片
    VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第3张图片
  2. 我这边系列里面用到的G729包,是160ms打包,每包是20个字节,解码的时候需要分两次解码,最终合并成一个音频数据包,如下;
    VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第4张图片
    VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第5张图片

amr格式解码(目前只支持octet-align=1字节对齐)

  1. 参考了非常重要的一篇博文,感谢原作者的分享,博文地址:https://blog.csdn.net/szfhy/article/details/50552819
  2. amr-nb:用到的函数
  3. amr-wb:用到的函数
  4. 需要注意的是,需要根据wireshark的抓包数据进行具体分析:VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第6张图片
    amr-wb和amr-nb的最大区别是码率不一致,在payload的第一个字节中,可以得到码率,这个码率根据设定可以对应得到payload的实际长度,下面是具体的长度:

*//amr_nb长度
const int amr_nbsizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };

//AMR_WB长度
const int amr_wbsizes[] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, -1, 0 };
计算方式:计算此处pbuffer[1]对应的就是抓包数据中的第一个字节0x44;
5. 调用解码函数的时候,是需要把第一个字节直接带入解码函数的buffer;

实际实现过程中遇到的问题

  1. 假如终端,在静默时,不发送音频数据,那么导致最终抓取到的音频数据包,seq连续,但是timestamp确是不连续的,这种情况下需要记录已经写入的最后一个时间戳,然后处理当前这个帧时,根据时间戳、结合打包时间戳来处理是否补充数据,具体实现如下:VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第7张图片
  2. 关于噪音帧:amr中AMR-SID对应值是8,amr-wb中对应值是9;像这样的情况,应该把该帧之间过滤,然后通过第一点提到的补充数据长度,把对应数据保存到文件中;
    VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第8张图片
    VOIP系统开源实现PCMA/PCMU/AMR/G729常用格式解码服务_第9张图片
  3. 此外还用到了简单的线性混音函数,可参考网络;

你可能感兴趣的:(通信系统与音视频开发,pcma,g729,amr-wb,amr,解码)