今天谈的这个主题(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没有全球统一的标准,而是各个国家有自己的标准,比如中国的标准,欧洲的标准,美国的标准等。下表就是我们国家的标准:

谈谈语音通信中的各种tone-LMLPHP

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

谈谈语音通信中的各种tone-LMLPHP

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

谈谈语音通信中的各种tone-LMLPHP

其中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个比特),具体如下:

谈谈语音通信中的各种tone-LMLPHP

其中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值。

04-26 00:32