谈谈语音通信中的各种tone

今天谈的这个主题(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个比特),具体如下:

packages/services/Telecomm/src/com/android/server/telecom/InCallTonePlayer.java,该类用于通话中提示音的播放。
case TONE_RING_BACK:
toneType = ToneGenerator.TONE_SUP_RINGTONE;
toneVolume = RELATIVE_VOLUME_HIPRI;
toneLengthMillis = Integer.MAX_VALUE -TIMEOUT_BUFFER_MILLIS;
                  break;
----------------------------------------------------------------------------------------------
Also please enable telecom log to collect the dut and ref logs. Thanks 

adb reboot  
adb wait-for-device  
adb shell setprop log.tag.TelecomFramework VERBOSE  
adb shell setprop log.tag.Telecom VERBOSE  
adb shell setprop log.tag.Telephony VERBOSE  
adb shell setprop log.tag.InCall VERBOSE  
adb shell setprop log.tag.QImsService VERBOSE  
DONOT reboot after this 

猜你喜欢

转载自blog.csdn.net/keyanting_2018/article/details/84105676