HowTo文档

如何在 XSwitch 中使用 ASR 及 TTS

随着人工智能的发展,ASR/TTS 技术也日臻成熟。与机器人对话,也渐渐成了人们日常生活的一部分。在此,我们来看一下如何使用 XSwitch 的 ASR/TTS 功能。

ASR 的全称是 Automatic Speech Recogonation,即语音识别,TTS 的全称是 Text To Speech,即文本到语音转换,也称语音合成。

通过使用 ASR/TTS,XSwitch 可以完成机器人自动智能语音交互,如电话通知、问卷调查、话费催收等。

配置 XSwitch 连接阿里云

XSwitch 有多个相关的 ASR/TTS 模块,下面在阿里云的智能语音交互服务中来说明。

关于阿里云 ASR/TTS 的 AI 产品说明可以参考https://help.aliyun.com/product/30413.html

连接阿里云 ASR/TTS 服务需要以下参数:

在此,我们使用 XSwitch 内置的mod_ali模块连接阿里云。进入【AI】⇨【阿里】⇨【ali】,在【Setting 参数】中填上阿里的acckeysecret,这是阿里云用户获取登录 Token 的接口。

在 TTS 和 ASR 参数中填上阿里云智能语音交互服务的appkey

配置完成后,到【高级】⇨【系统管理】⇨【系统模块】中,找到mod_ali,在控制列中点击【加载】,模块颜色由灰色变为黑色,表示加载成功。把启用改为【是】,以便下次 XSwitch 重启时能自动加载。

测试 TTS

到【呼叫】⇨【路由】中,新建一条路由:

  • 名称:tts,也可以随意
  • 被叫字冠:tts,也可以是其它号码,如1234
  • 呼叫源:default
  • 目的地类型:高级功能/系统

新出现的“文本”框中填入以下内容:

answer
speak ali|default|你好,欢迎致电烟台小樱桃网络科技有限公司

其中:

  • ali:TTS 引擎名称
  • default:TTS 发音人,也可以使用阿里文档中提供的其它发音人(voice)名称,如xiaoyun等。

注意:当发音人设置为default的时候会使用阿里云控制台中设置的默认发音人,未指定的情况下默认为xiaoyun,如需改动需要在控制台设置,同时,如果开启了缓存的情况,改动前请清除之前缓存的音频,避免出错。

提交后,用话机拨打tts号码就可以听到声音了。

也可以这样:

answer
set tts_engine=ali
set tts_voice=default
speak 你好,欢迎致电烟台小樱桃网络科技有限公司

测试 ASR

到【呼叫】⇨【路由】中,新建一条路由:

  • 名称:asr,也可以随意
  • 被叫字冠:asr,也可以是其它号码,如1234
  • 呼叫源:default
  • 目的地类型:高级功能/系统

新出现的“文本”框中填入以下内容:

answer
set tts_engine=ali
set tts_voice=default
play_and_detect_speech say:'你好,请说' detect:ali default
info
log err $${detect_speech_result}

打开【高级】⇨【扩展功能】⇨【终端】就可以看到日志。上面使用了err级别的日志是为了红色能显示的更醒目,便于调试。

注意:测试时不要使用免提或外放,因为如果话机终端不好的话,容易产生回音影响识别结果。如果是在电脑上的 SIP 终端,带上耳机测,如果是硬件话机,拿起听筒测。另外,听到声音立即说话,不要等它说完,也可以提高成功率。有很多其它方法可以解决外放时引起的识别不准问题,但超出了本文的范围,请咨询我们的技术支持工程师。

调试与排错

如果不能一次成功,可以通过终端上显示的日志内容跟踪调试。但 Web 界面上功能有限,高级的命令要进入 XSwitch 后台,使用如下步骤可以进入 XSwitch 控制台:

make bash
fs_cli
  • 在界面上检查所有配置参数是否输入正确。
  • 输入ali_token看是否正确获取到 Token。
  • 模块会定期获取 Token,日志中有类似如下的内容:Aliyun token expires after: 213431
  • 该模块的 TTS 会有缓存,默认位于/tmp/,可以在打完电话后输入ls /tmp查看是否有tts-开头的.wav文件。

高级应用

通过上述步骤,可以初步确定 XSwitch 已能正常提供 ASR/TTS 功能。在实际应用中,一般会多次交互,XSwitch 支持以下方式与系统交互:

  • Lua 脚本:可以直接在 XSwitch 中写 Lua 脚本交互
  • XSwitch XCC APIXCC API 示例中有很多各种语言的 TTS 及 ASR 的例子。
  • XSwitch AI API:该 API 可以使用 HTTP 接口控制 XSwitch(联系我们获取 API 文档)。

具体的例子我们后面再补充。

其它模块

其它模块操作也类似

  • mod_huawei:华为 ASR/TTS
  • mod_baidu:百度 ASR/TTS
  • mod_ifly:讯飞 ASR/TTS

详细的步骤请参考如何在 XSwitch 中使用 ASR 及 TTS(二)

MRCP

除了上述模块外,XSwitch 也支持通过 MRCP 连接 ASR/TTS,使用mod_unimrcp模块。

XSwitch 的 XUI 界面上没有提供 MRCP 的配置入口,使用时,需要手工修改相应的配置文件。XSwitch 内置了一个/usr/local/freeswitch/conf/mrcp/aliyun-sdm.xml配置模板。其中,客户端即 XSwitch,它会做为一个 MRCP 客户端连接 MRCP 服务器。

<include>
    <!-- Aliyun MRCP Server 7 MRCPv2 -->
    <profile name="ali" version="2">
      <!-- 客户端外部IP,如果在XSwitch与MRCP服务之间有NAT时需要配置 -->
      <!--param name="client-ext-ip" value="auto"-->
      <!-- 客户端IP,即XSwitch的IP,可以设置XSwitch使用的IP地址,或使用auto自动获取 -->
      <param name="client-ip" value="auto"/>
      <!-- 客户端端口号,根据需要配置 -->
      <param name="client-port" value="4090"/>
      <!-- MRCP服务器的IP -->
      <param name="server-ip" value="172.18.0.4"/>
      <!-- MRCP服务器的端口号 -->
      <param name="server-port" value="7010"/>
      <!--param name="force-destination" value="1"/-->
      <!-- SIP协议承载,支持TCP和UDP -->
      <param name="sip-transport" value="udp"/>
      <!-- 设置User-Agent头域 -->
      <!--param name="ua-name" value="FreeSWITCH"/-->
      <!-- 设置SDP中的origin字段 -->
      <!--param name="sdp-origin" value="FreeSWITCH"/-->
      <!-- 设置外网RTP地址,在NAT中需要设置 -->
      <!--param name="rtp-ext-ip" value="auto"/-->
      <!-- 使用的RTP IP,auto为自动获取 -->
      <param name="rtp-ip" value="auto"/>
      <!-- RTP端口号范围 -->
      <param name="rtp-port-min" value="4000"/>
      <param name="rtp-port-max" value="5000"/>
      <!--param name="playout-delay" value="50"/-->
      <!--param name="max-playout-delay" value="200"/-->
      <!-- 默认的打包间隔 -->
      <!--param name="ptime" value="20"/-->
      <!-- 使用的编码 -->
      <param name="codecs" value="PCMU PCMA L16/96/8000"/>
      <!-- 语法文件类型 -->
      <param name="jsgf-mime-type" value="application/jsgf"/>

      <!-- Add any default MRCP params for SPEAK requests here -->
      <synthparams>
      </synthparams>

      <!-- Add any default MRCP params for RECOGNIZE requests here -->
      <recogparams>
        <!--param name="start-input-timers" value="false"/-->
      </recogparams>
    </profile>
  </include>

可以使用如下方式进入容器修改该文件:

make bash
vi /usr/local/freeswitch/conf/mrcp/aliyun-sdm.xml

配置完成后,可以直接在命令行上使用命令load mod_unimrcp加载该模块,也可以在 XUI 界面上加载。

加载成功后,就可以使用了。可以将前面的例子中的 TTS/ASR 引擎名称由ali换成unimrcpunimrcp:ali,另外,也不能使用default当作发音人的名称,而需要使用合法的名称如xiaoyun等。

注意:该文件的修改在容器重建后将失效,如果需要永久存储,则需要将该文件存在宿主机上并在docker-compose.yml文件中增加挂载配置,如:

volumes:
  - ./aliyun.xml:/usr/local/freeswitch/conf/mrcp/aliyun-sdm.xml

详见《XSwitch 运维手册》

目前,大部分云厂商都提供在线的 ASR/TTS 服务,大部分都以 Websocket 服务提供。XSwitch 针对大部分云厂商专门写了相应的模块,效率高、效果好,且可以支持云厂商提供的所有功能和特性,如连续语音识别等。

MRCP 协议的全称是 Media Recource Control Protocol,是一个标准的访问媒体资源的协议,但是该协议比较老,而且也不适合互联网。虽然像阿里云等厂商也提供该协议,但只不过是增加了一层转换网关,增加了一个故障点,且完全浪费资源,示意图如下:

有 MRCP:

      SIP                                        MRCP协议               Websocket
话机 ------> [(mod_sofia) XSwitch (mod_unimrcp)] ---------> [MRCP服务器] --------> 阿里云服务器

没有 MRCP:

      SIP                                   Websocket
话机 ------> [(mod_sofia) XSwitch (mod_ali)] --------> 阿里云服务器

所以,尽量使用我们 XSwitch 原生的模块,节省资源。

除此之外,原生模块与 MRCP 服务器的另一个区别是,原生模块一般返回 JSON 数据,而 MRCP 会返回 XML 格式的数据。

当然,如果你的 ASR/TTS 厂商仅支持 MRCP 协议,那就这么用吧。

如果你在开发测试中需要离线 ASR/TTS,参见如何使用 XSwitch 内置的离线 ASR 及 TTS

如何使用XSwitch内置的离线ASR及TTS