MCU添加aac-ld语音支持

来源:互联网 发布:mac os x 10.9 下载 编辑:程序博客网 时间:2024/06/10 04:11
最近给我们的产品添加aac-ld语音的支持,完结后做一个总结归纳,不系统不全面,就是记录自己在这个过程中遇到的问题和学到的东西。

我们的视频会议终端设备本身有支持aac语音的功能,但并不全面,提供基于TI芯片与思科对接的aac-ld编码功能,其TCS/OLC信令交互过程携带的编解码参数只是起到了描述的作用,真正程序里是固定的参数,也就是说编解码音频流只能是固定的:64k编码率、48k采样频率、单声道、16比特样点宽度。这个我觉得是有待改进的地方,但是我们创业公司,目前并未完善。
一.能力协商
上图吧:
TCS/OLC:
这里写图片描述

这是我抓的信令内容,我们原来的代码只支持sip信令协商,h323只能自己写了,正常的应该是TCS提供一个能力集的域,然后双方协商过滤出一个最佳能力,然后由OLC打开信道,但是我们这个其实并未做aacld能力协商的工作,只提供一个aac-ld的固定能力,参数一点不同都会pass掉aac-ld的能力,所以我们这里的TCS和OLC携带内容完全相同,解释:这里写图片描述
:这个是标准,具体内容填这里写图片描述蓝色的字节,我在填信令的时候各种搜索找不到,逆推代码填的。
这里写图片描述
接下来的maxBitRate是编码率,表示1s内编码输出比特率,64000bps也即是8KB/s,我们采样频率为48KHZ,样点16bits,所以每秒96KB源数据,可以看到压缩比为12:1。下面的参数无意义,aac目前并没有形成统一标准,或者是我没找到,这里的是我仿效华为信令交互的内容,没搞清含义,按一般标准,stand 1表示每个packet内含有的帧数目,stand 2 表示CBR设置,stand 3表示信道数量,这里的这两项不懂,要是有人看到希望留言教我。
这里写图片描述
接下来这些是aac能力参数,stand 值为0 代表profile&level,1表示源数据格式formatType,3表示audioObjectType,4表示AudioSpecificConfigure(这个参数后面要详细说一下),8表示streamMuxConfig,这些是在别人博客里看到的,没有找到全部的值代表的参数含义,后来发觉可以在开源的ffmpeg项目中看代码去了解,占时还没有时间去研究,主要的参数就是上面几个就可以了。
profile&level
这里写图片描述
这里写图片描述
这里写图片描述

第一个表可以看到aac-ld对应的一系列level值,通过第二个表可以选着我们想要的能力,例如是aac-ld单声道那么用的是0x18 Low Delay Audio Profile/L3,双声道的是0x19 Low Delay Audio Profile/L4,。
formatType:
一般填0,表示 原始数据格式。

audioObjectType:
这里写图片描述
这项直接根据使用的类型选着AOT值,如果是aac-lc就是2,如果是aac-ld就是23.
以上基本介绍完毕
二.Fdk-aac库使用
其实这个在官网上下载fdk-aac的源码里就有使用文档,但是有些东西并不那么好用,
首先,编译,拷贝libfdk-aac.a和相应头文件到相应路径。
编码模块,源码包中有编码器使用例子enc.c,参照使用文档照虎画猫,很容易通过,编译出的aac-ld语音可以被终端完美播放。
重点来了,虽然使用文档中说有一个解码器的使用例子main.c做参考,但是实际上没有,网上也找不到相应的使用例子,我只能自己按着文档里的调用顺序写解码器,这里出现两次问题,第一个问题解码器需要配置AudioSpecificConfiure参数,但是使用文档里没有详细介绍,网上各种地方也都找不到,最后我只能通过fdk-aac源码里对ASC参数使用的部分逆推其构成 ,总结如下
初始化解码器时如果待解码的语音流是LATM/LOAS则流配置StreamMuxConfig(SMC),其他格式配置AudioSpecificConfig(ASC):
AudioSpecialConfig:
leftFirst5 bits: AudioObjectType ( if it bigger than 31, read the follow six bits to add32 as the final value of AOT )
followed4 bits: SampleRate
followed4 bits: channel number
上面直接粘的我周报里的部分,其实后面还有内容,信道数量后面一比特是是否有拓展的标志位,0则结束,1则后面还有拓展字节,不过这些基本也都是用不到的,配置好前面几项就行了,其中采样率依照下表填3.
这里写图片描述
到此时MCU解析完终端的aac-ld语音后再混频发给其他终端出现第二个问题,声音明显的不流畅,这个问题纠结了很长时间,各个环节排查也都没问题,后来一想可能还是对fdk-aac解码器的使用有问题,但是网上又找不到实例,解码器完全是按照源码里的使用文档封装的,后来跟同事开会讨论,大家让我参考下ffmpeg项目里有没有类似的使用,于是就下载了ffmpeg的源码来看,最终找到了救命的解药,在ffmpeg源码FFmpeg/libavcodec/libfdk-aacdec.c文件中有fdk-aac解码器的使用实例,我按照使用文档的操作少了一步设置
if ((err = aacDecoder_SetParam(s->handle,AAC_CONCEAL_METHOD,
s->conceal_method)) != AAC_DEC_OK) {
av_log(avctx, AV_LOG_ERROR, “Unable to set error concealmentmethod\n”);
return AVERROR_UNKNOWN;
}
AAC_CONCEAL_METHOD值为0,解析时两帧之间衔接处静音,为1衔接处噪声替换,为2时添加模拟衔接。
设置完次操作后mcu可以正确解析aac-ld语音。
比较杂乱,仅作记录。

0 0