今天谈的这个主题(tone)存在于我们的日常打电话过程中。先举两个场景:1,你拿起固话话筒准备打电话,按电话号码前先从话筒里听到“嗡”的连续音,这叫dial tone(拨号音,表示你可以拨电话号码了),你拨完号码对方振铃后你又听到有规律的“嘟-嘟-”的断续音,这叫ring back tone(回铃音,表示对方已振铃了)。2,你给企业服务号(比如中国移动的10086)打电话,对方叫你按键选择,当你按下键后会听到按键声,这叫DTMF tone(双音多频音)。感觉到它存在于我们日常的打电话过程中了吧。现在我们就从技术的角度谈谈这些tone。

在语音通信中tone主要分两大类:CPT(call progress tone,呼叫过程音)tone和DTMF(dual tone multi frequency,双音多频音)tone。CPT tone存在于通话过程中,主要用于告诉用户目前在什么状态,主要有dial tone(拨号音)/ringback tone(回铃音)/busy tone(忙音)等。CPT tone是单频音,即由一个频率的正弦波形成。CPT tone没有全球统一的标准,而是各个国家有自己的标准,比如中国的标准,欧洲的标准,美国的标准等。下表就是我们国家的标准:

还有其他类型的CPT tone,由于用的相对较少,这里就不一一列出了。相对于CPT tone是单频音,DTMF tone是双频音,即用两个频率(一个高频和一个低频)的正弦波叠加去表示某个按键值。与CPT tone各国有自己的标准不同的是DTMF tone全球有统一的标准,下表列出了常用的16个按键值是由哪些高频音和低频音组合而成的:

从软件实现的角度对tone主要有两类处理:tone generation,让用户听到tone;tone detection,主要是指DTMF tone的detection,让软件知道哪个按键按下了,好进行后续的处理。我们先看tone generation,也就是生成单个频率的正弦波(CPT tone)或者两个频率正弦波的叠加(DTMF tone),在信号处理上有相应的算法。对于单频正弦波,各个采样点上值的生成可通过如下的数学表达式求得:

其中a/y(0)/y(1)在各个频点上的值已事先根据数学公式做成表,从而减少数学运算。对于DTMF这样的双频率音来说,采样点上的值就是两个频率采样点上的值相加。Tone generation分两个方向,local 和remote。Local是tone让自己听到,把生成的正弦波放到RX stream上;remote是tone让对端听到,把生成的正弦波放到TX stream上。对于像ring back tone等断续音还需要timer控制放多长时间停多长时间。

再来看tone detection,这里主要是指对DTMF的tone detection。有专门的算法(Goertzel戈泽尔算法)来detect DTMF的键值,把DTMF的音频信号(多帧的PCM信号)作为算法的输入,经过一定帧数后得到的就是DTMF的键值。原理这里就不详细讲了,有兴趣的可以看相关文章。有时候我们需要告诉对端按下的是什么DTMF键,即要把键值传给对端,主要有三种方法,具体如下:

1,把DTMF音频信号直接编码得到码流放在RTP中发给对端。对端收到RTP包后解码复原出音频信号,然后再通过DTMF detection算法得到键值。这通常被叫做in-band方法。

2,在本端做DTMF detection得到键值,然后根据RFC2833(后来升级成RFC4733)组成RFC2833包发给对端。对端收到RFC2833包后去解析就知道是哪个键值了。这通常被叫做out-of-band方法。RFC2833包也是用RTP做承载,不过它的payload type是动态的(96~127之间一个值),payload共4个字节(32个比特),具体如下:

其中bit0-7(共8位)表示键值,bit8表示DTMF按键结束,bit9目前保留不用,bit10-15(共6位)表示按键信号的level(dBm表示),bit16-31(共16位)表示按键持续的时间(以采样值为单位)。一个DTMF键会生成多个RFC2833包,对同一个键值而言,这些包的sequence number会每次加1,但是timestamp不变,duration会持续增加,以8k采样率20ms为一包为例,第一个RFC2833包duration为160,第二个RFC2833包duration为320,依次向上加,直到END包(bit8置1)结束。END包会发3次(发3 次主要是为了防丢包),每个END包sequence number会加1,但是duration保持不变。

3,在本端做DTMF detection得到键值,然后通过SIP信令的INFO带给对端,让对端知道是哪个键值。

这三种方法中,具体用那种方法要看双方设备的支持程度,在SDP中有个协商的过程,最终选用双方都支持的一种方法(如果双方都支持多种方法,还有一个优先级来控制选择哪种方法)来传送DTMF值。

谈谈语音通信中的各种tone的更多相关文章

  1. 语音通信中终端上的时延(latency)及减小方法

    时延是语音通信中的一个重要指标,当端到端(end2end)的时延(即one-way-delay,单向时延)低于150Ms时人感觉不到,当端到端的时延超过150Ms且小于450Ms时人能感受到但能忍受不 ...

  2. 如何在嵌入式Linux上开发一个语音通信解决方案

    开发一个语音通信解决方案是一个软件项目.既然是软件项目,就要有相应的计划:有多少功能,安排多少软件工程师去做,这些工程师在这一领域的经验如何,是否需要培训,要多长时间做完,中间有几个主要的milest ...

  3. 浅谈传统语音通信和APP语音通信音频软件开发之不同点

    本人在传统的语音通信公司做过手机和IP电话上的语音软件开发,也在移动互联网公司做过APP上的语音软件开发.现在带实时语音通信功能的APP有好多,主流的有微信语音.QQ电话.钉钉等,当然也包括我开发过的 ...

  4. 腾讯云H5语音通信QoE优化

    本文首发在云+社区,未经许可,不得转载. 云+导语:4月21日,腾讯云+社区在京举办"'音'你而来,'视'而可见--音视频技术开发实战沙龙",腾讯音视频实验室高级工程师张轲围绕网络 ...

  5. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  6. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  7. 谈谈MVC项目中的缓存功能设计的相关问题

    本文收集一些关于项目中为什么需要使用缓存功能,以及怎么使用等,在实际开发中对缓存的设计的考虑 为什么需要讨论缓存呢? 缓存是一个中大型系统所必须考虑的问题.为了避免每次请求都去访问后台的资源(例如数据 ...

  8. Android IOS WebRTC 音视频开发总结(七五)-- WebRTC视频通信中的错误恢复机制

    本文主要介绍WebRTC视频通信中的错误恢复机制(我们翻译和整理的,译者:jiangpeng),最早发表在[这里] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:blac ...

  9. 使用SSL确保通信中的数据安全

    #region Server /// <summary> /// 用于保存非对称加密(数字证书)的公钥 /// </summary> private string public ...

随机推荐

  1. MyBatis之基于XML的动态SQL

    先说下我的梦想,大学的时候一直想着是能开店卖胡辣汤,到目前依然还是我的梦想,上周一家出版社联系我问我有没有时间可以合作出书,这也是我的梦想之一,想了想还是放弃了,至少觉得目前不行,毕竟工作还不到五年, ...

  2. 【编程技巧】alert vs Ext.Msg.alert

    alert会阻塞程序的运行. Ext.Msg.alert是异步的,它的调用并不会停止浏览器中代码的执行.

  3. MySql优化子查询

    用子查询语句来影响子查询中产生结果rows的数量和顺序. For example: SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM ...

  4. java中的nextLine

    package scanner; import java.util.Scanner; public class NextLine { public static void main(String[] ...

  5. python基础8之自定义模块、if __name__==__main__:解释

    一.自定义模块与使用 python模块说明:类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  6. Spring @Scheduled 在tomcat容器里面执行两次

    今天在用spring里面的@Scheduled执行定时任务,但是发现到触发定时任务的时间点总会执行两次.原因是修改了tomcat conf包下面的server.xml文件导致的.配置如下: <H ...

  7. float是什么样式?

    什么是float样式? 让标签浮动起来,总体方向往上 right,left(右浮,左浮) 联合height,width使用,分别占用y方向和x方向多少,单位px或百分比(%) 作用对象不是页面,而是作 ...

  8. android studio获取sha1签名

    转载 :http://blog.csdn.net/kezhongke/article/details/42678077

  9. 日历插件——laydate.js

    laydate是一款很好用的日历控件,兼容了包括IE6在内的所有主流浏览器,默认有三种皮肤,如需其它皮肤可去官网下载http://www.layui.com/laydate/  一.核心方法:layd ...

  10. ATS日志说明

    在ATS日志中我们经常遇到形形色色的缓存结果码,为了更清晰地认识它们,相关资料整理到这里: TCP_HIT 请求对象的一份合法拷贝被缓存,ATS将发送该对象给client TCP_MISS 请求对象未 ...