sound_play提供一个node,可以把topic(robotsound)中的commands转化为语音, 该node支持内建语音,播放OGG/WAV文件,以及通过festival做语音合成功能。
1 命令行使用
1.1 播放OGG/WAV文件
1)检查声卡
siriansu@siriansu-nuc:~/cmusphinx/mytest$ cat /proc/asound/cards
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xdc340000 irq 135
1 [Device ]: USB-Audio - USB Audio Device
C-Media Electronics Inc. USB Audio Device at usb-0000:00:14.0-1, full speed)
我目前使用声卡1,这个需要设置。
2)启动ros master
roscore
3)启动sound_play节点
rosrun sound_play soundplay_node.py
4)播放声音文件
rosrun sound_play play.py /usr/share/sounds/alsa/Side_Right.wav
1.2 播放内建语音
与1.1唯一差异步骤在4),运行命令(后面数字为内建的语音的IDs)
rosrun sound_play playbuiltin.py 2
查看内建的语音消息sound_play/SoundRequest的命令如下:
cat `rospack find sound_play`/msg/SoundRequest.msg
1.3 播放语音合成text
与1.1唯一差异步骤在4),运行命令如下:
rosrun sound_play say.py 'Hello world'
如果你不喜欢这个声音,可以执行下面命令来换一个人发音,
sudo apt-get install festvox-don
rosrun sound_play say.py 'Hello world' voice_don_diphone
1.4 使robot静默
有时候node连续请求正在播放sound会导致node crash,所以我们可能需要临时shutup robot,
rosrun sound_play shutup.py
1.5 测试节点soundplay_node.py是否正常
rosrun sound_play test.py
这个操作将会播放各种内建的声音,wav文件,以及执行TTS操作。
2 节点说明
2.1 订阅的主题(为play sound)
robotsound (sound_play/SoundRequest)
2.2发布的主题(报告driver诊断信息)
diagnostics (diagnostic_msgs/DiagnosticArray)
3 Robot发音
让robot说我们通过麦克风讲的话,即复述我们的话,这里我们可以简单使用ros by example volume 1中小程序talkback.py。
roslaunch rbx1_speech talkback.launch
大致工作思路:
1)节点/recognizer完成语音识别,并且通过主题/recognizer/output发布是别的格式std_msgs/String的语音文本串
2)节点/talkback订阅/recognizer/output,并通过/robotsound主题发布
3)节点/soundplay_node订阅/robotsound,并播放语音
talkback.py文件内容如下:
#!/usr/bin/env python
"""
talkback.py - Version 1.1 2013-12-20
Use the sound_play client to say back what is heard by the pocketsphinx recognizer.
Created for the Pi Robot Project: http://www.pirobot.org
Copyright (c) 2012 Patrick Goebel. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.5
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details at:
http://www.gnu.org/licenses/gpl.htmlPoint
"""
import rospy
from std_msgs.msg import String
from sound_play.libsoundplay import SoundClient
import sys
class TalkBack:
def __init__(self, script_path):
rospy.init_node('talkback')
rospy.on_shutdown(self.cleanup)
# Set the default TTS voice to use
self.voice = rospy.get_param("~voice", "voice_don_diphone")
# Set the wave file path if used
self.wavepath = rospy.get_param("~wavepath", script_path + "/../sounds")
# Create the sound client object
self.soundhandle = SoundClient()
# Wait a moment to let the client connect to the
# sound_play server
rospy.sleep(1)
# Make sure any lingering sound_play processes are stopped.
self.soundhandle.stopAll()
# Announce that we are ready for input
self.soundhandle.playWave(self.wavepath + "/R2D2a.wav")
rospy.sleep(1)
self.soundhandle.say("Ready", self.voice)
rospy.loginfo("Say one of the navigation commands...")
# Subscribe to the recognizer output and set the callback function
rospy.Subscriber('/recognizer/output', String, self.talkback)
def talkback(self, msg):
# Print the recognized words on the screen
rospy.loginfo(msg.data)
# Speak the recognized words in the selected voice
self.soundhandle.say(msg.data, self.voice)
# Uncomment to play one of the built-in sounds
#rospy.sleep(2)
#self.soundhandle.play(5)
# Uncomment to play a wave file
#rospy.sleep(2)
#self.soundhandle.playWave(self.wavepath + "/R2D2a.wav")
def cleanup(self):
self.soundhandle.stopAll()
rospy.loginfo("Shutting down talkback node...")
if __name__=="__main__":
try:
TalkBack(sys.path[0])
rospy.spin()
except rospy.ROSInterruptException:
rospy.loginfo("Talkback node terminated.")