DTMF信号的生成

一个DTMF信号由两个单音频正弦信号所组成,即每个DTMF信号需包含一个来自低频组中的某个低频成分和一个来自高频组中的某个高频成分。所以有16种不同的组合表示16个唯一的按键信息:0-9数字键和A-F功能键。

生成DTMF信号的思路是,按下的键在计算机中识别的是ASCII码值,为了与具体的号码一一对应,数字所代表的ASCII码需要通过减去0x30,字母所代表的ASCII码需要减去0x37,从而得到相应具体的按键。按下一个按键有持续时间Tc,每个按键的间隙有静音时间Ts,DTMF信号的数据点数=采样频率每个按键及中间静音的时间和按键的个数。

通过把0~9A~F所对应的DTMF信号频率根据低频高频顺序排列成一个频率数据数组,根据按下的键所对应的具体符号可以在频率数据数组中找到相应的高低频,进而可以完成产生DTMF信号的工作。

DTMF信号的检测

最终的目标是要用goertzel算法检测并分析出一连串按键具体是对应的是哪些符号。
检测中用到的goertzel算法,主要是两个公式,一个是v[n] = dtmf_out[n] + goertzl_fre_F[i]*v[n-1]-v[n-2].这个公式的作用是更新迭代每一个dtmf信号进来的递归数据,其中goertzel_fre_F[i]是由需要检测的那个频率点决定的,v[n-1]是和前一个输入信号数据有关,同理v[n-2]是和前两个的输入信号数据有关。由于需要更新递归,即v[n]的数据要传给v[n-1],而v[n-1]的数据要传给v[n-2]。另一个公式为|y[n]^2| = v[n]^2 + v[n-1]^2 - goertzel_fre_F[i]*v[n]*v[n-1],目的是通过每次输入的dtmf数据得到的递归量v[n]和v[n-1]来计算每个数据点的输出能量。

具体检测思路是,用检测固定8个频率点的goertzel滤波器并行操作,DTMF信号输入,经过每次递归都输出一个输出能量。因为每个频点滤波器都会输出和DTMF信号数据同样多的能量数据点,所以最后通过8个goertzel滤波器的输出能量图中应当表现为当检测到了对应按键的DTMF信号中存在的频率,对应数据点的能量值很大,而在这个频点滤波器上的不包含此频率的按键信号输出能量值则是前者的1/10左右。需要注意的是,倘若输出能量图中出现了震荡严重的情况,需要在goertzel滤波器的基础上再增加一个环路滤波器,可以滤除过于严重的震荡点,使得波峰震荡的程度减缓,从而得到更好的输出。

当8个频点滤波器把所有的DTMF输入数据检测完之后,需要开始判断具体是输入的哪些按键符号。在4个低频goertzel滤波器输出中,需要在每一个按键符号的时间段内判断出一个最大值,而且这个最大值要大于设定的门限。如果是在matlab上仿真,由于输出的是一系列的能量值,在大于门限值的第一个点到小于门限值时的那个点范围内就是按键符号的低频信号范围。同理4个低频输出的高于门限的信号点范围都可以得到。

对于4个高频goertzel滤波器输出也一样,在高于给定门限下检测出的高频信号点范围需要和低频信号点范围取交集,规定交集持续的时间要大于40ms,如果小于40ms就判断不存在按键信号。最后根据交集中低频高频对应的符号参数,经过查表得到最后输入的按键符号。