聊聊音频类开源代码这点事

摘要:
后来,我去了芯片公司,在终端上做语音引擎,并开始接触音频类的开源代码,首先是ITU-T/3GPP的各种编解码器,然后是各种完整的解决方案。尽管到目前为止还没有关于使用的音频开源代码数量的具体统计数据,但至少有十几个,例如webRTC/PJSIP/FFMMPEG。今天,我们将讨论开源音频代码。音频代码的开放源代码有益于行业、公司和个人。音频开源代码也有自己的特点:1.对于算法开源实现,尤其是各种编解码器的参考码,不能直接使用,只能在优化后使用。

我工作的头几年是在通信设备商做通信设备上的语音软件开发,主要是follow ITU-T/3GPP/RFC等SPEC写代码,相对封闭,没怎么接触开源代码。后来到芯片公司做终端上的voice engine,开始接触音频类的开源代码,先是ITU-T/3GPP的各种codec,后来是各种完整的解决方案。刚开始做voice engine的时候,GIPS还没被Google收购,更加没有webRTC的开源,那时腾讯QQ上的语音方案还没自研(用的是GIPS的方案)。到现在用过的音频类开源代码个数虽然没具体统计过,至少也有十几个吧,例如webRTC/PJSIP/FFMPEG。今天我们就聊聊音频类开源代码这点事。

音频类开源代码众多,我根据自己的使用以及理解将它们分成三类,如下表:

聊聊音频类开源代码这点事第1张

算法类主要有ITU-T/3GPP codec reference code等,音频的算法主要是数字信号处理,技术门槛是很高的,ITU-T/3GPP等组织为了普及自己制定的codec,就开源了codec的软件实现方便大家使用,大家用时的主要工作就是优化代码,使其在具体的平台上流畅运行。解决方案类主要有webRTC/PJSIP等,包括了从采集、编解码、传输到播放的整个过程,并且对不同平台(Linux/Android/iOS)进行了适配。好多公司(尤其互联网公司)基于这样的开源实现做二次开发,形成自己的产品。这类开源实现中也用其他的开源代码,主要是算法类的,比如用ITU-T/3GPP各种codec的reference code,再比如PJSIP就用了webRTC里的AEC的开源实现。介于算法和解决方案之间的既不是单纯的算法,也没有形成一套完整的解决方案,比如FFMPEG,它除了各种算法之外,还有各种音频格式的封装和解封装等,但它没有形成完整的解决方案,而是提供API给其他模块用。

音频类代码的开源,不管是对行业对公司还是对从业的个人都是受益颇多。对行业而言,主要是降低了技术的门槛,促进了技术的普及,大家都来做了,也促进了行业的繁荣。要是没有webRTC的开源,短时间内肯定不会有音视频直播APP的集中涌现,更加不会有2016年全民玩直播的热潮。

对公司而言,主要有以下益处:

1,基于解决方案类的开源实现做产品,极大地缩短了产品的开发周期,让产品尽早的投放市场,获得先机和较好的市场份额。

2,音频处理中复杂的算法,比如AEC,都是有很高的技术门槛的,一般不可能在短时间内做出一个性能很好的软件实现。以前只有大公司或者专业的算法公司才做这些算法,一般公司都是去买算法库用到自己的产品里。现在这些算法开源了,可以拿来用,节省了一笔开支。

3,基于解决方案类开源实现做产品,就要对里面的机制技巧等搞清楚吃透,然后才能做二次开发。这样就逐渐的提高了整个团队的技术能力和竞争力。

对个人而言,主要有以下益处:

1,一些算法实现,如果只有文档,可能理解的不是很深刻,有了代码实现后就可以去调试,更好的理解算法。

2,著名的解决方案类开源实现都是技术大牛写出来的,里面有很多的技巧和设计的思想,把这些都理解了后就无形中提高了自己的编程架构等能力。大家做东西一般都不是从零开始的,而是先学习他人的,理解消化后再根据自己开发产品的需要做改进。以我自己为例,以前对jitter buffer只有一个基本的概念,并不知道如何实现,后来学习了开源里的实现,理解消化后并做了一定的改进用到了自己开发的产品里。

音频类开源代码也有自己的一些特点:

1,对算法类开源实现而言,尤其是各种codec的reference code,一般都不能直接使用(主要是因为CPU load 高),而是优化后才能使用。

2,对解决方案类开源实现而言,一般会适配各种平台各种协议,因而是包罗万象的,有的还增加了适配层,这些处理增加了代码的复杂度,加大了代码走读的难度。同时这些代码都是大牛写的,技巧性很强,也加大了代码走读的难度。我记得刚开始读PJSIP代码时特别晕,好多抽象出的适配层,到处是callback函数,而且这些callback函数的名称都一样,只有加log才知道这个函数在哪调的。后来代码熟悉了知道这些callback函数在哪调才好很多。

就我自己而言,既在产品开发中用过算法类开源实现,也有基于解决方案类开源实现开发产品。我的看法是算法和模块可以用开源的,但是整个解决方案最好不要用开源的,即使刚开始为了赶进度用开源的,后面有时间了也要自己重写。因为解决方案类开源是保罗万象的,而我们自己开发的产品平台和协议等都是明确的,这样可以减少代码的复杂度冗余度,也有利于后期的维护(我看到一些基于解决方案类开源做的产品越到后面越难维护,不得不重写)。同时开源实现中好多会用非常复杂的数据结构,有时还有多层的封装,代码走读性不够友好。我喜欢的代码风格是简洁明了,能用简单的数据结构就不用复杂的,即使是刚毕业的学生也能很快看懂,也有利于后期的维护。记得在开发过的一款产品里前人用双向链表(buffer动态分配不固定)来存储从网络上收到的语音包,通常情况下都没有问题,但是网络状况多变,好多场景是设计时想不到的,只有出问题了才意识到。而且出问题基本上都是指针飞了crash,如果没有很好的定位crash的手段,再加上log又不是实时的,不知道crash在什么地方,会很痛苦。当时就填了好多这样的坑。后来我们用循环数组替换了双向链表,存放语音包的buffer是一块连续的空间,代码好理解,也很少出crash的问题,即使出crash问题也能很快定位解决。所以我觉得能用数组解决问题的就不要用链表,数组(循环数组/ring  buffer)是我这么多年用的最多的数据结构,而链表是很少用的。

免责声明:文章转载自《聊聊音频类开源代码这点事》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇让div在屏幕中居中(水平居中+垂直居中)的几种方法hbuilder个推功能下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mybatis plus 主键生成 Twitter雪花算法 id 及修改id为字符型

mybatis plus配置主键生成策略为2,就是 使用Twitter雪花算法 生成id spring boot中配置为: GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector()); conf.setIdType(5); 这样生成的是long类型的,如果想把这个i...

哪种开源许可证下的软件可以用于商业

  开源的软件大家应该不会陌生,它帮助我们可以迅速的了解一个技术的实现过程。并且可以加快我们的开发速度。但是不同的 开源软件遵守各自的许可证协议,有些开源软件是不能用作商业用途的。经过Open Source Initiative 组织通过批准的开源协议目前 有60多种,那么哪种许可证下的开源软件可以用于商业,哪种又不能呢?下面就我个人的理解做个介绍。 下面...

人人开源框架学习笔记

框架介绍 三个框架 人人框架总共分为三个,分别是: renren-security、 renren-fast、 renren-generator。 根据官方的介绍, renren-security: 轻量级权限管理系统 https://gitee.com/renrenio/renren-security renren-fast : Java快速开发平台...

二维码扫描开源库ZXing定制化【转】

转自:http://www.cnblogs.com/sickworm/p/4562081.html 最近在用ZXing这个开源库做二维码的扫描模块,开发过程的一些代码修改和裁剪的经验和大家分享一下。 建议: 如果需要集成到自己的app上,而不是做一个demo,不推荐用ZXing的Android外围开发模块,只用核心的core目录的代码就好了。androi...

C#如何为程序打包发布应用(图解教程) (转)

1:新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点击确定.(详细见下图) 此主题相关图片如下: 2:安装向导关闭后打开安装向导,点击下一步,或者直接点击完成. 3:开始制作 安装向导完成后即可进入项目文件夹: 双击"应用程序文件夹"在右边的空白处右击,选择添加->文件,将你...

干货|自适应大邻域搜索(ALNS)算法求解带时间窗的车辆路径规划问题(附java代码)

转眼距离开学又过去一个多月了,不知道大家在家里学习的怎么样?这段时间小编在家里也没闲着,时隔多日,再次为大家带来干货内容。 邻域搜索类启发式算法有很多种,比如禁忌搜索啦,模拟退火啦,变邻域搜索啦等等。这次带来的自适应大邻域搜索代码,相对上述几种会更复杂,编写相对全面。 小编在编写代码时,主要采用git-hub上一位作者de.markusziller的代码,...