HowTo文档

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

如何在 XSwitch 中使用 ASR 及 TTS中提到,XSwitch 内置了很多 ASR/TTS 模块,但大多数的 ASR/TTS 服务都是云厂商提供的。使用这些服务不仅需要有相应的账号,而且大部分也需要付费才能使用。在开发测试时,有时用起来就不能随心所欲。

为方便大家开发与测试,XSwitch 也提供了离线的 ASR 与 TTS。

tts_commandline

该模块是 XSwitch 内置的模块,XSwitch 提供了配套的espeak-ng,可以支持中文。

在命令行上加载模块:

load mod_tts_commandline

当然,也可以在 XUI 界面上加载,殊途同归。

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

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

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

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

然后就可以呼叫tts进行测试了。

注意,espeak-ng放出来的声音不好听,但对于开发测试来说,有总比没有好。另外,如果使用该模块切换语音的话(如经常进行中、英文切换),结果可能是未知的,有可能出现崩溃等情况。我们后续会给出一个更“好听”的使用方法,敬请期待。

在上述例子中,tts_commandline是模块名称(也是引擎名称、即tts_engine)、zh表示是中文语音(tts_voice)。除此之外,XSwitch 也支持所有 eSpeak NG 支持的声音,可以在 Linux 命令行上使用espaek-ng --voices查看,下面列表中第二列即为所有的语种名称,可以作为tts_voice参数:

$ espeak-ng --voices

Pty Language       Age/Gender VoiceName          File                 Other Languages
 5  af              --/M      Afrikaans          gmw/af
 5  am              --/M      Amharic            sem/am
 5  an              --/M      Aragonese          roa/an
 5  ar              --/M      Arabic             sem/ar
 5  as              --/M      Assamese           inc/as
 5  az              --/M      Azerbaijani        trk/az
 5  ba              --/M      Bashkir            trk/ba
 5  bg              --/M      Bulgarian          zls/bg
 5  bn              --/M      Bengali            inc/bn
 5  bpy             --/M      Bishnupriya_Manipuri inc/bpy
 5  bs              --/M      Bosnian            zls/bs
 5  ca              --/M      Catalan            roa/ca
 5  cmn             --/M      Chinese_(Mandarin) sit/cmn              (zh-cmn 5)(zh 5)
 5  cs              --/M      Czech              zlw/cs
 5  cy              --/M      Welsh              cel/cy
 5  da              --/M      Danish             gmq/da
 5  de              --/M      German             gmw/de
 5  el              --/M      Greek              grk/el
 5  en-029          --/M      English_(Caribbean) gmw/en-029           (en 10)
 2  en-gb           --/M      English_(Great_Britain) gmw/en               (en 2)
 5  en-gb-scotland  --/M      English_(Scotland) gmw/en-GB-scotland   (en 4)
 5  en-gb-x-gbclan  --/M      English_(Lancaster) gmw/en-GB-x-gbclan   (en-gb 3)(en 5)
 5  en-gb-x-gbcwmd  --/M      English_(West_Midlands) gmw/en-GB-x-gbcwmd   (en-gb 9)(en 9)
 5  en-gb-x-rp      --/M      English_(Received_Pronunciation) gmw/en-GB-x-rp       (en-gb 4)(en 5)
 2  en-us           --/M      English_(America)  gmw/en-US            (en 3)
 5  eo              --/M      Esperanto          art/eo
 5  es              --/M      Spanish_(Spain)    roa/es
 5  es-419          --/M      Spanish_(Latin_America) roa/es-419           (es-mx 6)(es 6)
 5  et              --/M      Estonian           urj/et
 5  eu              --/M      Basque             eu
 5  fa              --/M      Persian            ira/fa
 5  fa-latn         --/M      Persian_(Pinglish) ira/fa-Latn
 5  fi              --/M      Finnish            urj/fi
 5  fr-be           --/M      French_(Belgium)   roa/fr-BE            (fr 8)
 5  fr-ch           --/M      French_(Switzerland) roa/fr-CH            (fr 8)
 5  fr-fr           --/M      French_(France)    roa/fr               (fr 5)
 5  ga              --/M      Gaelic_(Irish)     cel/ga
 5  gd              --/M      Gaelic_(Scottish)  cel/gd
 5  gn              --/M      Guarani            sai/gn
 5  grc             --/M      Greek_(Ancient)    grk/grc
 5  gu              --/M      Gujarati           inc/gu
 5  hak             --/M      Hakka_Chinese      sit/hak
 5  hi              --/M      Hindi              inc/hi
 5  hr              --/M      Croatian           zls/hr               (hbs 5)
 5  ht              --/M      Haitian_Creole     roa/ht
 5  hu              --/M      Hungarian          urj/hu
 5  hy              --/M      Armenian_(East_Armenia) ine/hy               (hy-arevela 5)
 5  hyw             --/M      Armenian_(West_Armenia) ine/hyw              (hy-arevmda 5)(hy 8)
 5  ia              --/M      Interlingua        art/ia
 5  id              --/M      Indonesian         poz/id
 5  is              --/M      Icelandic          gmq/is
 5  it              --/M      Italian            roa/it
 5  ja              --/M      Japanese           jpx/ja
 5  jbo             --/M      Lojban             art/jbo
 5  ka              --/M      Georgian           ccs/ka
 5  kk              --/M      Kazakh             trk/kk
 5  kl              --/M      Greenlandic        esx/kl
 5  kn              --/M      Kannada            dra/kn
 5  ko              --/M      Korean             ko
 5  kok             --/M      Konkani            inc/kok
 5  ku              --/M      Kurdish            ira/ku
 5  ky              --/M      Kyrgyz             trk/ky
 5  la              --/M      Latin              itc/la
 5  lfn             --/M      Lingua_Franca_Nova art/lfn
 5  lt              --/M      Lithuanian         bat/lt
 5  lv              --/M      Latvian            bat/lv
 5  mi              --/M      Māori             poz/mi
 5  mk              --/M      Macedonian         zls/mk
 5  ml              --/M      Malayalam          dra/ml
 5  mr              --/M      Marathi            inc/mr
 5  ms              --/M      Malay              poz/ms
 5  mt              --/M      Maltese            sem/mt
 5  my              --/M      Myanmar_(Burmese)  sit/my
 5  nb              --/M      Norwegian_Bokmål  gmq/nb               (no 5)
 5  nci             --/M      Nahuatl_(Classical) azc/nci
 5  ne              --/M      Nepali             inc/ne
 5  nl              --/M      Dutch              gmw/nl
 5  om              --/M      Oromo              cus/om
 5  or              --/M      Oriya              inc/or
 5  pa              --/M      Punjabi            inc/pa
 5  pap             --/M      Papiamento         roa/pap
 5  pl              --/M      Polish             zlw/pl
 5  pt              --/M      Portuguese_(Portugal) roa/pt               (pt-pt 5)
 5  pt-br           --/M      Portuguese_(Brazil) roa/pt-BR            (pt 6)
 5  py              --/M      Pyash              art/py
 5  quc             --/M      K'iche'            myn/quc
 5  ro              --/M      Romanian           roa/ro
 5  ru              --/M      Russian            zle/ru
 2  ru-lv           --/M      Russian_(Latvia)   zle/ru-LV
 5  sd              --/M      Sindhi             inc/sd
 5  shn             --/M      Shan_(Tai_Yai)     tai/shn
 5  si              --/M      Sinhala            inc/si
 5  sk              --/M      Slovak             zlw/sk
 5  sl              --/M      Slovenian          zls/sl
 5  sq              --/M      Albanian           ine/sq
 5  sr              --/M      Serbian            zls/sr
 5  sv              --/M      Swedish            gmq/sv
 5  sw              --/M      Swahili            bnt/sw
 5  ta              --/M      Tamil              dra/ta
 5  te              --/M      Telugu             dra/te
 5  tn              --/M      Setswana           bnt/tn
 5  tr              --/M      Turkish            trk/tr
 5  tt              --/M      Tatar              trk/tt
 5  ur              --/M      Urdu               inc/ur
 5  uz              --/M      Uzbek              trk/uz
 5  vi              --/M      Vietnamese_(Northern) aav/vi
 5  vi-vn-x-central --/M      Vietnamese_(Central) aav/vi-VN-x-central
 5  vi-vn-x-south   --/M      Vietnamese_(Southern) aav/vi-VN-x-south
 5  yue             --/M      Chinese_(Cantonese) sit/yue              (zh-yue 5)(zh 8)

除此之外,XSwitch 也支持 Edge TTS,但需要手工安装依赖,详见如何在 XSwitch 中使用 Edge TTS

mod_ai

XSwitch 在mod_ai中提供了一个asr服务,可离线使用,效果还不错。使用开源的 Vosk 引擎。Vosk 引擎比较小,但是模型文件比较大,因而需要单独下载。

首先,进入宿主机上的storage目录,创建vosk目录,如下:

cd data/storage
mkdir vosk

到以下地址下载模型文件,解压后放到刚刚创建的vosk目录。

https://alphacephei.com/vosk/models

目前测试了以下几个模型:

  • vosk-model-cn-0.1 8k
  • vosk-model-small-cn-0.3 16k
  • vosk-model-small-en-us-0.15 16k
  • vosk-model-en-us-daanzu-20200328 16k

然后,到 XUI 上【AI】⇨【AI】⇨【default】中,配置 Asr-Models,启用相应的模型配置。配置完成后【重载】模块。

简单使用

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

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

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

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

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

上述命令中,也可以通过asr:ai:vosk-model-cn-0.1指定使用的模型。

使用方法

其中,asr engine 参数语法为:

engine[:model]

其中:model可以省略,如果省略,则使用能找到的第一个模型,如:

ai:vosk-model-cn-0.1     # 使用AI模块,8k语音模型
asr:ai:vosk-model-cn-0.1 # 使用AI模块,FreeSWITCH兼容模式,8k语音模型

在 XCC 中的用法

XCC 中,不需要asr:前缀,用起来更高效。

asr_engine = 'ai:vosk-model-cn-0.1'

params = {
	command = "xcc_detect_speech",
	data = {
		speech = {
			engine = asr_engine,
			grammar = "default",
			no_input_timeout = 5000,
			speech_timeout = 8000,
			partial_events = true,
			params = {
				language = 'zh-CN',
				-- "interim-results" = "true"
			}
		}
	}
}

在 Lua 中使用

FreeSWITCH 兼容用法(Lua):

session:execute("detect_speech", "asr:ai:vosk-model-cn-0.1 default default default")

其它

mod_ai模块实现了:

  • AI API:类似mod_httapi,但是用 JSON 代替 XML
  • ai ASR Interface:是一个 XCC 的 ASR,仅用于xcc_detect_speech,不适用于在核心中调用。
  • asr ASR Interface:是一个 XCC ASR 的包装器,通过使用asr:your-xcc-asr-interface-name可以将 XCC ASR 包装成系统原生接口使用。

XCC ASR 主要是取消了核心状态机,通过以下参数发送事件,事件驱动,而无须核心中的忙等待。

  • asr-result-fire-json-event:发送 JSON 事件,可以使用 JSON Event Channel 订阅ai_asr主题获取事件。
  • asr-result-fire-switch-event:发送原生 FreeSWITCH Detected Speech 事件,可以在 ESL 中获取。
  • asr-result-fire-session-event:发送 Sesion 事件,可以在 Lua onInputCallback 中回调。

XCC ASR 由于取消了核心状态机,实现比较简单。

asr ASR Interface 实现了一个包装器,通过 JSON Event Channel 与 XCC ASR Interface 通信。主题格式为:ai_asr.$channel_uuid,因此,channel-uuid参数是必须的。channel-uuid不一定是真正的 Channel UUID,只要是不重复的字符串就行,如果字符串发生重复,结果是未知的。

小结

本文提供的离线 ASR/TTS 仅为方便开发测试,效果不如云厂商提供的好,不建议在生产上使用。

在安装或使用XSwitch时遇到问题我该怎么办?