[原创] 在树莓派上把文字转成语音(Text-To-Speech/TTS)

本文软硬件环境:
树莓派:3代 Model B V1.2,内存1GB
OS:Arch Linux ARM

有时候,我们需要在程序中添加文字转语音的功能,即通过某个程序或API,把输入的文字朗读出来,也就是通常所说的 text-to-speech(简写为TTS)。我尝试了一个简单的方案——使用Espeak来完成这个任务,在这里记录下来。

『1』TTS方案
我们可以使用本地的TTS软件,也可以使用云端的TTS服务来实现文字转语音。使用本地TTS软件的好处就是不需要联网,云端的TTS服务通常提供更好的语音转换效果,不过也通常麻烦得多得多——例如,需要写程序来发送数据、接收返回数据等。
本地的TTS软件非常多,例如Espeak,Festival等。
我试了一下Espeak:

Text to Speech engine for English, with support for other languages.

也就是说Espeak是一个英语的TTS引擎,但同时也支持其他语言。
文章来源:http://www.codelast.com/
『2』硬件连接
首先你要把可以播放声音的设备连接到树莓派上。使用有源音箱或者无源的耳机都可以。我使用的是耳塞,连接到树莓派的3.5mm音频输出接口上,如下图所示:
raspberry pi 3.5 mm audio interface
注意连接的瞬间可能会发出强电流声(爆音),最好不要戴在耳朵上。
文章来源:http://www.codelast.com/
『3』Espeak安装、系统配置及使用
安装非常简单:

pacman -S espeak alsa-utils

其中,alsa-utils 我记得是一个Espeak依赖的包,反正我装了。
然而这样安装好之后,你还是无法使用它的。不信可以直接试试:

espeak "hello"

这是让Espeak朗读“hello”。通常情况下会直接报错:

ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
ALSA lib conf.c:4371:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4371:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4371:(_snd_config_evaluate) function snd_func_refer returned error: No such file ordirectory
ALSA lib conf.c:4850:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM sysdefault
......
wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)

这是因为你需要让系统在启动的时候加载和音频相关的模块,修改 /boot/config.txt,在里面添加上一句:

dtparam=audio=on

然后重启系统即可。
文章来源:http://www.codelast.com/
重启之后,你再执行上面的Espeak命令,会发现仍然输出类似于下面的一堆错误信息:

ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
connect(2) call to /dev/shm/jack-0/default/jack_0 failed (err=No such file or directory)
attempt to connect to server failed

但这并不影响使用,此时已经可以正常发声了。
如果要让Espeak朗读中文,可以带参数这样执行:

espeak -vzh "编程"

文章来源:http://www.codelast.com/
『4』使用感受
最大的感觉就是朗读的语音“不自然”——完全是机器人在读的生硬感,而不是人类在读的顺畅感。并且,朗读的时候会带有比较明显的背景噪音。
此外还有一个致命的问题:如果我让它朗读一个非常长的句子(无论是英文还是中文),那么它读着读着就会越来越慢,并且产生越来越大的电流噪音,就好像一个人已经上气不接下气了。这个奇怪的现象我还不知道是为什么。总之,如果拿来读很短的句子或者单词,效果还是勉强能接受的。
如果要追求好的发声效果,还是要使用现在流行的一些云端服务,例如科大讯飞、百度的语音合成API等,它们不仅提供了良好的合成效果,并且还有很多可选的音色(男声,女声,成人声,小孩声,老人声,等等)。

文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):

wechat qrcode of codelast

《[原创] 在树莓派上把文字转成语音(Text-To-Speech/TTS)》有4条评论

  1. 请问一下,在 sudo su -s /bin/bash homeassistant 用户下,使用 espeak -vzh "编程" 报了一堆错,如下
    -----------------------------

    homeassistant@raspberrypi:/home/pi/haisantts-py $ espeak -vzh "编程"
    Full dictionary is not installed for 'zh'
    ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
    ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
    ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
    ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM sysdefault
    ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
    ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
    ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
    ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM sysdefault
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    Cannot connect to server socket err = No such file or directory
    Cannot connect to server request channel
    jack server is not running or cannot be started
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    Cannot connect to server socket err = No such file or directory
    Cannot connect to server request channel
    jack server is not running or cannot be started
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
    ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
    ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused

    ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused

    ALSA lib pcm_a52.c:823:(_snd_pcm_a52_open) a52 is only for playback
    ALSA lib conf.c:5014:(snd_config_expand) Unknown parameters {AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM iec958:{AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_hw.c:1822:(_snd_pcm_hw_open) Invalid value for card
    ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
    ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
    ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
    ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
    ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
    ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM default
    ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
    ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
    ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
    ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM default
    ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
    ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
    ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
    ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
    ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory
    ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM dmix
    Cannot connect to server socket err = No such file or directory
    Cannot connect to server request channel
    jack server is not running or cannot be started
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
    wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)
    wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)
    wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)
    wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)
    wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)
    homeassistant@raspberrypi:/home/pi/haisantts-py $

    回复
    • 这不就是一个简单的文本处理的工作么。

      例如:
      mountain bike, all-terrain bike, off-roader (score = 0.56671)
      tricycle, trike, velocipede (score = 0.12035)
      bicycle-built-for-two, tandem bicycle, tandem (score = 0.08768)
      lawn mower, mower (score = 0.00651)
      alp (score = 0.00387)

      第一行就是你要的结果,处理一下就得到分数最高的名词了。

      回复

发表评论