#!/usr/bin/env python2 import sys import os import glob, re # set to location of libgstkaldionline2.so directory = os.path.dirname(__file__) or '.' os.environ['GST_PLUGIN_PATH'] = directory + '/asr/gst' os.environ['GTK_THEME'] = 'light' print 'gst plugin path =', os.environ['GST_PLUGIN_PATH'] # import gtk stuff from threading import Thread import gi gi.require_version('Gst', '1.0') from gi.repository import GObject, Gst, Gtk, Gdk GObject.threads_init() Gdk.threads_init() Gst.init(None) # make sure ctrl-c works import signal signal.signal(signal.SIGINT, signal.SIG_DFL) # import local stuff import confirm, asr, actions, xmlview import levenstein, slu, osc class ScriptedASR(Gtk.Window): def __init__(self, xml_filename, asr_config_file, osc_host, osc_port): super(ScriptedASR, self).__init__() self.connect("destroy", self.quit) self.set_default_size(1024, 768) self.set_border_width(10) self.set_title('ASR Transcript [xml=%s asr=%s osc=%s:%s]' % (xml_filename, asr_config_file, osc_host, osc_port)) vbox = Gtk.VBox() self.xmlview = xmlview.XmlView(xml_filename) vbox.pack_start(self.xmlview, True, True, 5) self.confirmer = confirm.ConfirmationBox() vbox.pack_start(self.confirmer, False, True, 5) # transcript view self.asr = asr.ASR(asr_config_file, self.hyp_changed) vbox.pack_start(self.asr, False, True, 5) # slu #prefix = 'slu/automate/homeostasis_25nov_%s' #library = 'slu/src.new/librocio_slu.so' prefix = 'slu/automate/homeostasis_25nov_%s' library = 'slu/src/librocio_slu.so' self.slu = {} for section_fst in glob.glob(prefix % 'section*.fst'): found = re.search('section(\d+)\.fst$', section_fst) if found: section_id = int(found.group(1)) self.slu[section_id - 1] = slu.SLU(prefix % 'dico_word.txt', prefix % 'dico_action.txt', section_fst, prefix % 'clean_tail.fst', library=library) self.add(vbox) self.show_all() self.confirmer.hide() # load css style style_provider = Gtk.CssProvider() style_provider.load_from_data(open('data/style.css', 'rb').read()) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) # setup singletons osc.setup(osc_host, osc_port) actions.setup(self.confirmer, self.xmlview) self.current_section = 0 self.current_section_history = [''] self.slu_output = '' self.kept_history = '' self.kept_actions = [] self.connect('key-press-event', self.global_keybindings) def global_keybindings(self, widget, event): if event.keyval == Gdk.KEY_1: self.set_section(0) elif event.keyval == Gdk.KEY_2: self.set_section(1) elif event.keyval == Gdk.KEY_3: self.set_section(2) elif event.keyval == Gdk.KEY_4: self.set_section(3) elif event.keyval == Gdk.KEY_5: self.set_section(4) elif event.keyval == Gdk.KEY_6: self.set_section(5) elif event.keyval == Gdk.KEY_7: self.set_section(6) elif event.keyval == Gdk.KEY_8: self.set_section(7) elif event.keyval == Gdk.KEY_9: self.set_section(8) elif event.keyval == Gdk.KEY_y: self.confirmer.click_yes() elif event.keyval == Gdk.KEY_n: self.confirmer.click_no() elif event.keyval == Gdk.KEY_space: if not self.asr.button.has_focus(): self.asr.button_clicked(None) else: return True return False def set_section(self, section_id): self.xmlview.set_section(section_id) def slu_finished(self, model, slu_output): slu_output = str(slu_output) self.slu_actions = model.get_actions().split() self.slu_output = slu_output print 'SLU output: "%s", actions: "%s"' % (self.slu_output, ' '.join(self.slu_actions)) #for action_id in range(0, len(self.slu_actions)): for action_id in range(len(self.kept_actions), len(self.slu_actions)): print 'NEW ACTION:', action_id, self.slu_actions[action_id] action = actions.parse_slu_action(self.slu_actions[action_id]) print action.text if action.text.startswith('#ENDSEQUENCE('): pass elif action.text.startswith('#ENDSECTION('): new_section = self.xmlview.get_section() + 1 self.confirmer.confirm('Go to section %d?' % (new_section + 1), 3, lambda: self.set_section(new_section)) else: self.xmlview.highlight(action) actions.perform_action(action, False) def hyp_changed(self, hyp): #hyp = ' '.join(hyp).replace('[noise]', ' ').split() if len(hyp) > len(self.current_section_history): self.current_section_history.append('') self.kept_history = self.slu_output self.kept_actions = self.slu_actions words = hyp[-1].strip().replace('_', ' ').split() if len(words) == 0: return section_id = self.xmlview.get_section() if self.current_section != section_id: self.previous_actions = 0 self.current_section = section_id self.current_section_history = [''] self.slu_output = '' self.slu_actions = [] self.kept_history = '' self.kept_actions = [] if section_id in self.slu: self.slu[section_id].reset_slu() #print section_id if section_id in self.slu: model = self.slu[section_id] #self.previous_actions = model.num_actions() print 'SLU input: history="%s", words="%s"' % (self.kept_history, ' '.join(words)) model.process(words, self.kept_history, self.slu_finished, False) self.current_section_history[-1] = ' '.join(words) def quit(self, window): for slu in self.slu.values(): slu.shutdown() Gtk.main_quit() if __name__ == '__main__': import selector xml_filename = 'data/homeostasis_25nov.xml' asr_config_file = 'asr/mika-fred-1.cfg' asr_config_file = 'asr/mika-fred-2.cfg' asr_config_file = 'asr/fisher-benoit-1.cfg' if len(sys.argv) > 1: xml_filename = sys.argv[1] if len(sys.argv) > 2: asr_config_file = sys.argv[2] xml_filename, asr_config_file, osc_host, osc_port = selector.ModelSelector(xml_filename, asr_config_file).run() if xml_filename == None or asr_config_file == None or osc_host == None or osc_port == None: sys.exit(0) app = ScriptedASR(xml_filename, asr_config_file, osc_host, osc_port) Gtk.main()