diff options
author | Jezra <jezra@jezra.net> | 2013-04-17 22:01:39 -0700 |
---|---|---|
committer | Jezra <jezra@jezra.net> | 2013-04-17 22:01:39 -0700 |
commit | 73c3ca50ddd83e49952b93b70c8bf0e660b77f87 (patch) | |
tree | 4744da3f76f6ff32fed83b7201c05e5903bada47 | |
parent | d9ddd711158e69a6eeb4900f68c80946705d1305 (diff) |
Config and language files are now in ~/.config/blather
-rwxr-xr-x | Blather.py | 108 | ||||
-rw-r--r--[-rwxr-xr-x] | QtUI.py (renamed from blather.py) | 43 | ||||
-rw-r--r-- | README | 15 | ||||
-rwxr-xr-x | Recognizer.py | 56 | ||||
-rw-r--r-- | language/README | 2 | ||||
-rwxr-xr-x | language_updater.sh | 24 |
6 files changed, 173 insertions, 75 deletions
diff --git a/Blather.py b/Blather.py new file mode 100755 index 0000000..c9e4800 --- /dev/null +++ b/Blather.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python2 +import sys +import signal +import gobject +import os.path +import subprocess +from Recognizer import Recognizer + +#where are the files? +conf_dir = os.path.expanduser("~/.config/blather") +lang_dir = os.path.join(conf_dir, "language") +command_file = os.path.join(conf_dir, "commands") +strings_file = os.path.join(conf_dir, "sentences.corpus") +lang_file = os.path.join(lang_dir,'lm') +dic_file = os.path.join(lang_dir,'dic') +#make the lang_dir if it doesn't exist +if not os.path.exists(lang_dir): + os.makedirs(lang_dir) + +class Blather: + def __init__(self): + self.continuous_listen = False + self.commands = {} + self.read_commands() + self.recognizer = Recognizer(lang_file, dic_file) + self.recognizer.connect('finished',self.recognizer_finished) + + def read_commands(self): + #read the.commands file + file_lines = open(command_file) + strings = open(strings_file, "w") + for line in file_lines: + print line + #trim the white spaces + line = line.strip() + #if the line has length and the first char isn't a hash + if len(line) and line[0]!="#": + #this is a parsible line + (key,value) = line.split(":",1) + print key, value + self.commands[key.strip()] = value.strip() + strings.write( key.strip()+"\n") + #close the strings file + strings.close() + + + def recognizer_finished(self, recognizer, text): + #is there a matching command? + if self.commands.has_key( text ): + cmd = self.commands[text] + print cmd + subprocess.call(cmd, shell=True) + else: + print "no matching command" + #if there is a UI and we are not continuous listen + if self.ui: + if not self.continuous_listen: + #stop listening + self.recognizer.pause() + #let the UI know that there is a finish + self.ui.finished(text) + + def run(self, args): + #TODO check for UI request + #is there an arg? + if len(args) > 1: + if args[1] == "-qt": + #import the ui from qt + from QtUI import UI + elif args[1] == "-gtk": + from GtkUI import UI + else: + print "no GUI defined" + sys.exit() + self.ui = UI(args) + self.ui.connect("command", self.process_command) + self.ui.run() + else: + blather.recognizer.listen() + + def process_command(self, UI, command): + if command == "listen": + self.recognizer.listen() + elif command == "stop": + self.recognizer.pause() + elif command == "continuous_listen": + self.continuous_listen = True + self.recognizer.listen() + elif command == "continuous_stop": + self.continuous_listen = False + self.recognizer.pause() + +if __name__ == "__main__": + #make our blather object + blather = Blather() + #init gobject threads + gobject.threads_init() + #we want a main loop + main_loop = gobject.MainLoop() + #run the blather + blather.run(sys.argv) + #start the main loop + try: + main_loop.run() + except: + main_loop.quit() + sys.exit() + diff --git a/blather.py b/QtUI.py index ddc2ce7..032e93b 100755..100644 --- a/blather.py +++ b/QtUI.py @@ -6,14 +6,20 @@ import gobject from PySide.QtCore import Signal, Qt from PySide.QtGui import QApplication, QWidget, QMainWindow, QVBoxLayout from PySide.QtGui import QLabel, QPushButton, QCheckBox -from Recognizer import Recognizer -class Blather: - def __init__(self): - self.recognizer = Recognizer(); - self.recognizer.connect('finished',self.recognizer_finished) +class UI(gobject.GObject): + __gsignals__ = { + 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)) + } + + def __init__(self,args): + gobject.GObject.__init__(self) + #start by making our app + self.app = QApplication(args) #make a window self.window = QMainWindow() + #give the window a name + self.window.setWindowTitle("BlatherQt") center = QWidget() self.window.setCentralWidget(center) @@ -42,32 +48,35 @@ class Blather: if checked: #disable lsbutton self.lsbutton.setEnabled(False) - self.recognizer.listen() + self.lsbutton_stopped() + self.emit('command', "continuous_listen") else: self.lsbutton.setEnabled(True) + self.emit('command', "continuous_stop") def lsbutton_stopped(self): - self.recognizer.pause() self.lsbutton.setText("Listen") def lsbutton_clicked(self): val = self.lsbutton.text() print val if val == "Listen": - self.recognizer.listen() + self.emit("command", "listen") self.lsbutton.setText("Stop") else: self.lsbutton_stopped() + self.emit("command", "stop") def run(self): self.window.show() - -if __name__ == "__main__": - app = QApplication(sys.argv) - b = Blather() - b.run() - - signal.signal(signal.SIGINT, signal.SIG_DFL) - #start the app running - sys.exit(app.exec_()) + self.app.exec_() + def finished(self, text): + print text + #if the continuous isn't pressed + if not self.ccheckbox.isChecked(): + self.lsbutton_stopped() + + def quit(self): + #sys.exit() + pass diff --git a/README b/README index 4c2966d..4df3169 100644 --- a/README +++ b/README @@ -3,15 +3,18 @@ Requirements pocketsphinx gstreamer (and what ever plugin has pocket sphinx support) -pyside +pyside (only required for the Qt based UI) -0. move commands.tmp to commands and fill the file with sentences and command to run +0. move commands.tmp to ~/.config/blather/commands and fill the file with sentences and command to run -1. Run blather.py, this will generate a 'sentences.corpus' file based on sentences in the 'commands' file +1. Run blather.py, this will generate ~/.config/blather/sentences.corpus based on sentences in the 'commands' file 2. quit blather (there is a good chance it will just segfault) -3. go to http://www.speech.cs.cmu.edu/tools/lmtool-new.html and upload the sentences.corpus file -4. download the resulting XXXX.lm file to the 'language' directory and rename to file to 'lm' -5. download the resulting XXXX.dic file to the 'language' directory and rename to file to 'dic' +3. go to <http://www.speech.cs.cmu.edu/tools/lmtool-new.html> and upload the sentences.corpus file +4. download the resulting XXXX.lm file to the ~/.config/blather/language directory and rename to file to 'lm' +5. download the resulting XXXX.dic file to the ~/.config/blather/language directory and rename to file to 'dic' 6. run blather.py + * for Qt GUI, run blather.py -qt 7. start talking +####Bonus +once the sentences.corpus file has been created, run the language_updater.sh to automate the process of creating and downloading language files. \ No newline at end of file diff --git a/Recognizer.py b/Recognizer.py index 685e41d..8320cae 100755 --- a/Recognizer.py +++ b/Recognizer.py @@ -2,22 +2,18 @@ import pygst pygst.require('0.10') import gst -import subprocess import os.path -import time import gobject #define some global variables this_dir = os.path.dirname( os.path.abspath(__file__) ) -lang_dir = os.path.join(this_dir, "language") -command_file = os.path.join(this_dir, "commands") -strings_file = os.path.join(this_dir, "sentences.corpus") + class Recognizer(gobject.GObject): __gsignals__ = { - 'finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,)) + 'finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)) } - def __init__(self): + def __init__(self, language_file, dictionary_file): gobject.GObject.__init__(self) self.commands = {} #build the pipeline @@ -26,15 +22,12 @@ class Recognizer(gobject.GObject): #get the Auto Speech Recognition piece asr=self.pipeline.get_by_name('asr') asr.connect('result', self.result) - asr.set_property('lm', os.path.join(lang_dir, 'lm')) - asr.set_property('dict', os.path.join(lang_dir, 'dic')) + asr.set_property('lm', language_file) + asr.set_property('dict', dictionary_file) asr.set_property('configured', True) #get the Voice Activity DEtectoR self.vad = self.pipeline.get_by_name('vad') self.vad.set_property('auto-threshold',True) - self.read_commands() - #init gobject threads - gobject.threads_init() def listen(self): self.pipeline.set_state(gst.STATE_PLAYING) @@ -45,42 +38,5 @@ class Recognizer(gobject.GObject): def result(self, asr, text, uttid): #emit finished - self.emit("finished", True) - print text - #is there a matching command? - if self.commands.has_key( text ): - cmd = self.commands[text] - print cmd - subprocess.call(cmd, shell=True) - else: - print "no matching command" + self.emit("finished", text) - def read_commands(self): - #read the.commands file - file_lines = open(command_file) - strings = open(strings_file, "w") - for line in file_lines: - #trim the white spaces - line = line.strip() - #if the line has length and the first char isn't a hash - if len(line) and line[0]!="#": - #this is a parsible line - (key,value) = line.split(":",1) - print key, value - self.commands[key.strip()] = value.strip() - strings.write( key.strip()+"\n") - #close the strings file - strings.close() - -if __name__ == "__main__": - recognizer = Recognizer() - recognizer.listen() - main_loop = gobject.MainLoop() - #start the main loop - try: - main_loop.run() - except: - main_loop.quit() - - - diff --git a/language/README b/language/README deleted file mode 100644 index dea25cb..0000000 --- a/language/README +++ /dev/null @@ -1,2 +0,0 @@ -This is the directory where the language files go. -Please read ../README diff --git a/language_updater.sh b/language_updater.sh new file mode 100755 index 0000000..211793e --- /dev/null +++ b/language_updater.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +blatherdir=~/.config/blather +sourcefile=$blatherdir/sentences.corpus +langdir=$blatherdir/language +tempfile=$blatherdir/url.txt +lmtoolurl=http://www.speech.cs.cmu.edu/cgi-bin/tools/lmtool/run + +cd $blatherdir + +# upload corpus file, find the resulting dictionary file url +curl -L -F corpus=@"$sourcefile" -F formtype=simple $lmtoolurl \ + |grep -A 1 "base name" |grep http \ + | sed -e 's/^.*\="//' | sed -e 's/\.tgz.*$//' | sed -e 's/TAR//' > $tempfile + +# download the .dic and .lm files +curl -C - -O $(cat $tempfile).dic +curl -C - -O $(cat $tempfile).lm + +# mv em to the right name/place +mv *.dic $langdir/dic +mv *.lm $langdir/lm + +rm $tempfile |