手机打电话时如何识别对方按下的DTMF按键的字符
--安卓AI电话机器人
- 一、前言
前面的篇章中,使用蓝牙电话拦截手机通话的声音,并对数据加工,这个功能出来也有一段时间了。前段时间有试用的用户咨询说:有没有办法在手机上,识别出通话时对方手机按下的DTMF按键?就那种电话打通了之后,语音提示对方“按1查话费、按2查流量、按0转人工”这种功能。之前检索了一下,Android系统截至目前,并未提供此类“DTMF解码器”的解析能力。
我们静下心来思考了一下,觉得这样的经典IVR场景的需求是非常合理的。以前我们都是建议用户直接对接到呼叫中心或CRM,由这种语音平台对通话中的DTMF频率进行解码和识别。但如果不接入呼叫中心呢?我们手机本身是否能够从语音中直接识别出来呢?
这也是本篇章内容编写的由来。用户的需求,就是我们产品演化的方向和动力。在本篇章中,我们从DTMF频率的组成、FFT过滤声音的频率,以及DTMF字符的识别等角度,一起探讨一下:Android手机中,如何通过手机app,识别出通话时对方手机到底有没有按键、按的是哪个dtmf按键。
这个课题方向,估计也比较新颖,因为一般也没有人去干这种事(一般情况确实也没有这个需求,打个电话谁会关注对方按什么键呢?又不是打摩斯密码)。但是从一般应用场景来看也确实有这个需求。
- 二、认识DTMF按键
我们一般使用电话座机或手机,拨打电话时,在振铃阶段或接通后,均可以按下键盘上的数字0-9、*、#等按键,把对应的DTMF按键值发送给对方。通话的对方接收该按键值后进行业务处理和反馈。
通常来说,人耳是无法区分不同的DTMF按键值的,这也是DTMF(双音多频)中传输的频率太高,远超出人耳能分辨的频率所致。按下按键后,通常人耳只能听到“嘟嘟”的按键提示音,具体解析要由对应的数学运算模块对语音进行处理和识别。
本篇是应用文,多余的理论就不在赘述,主要看下面这个图。对语音数据做FFT运算(从时空域转频域),把横坐标和纵坐标的两个频率确定了,DTMF的数字字符就出来了:
详细描述看这个网址:http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling,有空自己去参考。
- 三、对声音数据做FFT运算
FFT运算算是非常经典和基础的算法了,特别对于音频和视频图像处理领域。本来我们在做之前还在想,要不要将FFT和DTMF字符识别的功能,做成一个纯Java的jar包,供有需要的或感兴趣的同学在Android中试着调用。
但在实践中发现真没必要,直接使用TarsosDSP库就好,反正也就400KB左右,又不大。
具体案例可以参考GitHub上的开源示例代码:
https://github.com/GreyLabsDev/TarsosDSP-Example
下载下来后,将TarsosDSP-Android-2.4.jar文件丢到Android项目的app\libs目录即可。
具体的FFT运算和DTMF识别,可以参考DeepSeek中检索的代码(实际测试确实可用,不得不说,DS真TM好用。^V^),示例内容如下图所示:
- 四、识别出DTMF字符
这个也没什么技术含量,直接按上面章节的DTMF(双音多频)的频率,进行高频和低频的解析,然后判断后即可正常识别出对方按下的DTMF按键字符。
DeepSeek中检索的内容这里也直接贴出来了,可以直接用。有兴趣的可以参考或自己在里面按关键字来提问获取代码。
有两点需要特意注明一下:
1、声音的DTMF解码处理,最好放到新的子线程当中去执行。这样可以不干扰原有业务的语音播放和识别处理。子线程中大多数时间都不反馈DTMF字符,如果有的话单独另外处理上抛的消息即可。
2、20ms一包的语音数据(每包数据320 字节)的FFT 的分辨率较低。通常需要缓存多包数据(如 40ms 或 80ms)来提高频率检测的准确性。按照一般理论,8k采样率下,采样点数量为205时,FFT运算的精度和识别的效果最好。
- 五、最终输出结果
子线程中FFT运算后上抛的DTMF按键值,基本上准确率还是比较高的。但由于每次DTMF音的时长较长,需要对识别的按键结果做去除重复的处理。
在运算性能上,由于本篇针对的是语音通话的上行数据做的处理。运算量非常的小,测试结果表明,Android手机上DTMF软解码功能的引入,对app的运算性能几乎可以忽略不计,放心大胆的用。
- 六、总结
本篇这个课题,通话时解码对方按下的DTMF按键值这种需求,正常使用手机的人群,偶尔可能会有这个想法一闪而过,但估计一般人也没有这个需求。毕竟我们打电话都是用人耳来接听,但人耳是无法分辨DTMF的“嘟嘟”声的。
这里之所以会出现识别的需求,前提条件是蓝牙电话方案中,已经能将手机SIM卡通话的声音给提取了出来。在这个基础之上,扩展出在手机本地进行DTMF识别来对接本地的IVR或AI电话机器人。
目前看起来,从语音中提取DTMF按键字符,还是非常简单的。在通话语音数据中挂一个子线程,把数据丢进去,等待它识别字符并上抛出来就行。
本篇章的内容,除了对手机声音IVR/AI处理功能比较刚需之外,对于的SIP坐席电话的数据处理,也能起到一定的参考作用。