Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3274755
  • 博文数量: 346
  • 博客积分: 10189
  • 博客等级: 上将
  • 技术积分: 3125
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-05 19:46
文章分类

全部博文(346)

文章存档

2013年(35)

2011年(35)

2010年(76)

2009年(48)

2008年(152)

分类: C/C++

2011-10-14 14:22:41

一个DTMF信号由两个频率的音频信号叠加构成。这两个音频信号的频率来自两组预分配的频率组:行频组或列频组。每一对这样的音频信号唯一表示一个数字或符号。产生DTMF信号,就是利用两个不同频率的正波叠加以后形成的波形,解码时则采用改进的Goertzel算法,从频域搜索两个正弦波的存在。
RTP媒体传输中携带DTMF信号。

该方法是将DTMF信号和媒体流一样,用RTP包来传输,因而没有DTMF信号和媒体流不同步的问题,使用H323信令的VOIP就是采用该种方法,相对来说比较成熟。

而其中又分In bandOut of bandRFC2833)两种。

l         In Band DTMF

In Band DTMF是指直接将DTMF的音频数字信号不经任何处理直接打成RTP包在IP网中传输。其中可能和用户的语音媒体流混合(mix)在一起传输。程序要获知哪个包有DTMF信号,是什么DTMF信号,必须实时检查每个RTP包里面的媒体流数据,分析它的频域。

l         Out of Band DTMF(RFC 2833)

Out of Band DTMFDTMF信号用专门的RTP包进行标识,在RTP包的头域中就可得知该包是DTMF包,并且知道是什么DTMF信号。RFC2833专门对此有定义。

动态生成DTMF音频信号

当程序需要产生一个DTMF音频数字信号时,当然可以读取已经录制好的文件。

在这里介绍如何利用算法程序动态产生单个DTMF音频数字信号。

前面介绍过DTMF信号的原理是两个不同频率的正弦波叠加。

简单的生成正弦波的公式:sample=sin(n*2*PI*f/samplerate)

n:采样序数,由0开始递增

f:正弦波的频率

samplerate:采样频率

sample:序数n时的得出的采样值

如果要生成一个采样频率是8000hz,采样位是8bitDTMF信号,则公式:

sample(n) = 128 + 63*sin(n*2*pi*f1/8000) + 63*sin(n*2*pi*f2/8000)

f1f2分别是该DTMF信号的两个正弦波频率

其中128 = 256/2

63 = 128 /2 – 1

同样地,如果要生成16bitDTMF信号,则公式:

sample(n) = 32768 + 16383*sin(n*2*pi*f1/8000) + 16383*sin(n*2*pi*f2/8000)

 

计算DTMF信号是一个耗费资源的过程,你可以通过不同途径去优化你的代码,最简单的是预先计算好2*pi*f12*pi*f2的值,减少CPU的计算时间。

 

关于DTMF信号的时间间隔,CCITT对DTMF信号规定的指标是,传送/接收率为每秒10个数字,即每个数字100ms。代表数字的音频信号必须持续至少45ms,但不超过55ms。100ms内其他时间为静音,以便区别连续的两个按键信号。

根据RTP包中的音频信号检测DTMF信号

在输入信号中检测DTMF信号,并将其转换为实际的数字,这一解码过程本质是连续的过程,需要在输入的数据信号流中连续地搜索DTMF信号频谱的存在。

整个检测过程分两步:首先采用Goertzel算法在输入信号中提取频谱信息;接着作检测结果的有效性检查。
Goertzel
算法
DTMF解码即是在输入信号中搜索出有效的行频和列频。计算数字信号的频谱可以采用DFT及其快速算法FFT,而在实现DTMF解码时,采用Goertzel算法要比FFT更快。通过FFT可以计算得到信号所有谱线,了解信号整个频域信息,而对于DTMF信号只用关心其8个行频/列频及其二次谐波信息即可(二次谐波的信息用于将DTMF信号与声音信号区别开)。此时Goertzel算法能更加快速的在输入信号中提取频谱信息

阅读(4845) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~