Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- """
- sphinx.py is a wrapper for pocketsphinx.
- parameters:
- ~lm - filename of language model
- ~dict - filename of dictionary
- ~mic_name - set the pulsesrc device name for the microphone input.
- e.g. a Logitech G35 Headset has the following device name: alsa_input.usb-Logitech_Logitech_G35_Headset-00-Headset_1.analog-mono
- To list audio device info on your machine, in a terminal type: pacmd list-sources
- publications:
- ~output (std_msgs/String) - text output
- services:
- ~start (std_srvs/Empty) - start speech recognition
- ~stop (std_srvs/Empty) - stop speech recognition
- """
- import roslib; roslib.load_manifest('speech_listener')
- import rospy
- import pygtk
- pygtk.require('2.0')
- import gtk
- import gobject
- import pygst
- pygst.require('0.10')
- gobject.threads_init()
- import gst
- from std_msgs.msg import String
- from std_srvs.srv import *
- import os
- import commands
- class recognizer(object):
- """ GStreamer based speech recognizer. """
- def __init__(self):
- # Start node
- rospy.init_node("sphinx")
- self._device_name_param = "~mic_name" # Find the name of your microphone by typing pacmd list-sources in the terminal
- self._hmm_param = "~hmm"
- self._jsgf_param = "~jsgf"
- self._lm_param = "~lm"
- self._dic_param = "~dict"
- # Configure mics with gstreamer launch config
- if rospy.has_param(self._device_name_param):
- self.device_name = rospy.get_param(self._device_name_param)
- self.device_index = self.pulse_index_from_name(self.device_name)
- self.launch_config = "pulsesrc device=" + str(self.device_index)
- rospy.loginfo("Using: pulsesrc device=%s name=%s", self.device_index, self.device_name)
- elif rospy.has_param('~source'):
- # common sources: 'alsasrc'
- self.launch_config = rospy.get_param('~source')
- else:
- self.launch_config = 'gconfaudiosrc'
- rospy.loginfo("Launch config: %s", self.launch_config)
- self.launch_config += " ! audioconvert ! audioresample " \
- + '! vader name=vad auto-threshold=true ' \
- + '! pocketsphinx name=asr ! fakesink'
- # Configure ROS settings
- self.started = False
- rospy.on_shutdown(self.shutdown)
- self.pub = rospy.Publisher('~output', String)
- rospy.Service("~start", Empty, self.start)
- rospy.Service("~stop", Empty, self.stop)
- if rospy.has_param(self._hmm_param) and (
- (rospy.has_param(self._lm_param) and rospy.has_param(self._dic_param)) or
- rospy.has_param(self._jsgf_param)
- ):
- self.start_recognizer()
- else:
- rospy.logwarn("((lm and dic) or jsgf) and hmm parameters need to be set to start recognizer.")
- def start_recognizer(self):
- rospy.loginfo("Starting recognizer... ")
- self.pipeline = gst.parse_launch(self.launch_config)
- self.asr = self.pipeline.get_by_name('asr')
- self.asr.connect('partial_result', self.asr_partial_result)
- self.asr.connect('result', self.asr_result)
- # Configure language model
- if rospy.has_param(self._hmm_param):
- hmm = rospy.get_param(self._hmm_param)
- else:
- rospy.logerr('Recognizer not started. Please specify a speech model file.')
- return
- if rospy.has_param(self._jsgf_param):
- jsgf = rospy.get_param(self._jsgf_param)
- else:
- if rospy.has_param(self._lm_param):
- lm = rospy.get_param(self._lm_param)
- else:
- rospy.logerr('Recognizer not started. Please specify a language model file.')
- return
- if rospy.has_param(self._dic_param):
- dic = rospy.get_param(self._dic_param)
- else:
- rospy.logerr('Recognizer not started. Please specify a dictionary.')
- return
- self.asr.set_property('hmm', hmm)
- self.asr.set_property('dict', dic)
- self.asr.set_property('lm', lm)
- self.asr.set_property('dsratio', 1)
- self.asr.set_property('configured', True)
- self.bus = self.pipeline.get_bus()
- self.bus.add_signal_watch()
- self.bus_id = self.bus.connect('message::application', self.application_message)
- self.pipeline.set_state(gst.STATE_PLAYING)
- self.started = True
- def pulse_index_from_name(self, name):
- output = commands.getstatusoutput("pacmd list-sources | grep -B 1 'name: <" + name + ">' | grep -o -P '(?<=index: )[0-9]*'")
- if len(output) == 2:
- return output[1]
- else:
- raise Exception("Error. pulse index doesn't exist for name: " + name)
- def stop_recognizer(self):
- if self.started:
- self.pipeline.set_state(gst.STATE_NULL)
- self.pipeline.remove(self.asr)
- self.bus.disconnect(self.bus_id)
- self.started = False
- def shutdown(self):
- """ Delete any remaining parameters so they don't affect next launch """
- for param in [self._device_name_param, self._lm_param, self._dic_param, self._hmm_param, self._jsgf_param]:
- if rospy.has_param(param):
- rospy.delete_param(param)
- """ Shutdown the GTK thread. """
- gtk.main_quit()
- def start(self, req):
- self.start_recognizer()
- rospy.loginfo("recognizer started")
- return EmptyResponse()
- def stop(self, req):
- self.stop_recognizer()
- rospy.loginfo("recognizer stopped")
- return EmptyResponse()
- def asr_partial_result(self, asr, text, uttid):
- """ Forward partial result signals on the bus to the main thread. """
- struct = gst.Structure('partial_result')
- struct.set_value('hyp', text)
- struct.set_value('uttid', uttid)
- asr.post_message(gst.message_new_application(asr, struct))
- def asr_result(self, asr, text, uttid):
- """ Forward result signals on the bus to the main thread. """
- struct = gst.Structure('result')
- struct.set_value('hyp', text)
- struct.set_value('uttid', uttid)
- asr.post_message(gst.message_new_application(asr, struct))
- def application_message(self, bus, msg):
- """ Receive application messages from the bus. """
- msgtype = msg.structure.get_name()
- if msgtype == 'partial_result':
- self.partial_result(msg.structure['hyp'], msg.structure['uttid'])
- if msgtype == 'result':
- self.final_result(msg.structure['hyp'], msg.structure['uttid'])
- def partial_result(self, hyp, uttid):
- """ Delete any previous selection, insert text and select it. """
- rospy.logdebug("Partial: " + hyp)
- def final_result(self, hyp, uttid):
- """ Insert the final result. """
- msg = String()
- msg.data = str(hyp.lower())
- rospy.loginfo(msg.data)
- self.pub.publish(msg)
- if __name__ == "__main__":
- start = recognizer()
- gtk.main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement