TYS的博客

算法小白努力学习中

0%

DTMF信号检测与识别

DTMF信号的检测与识别

1. 程序设计思路与框图

1.1 FFT直接计算

利用FFT计算输入的信号的DFT频域信息,并找到两个峰值频率点,从而检测DTMF信号。

  • 数据预处理,作业给定的为.wav文件,其中数据为16bit的short类型,文件指针偏移40个字节的位置记录了wav数据块的字节数,调用read函数将之后的数据读入到数组中。

  • 编写类FFTMethod,调用第一次作业编写的时域基2DFT对音频信号做FFT变换。找到频域中两个峰值对应的数字角频率,从而计算得到模拟角频率,找到对应的DTMF信号

  • 程序框图

    image-20201215223342850.png

1.2 Goertzel 算法

计算FFT包含了信号整个频域的信息,而我们只关注DTMF信号的八个特定频率,因此算法存在冗余。在FFT中如果我们只关注某一个特定的数字角频率,$X[k] = \sum_{n = 0}^{N- 1}x[m]W_n^{m -N}$,其可以视为$x[n]$通过冲激响应为$W_N^{-nk}$的LTI系统在N时刻的取值。第k个频点对应的差分方程为:
$$
V_k[n] = 2cos(\omega_k)V_k[n - 1] - V_k[n-2] + x[n] \
X_k[n] = V_k[n] - W_N^k[n - 1], v[-1] = v[-2] = 0
$$
其本质是一个动态规划的过程,由递推关系可以得到n时刻的状态,从而确定该频点的FFT。得到八个特定频点的FFT值后,选择两个峰值,从而确定DTMF信号。

image-20201215224401308.png

1.3一串DTMF信号的识别

下图为一串DTMF信号的时域图像,可以看到其中包含了15个DTMF信号,我们要做的工作是确定每一个信号的起始于结束位置,直接使用强度值进行判断存在较大的误差,因此选择滑动窗取平均的方式。程序中选择滑动窗大小为64,计算信号每个点对应的滑动窗内的平均能量,并与阈值作比较,从而确定每一个信号的起始结束位置。之后将每一段信号采用上述的两种方法进行信号判断

image-20201215224445627.png

  • 程序框图
image-20201215225103976.png

2.两种算法的结果与复杂度比较

实验结果:

image-20201215225340386.png

复杂度分析:

  • FFT方法采用DFT计算了所有的频点信息,时间复杂度为$O(nlogn)$,寻找峰值的复杂度为O(n),总的时间复杂度为$O(nlogn) + O(n)$

  • Goertzel方法只计算特定的8个频点,并采用差分方程的形式递推计算,时间复杂度为O(n)

  • FFT方法需要存储所有的频域信息,空间复杂度为$O(n)$, Goertzel方法在递推过程中只需要V[i-1]、V[i-2]这两个状态, 空间复杂度为$O(1)$