做音频软件开发10+年,包括语音通信、语音识别、音乐播放等,大部分时间在做语音通信。做语音通信中又大部分时间在做VoIP语音处理。语音通信是全双工的,既要把自己的语音发送出去让对方听到,又要接收对方的语音让自己听到。发送又可叫做上行或者TX,接收又可叫做下行或者RX。之前写了好多关于VoIP语音处理方面的文章,本文想结合框图对相关知识做一个梳理。先综述发送和接收方向的处理,再具体到每个知识点上。讲到某个知识点,如曾经写过相关的文章,就给出链接,如没有写过,等以后写到时再补上链接。由于一些知识点在发送和接收两个方向上是相关的,就放在一起讲。

VoIP语音处理在发送和接收方向上的软件框图如下图1和2:

图1:发送方向处理流程框图

图2:接收方向处理流程框图

在发送方向,从codec芯片采集到语音PCM数据后如有需要首先做重采样(SRC),然后做前处理(回声消除/AEC,噪声抑制/ANS,增益控制/AGC,俗称3A算法)。后面就是做静音检测(VAD),如是语音就编码(ENC),得到码流并通过RTP/UDP发送给对方。如是静音,就生成静音包(SID) 也通过RTP/UDP发送给对方。在弱网情况下为了提高语音质量,就需要前向纠错(FEC)、重传等手段把相应的包发给对方。一些场景下需要把tone音(比如 DTMF tone)发送给对方,先要做tone音检测(tone detection),然后按照SIP协议协商好的方式把tone音发送给对方。在发送RTP包的同时,也需要发送RTCP包来监控RTP包的收发情况等。

在接收方向,先收到对方发来的RTP/RTCP包。对于RTP包,如是正常包或者重传包,直接放进jitter buffer(后面简称JB),这些包有可能被JB收下,也有可能被JB丢弃(比如包来的太迟或者重复包等)。如是FEC包,先做FEC解码,再把解码后的RTP包放进JB。同样也有可能被JB收下或者丢弃。从JB里取出的如是语音包,就需要做解码(DEC),根据网络状况还可能要做丢包补偿(PLC)、加速、减速、融合等处理。如取出的是静音包(SID),则需要产生舒适噪声(CNG)。如取出的是RFC2833包,就要产生相应的tone音(tone generation)。处理好后还要经过噪声抑制(ANS)/增益控制(AGC)等处理,有可能的话还需要做重采样(SRC)。最后把PCM数据送给codec芯片播放出去。

下面看具体的知识点:

1,语音的采集和播放:主要是从codec芯片采集到语音得到PCM数据和把PCM数据发送给codec芯片播放出来,不同的OS下有不同的方法。曾经写过相关的文章,具体见《音频的采集和播放》。

2,重采样(SRC):就是把PCM的采样率从一种变成另一种。在音频处理中经常遇到采样率不一样的情况,需要做重采样。曾经写过怎么对开源的重采样算法做评估,从而觉定用哪个,具体见《音频开源代码中重采样算法的评估与选择》。也写过基于sinc方法的重采样的原理和实现,具体见《基于sinc的音频重采样(一):原理》和《基于sinc的音频重采样(二):实现》。

3,前后处理的3A算法:包括AEC/ANS/AGC等,他们是保证音质的关键因素之一。AEC是回声消除,曾写过AEC的基本原理和调试经验(算下来我前前后后共四次调试过AEC),具体见《音频处理之回声消除及调试经验》。ANS是噪声抑制,2021年我花了不少时间在ANS上,从学习原理到看懂代码以及自己写算法代码。也写了三个算法的系列,分别是webRTC里的ANS和基于MCRA-OMLSA的ANS以及基于混合模型的ANS,具体见《webRTC中语音降噪模块ANS细节详解(一)》、《 webRTC中语音降噪模块ANS细节详解(二)》 、《webRTC中语音降噪模块ANS细节详解(三)》、《 webRTC中语音降噪模块ANS细节详解(四)和 《基于MCRA-OMLSA的语音降噪(一):原理 》 、《基于MCRA-OMLSA的语音降噪(二):实现》、《基于MCRA-OMLSA的语音降噪(三):实现(续)》 以及《语音降噪论文“A Hybrid Approach for Speech Enhancement Using MoG Model and Neural Network Phoneme Classifier”的研读 》、《基于混合模型的语音降噪实践 》、《基于混合模型的语音降噪效果提升 》。AGC是自动增益控制,是控制语音信号的增益在预设的合理区间之内,避免忽大忽小。目前这一块还没有相关的文章。

4,静音检测(VAD)和舒适噪声生成(CNG):VAD会根据预先设定的threshold判断是语音还是静音。如果是语音就要去做编码,如果是静音则不需要编码,仅仅是周期性的(比如200毫秒)发送一个带能量大小的SID包给对方,对方收到这个包后去做CNG产生舒适噪声,让通话者感觉更舒服些。用VAD/CNG主要有两个好处:一是节省了带宽,通常语音通话中一方只占50%左右的讲话时间,其余时间处于静音状态。在静音时发送SID包,SID包比正常语音包小不少,发的频率也低好多,这样就节省了带宽。二是降功耗,在静音期间不需要编解码了,通常编解码的运算load比VAD/CNG高,这样就降低了功耗。目前还没有这方面的文章。

5,编解码(ENC/DEC):常用的codec有ITU-T的G系列(g.711/g.722/g.726/g.729等)、3GPP的AMR-WB/AMR-NB/EVS以及互联网厂商提出的iLBC/OPUS等。曾在文章《音频的编解码及其优化方法和经验 》中写过基于reference code去优化CPU load。

6,前向纠错(FEC)和重传:在弱网情况下需要保证音质,就得有一些补救措施,FEC和重传就是其中两种。FEC是在发送端编码生成冗余包,在接收端解码从而生成那些丢掉的包。重传是把对方需要的包发给对方。曾在文章《语音通信中提高音质的方法 》讲过这两种方法,当然也讲了其他的提高音质的方法。

7,RTP/RTCP/UDP:这三个都是网络协议,RTP是网络传输协议,RTCP是网络传输控制协议,UDP是数据报协议。在文章《语音传输之RTP/RTCP/UDP及软件实现关键点》里讲了它们的软件实现关键点。

8,tone音:一些场景下会用到tone音,比如DTMF tone,包括tone音检测(tone detection)和tone音生成(tone generation)。文章《谈谈语音通信中的各种tone 》详细的讲了tone音以及发送给对方的三种方式。

9,jitter buffer(JB):把从网络收到的RTP包放进JB里缓一下,同时把乱序的包排好序等,有利于播放的流畅。文章《音频传输之Jitter Buffer设计与实现 》写了我曾经设计过的一个JB。

10,netEQ:是webRTC里提出的概念,把JB、解码和解码后的PCM处理(加减速播放、丢包补偿(PLC)等)放在一起形成一个模块。也就是接收方框图中画虚线的部分。我曾经写过一个系列详细介绍了netEQ,大家对这个系列的评价还是不错的,具体见《webRTC中音频相关的netEQ(一):概述 》 《webRTC中音频相关的netEQ(二):数据结构 》 《webRTC中音频相关的netEQ(三):存取包和延时计算 》《 webRTC中音频相关的netEQ(四):控制命令决策 》和 《webRTC中音频相关的netEQ(五):DSP处理 》。

以上就是VoIP语音处理中的主要知识点。需要说明的是一个VoIP语音处理解决方案中以上模块并不全是必须的,而是根据需求选用的。当然有些是必须的,比如编解码。上面的框图只是把涉及到的知识点列出来,框图画的可能不是十分的准确。有些模块(比如提高音质的一些方法)我没用过,就没画出来。写这篇文章的目的只有一个,就是让大家知道VoIP语音处理的流程和其中有哪些知识点。

VoIP语音处理流程和知识点梳理的更多相关文章

  1. Javascript重要知识点梳理

    Javascript重要知识点梳理 一.Javascript流程控制 js中常用的数据类型 var关键字的使用 if – else if – else switch while for 二.Javas ...

  2. Memcache知识点梳理

    Memcache知识点梳理 Memcached概念:    Memcached是一个免费开源的,高性能的,具有分布式对象的缓存系统,它可以用来保存一些经常存取的对象或数据,保存的数据像一张巨大的HAS ...

  3. [独孤九剑]Oracle知识点梳理(十)%type与%rowtype及常用函数

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  4. [独孤九剑]Oracle知识点梳理(九)数据库常用对象之package

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  5. [独孤九剑]Oracle知识点梳理(八)常见Exception

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  6. [独孤九剑]Oracle知识点梳理(七)数据库常用对象之Cursor

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  7. [独孤九剑]Oracle知识点梳理(六)数据库常用对象之Procedure、function、Sequence

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  8. [独孤九剑]Oracle知识点梳理(五)数据库常用对象之Table、View

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  9. [独孤九剑]Oracle知识点梳理(四)SQL语句之DML和DDL

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

随机推荐

  1. scrapy爬取招聘网站,items转换成dict遇到的问题

    pipelines代码 1 import json 2 3 class TencentJsonPipeline(object): 4 def __init__(self): 5 self.file = ...

  2. Mysql解决主从慢同步问题

    目录 一.简介 为何有延迟 二.观察 三.解决办法 参数 多线程 组提交 一.简介 一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) ----->IO Thread (从) ...

  3. [BUUCTF]PWN——roarctf_2019_easy_pwn(详解)

    roarctf_2019_easy_pwn 附件 步骤: 例行检查,64位程序,保护全开 试运行一下程序,看看大概的情况,经典的堆块的菜单 64位ida载入,改了一下各个选项的函数名,方便看程序(按N ...

  4. CF1036A Function Height 题解

    Content 给定一个坐标系,在它的 \(x\) 轴上有 \(2n+1\) 个点 \(P_0,P_1,P_2,...,P_{2n}\),其中对于 \(0\leqslant i\leqslant 2n ...

  5. CF1437A Marketing Scheme 题解

    Content 有 \(t\) 组询问,每组询问给定两个整数 \(l,r\),问是否存在一个 \(a\),使得 \(\forall x\in[l,r]\),都有 \(x\mod a\geqslant\ ...

  6. yum安装curl支持http2

    yum 安装 安装 yum 源 rpm -ivh http://mirror.city-fan.org/ftp/contrib/yum-repo/city-fan.org-release-2-1.rh ...

  7. Tornado 的安全性保障机制Cookie XSRF跨站请求伪造阻断 &用户验证机制

    6.1 Cookie 对于RequestHandler,除了在第二章中讲到的之外,还提供了操作cookie的方法. 设置/获取 注意:Cookie 在浏览器调试时, 只有在第一次访问该网站的时候获取到 ...

  8. IPtables 之“四表五链”

    目录 架构图 IP tables 简介 包过滤防火墙 Iptables如何过滤 "四表" "五链" Iptables流程 架构图 公司架构模式(酒店迎宾比喻) ...

  9. Linux使用tar解压的时候去掉父级目录

    去除解压目录结构使用  --strip-components N 如: 压缩文件text.tar 中文件信息为 src/src1/src2/text.txt 运行 tar -zxvf text.tar ...

  10. windows平台使用 pthreads库

    note 近日封装一些跨平台库时, 发现线程的创建需要做平台的区分, windows的线程创建和Linux下的线程操作不一样.很麻烦,还要做平台区分. 能否在windows上使用pthread的线程库 ...