summary refs log tree commit diff
diff options
context:
space:
mode:
authorJezra <jezra@jezra.net>2013-04-17 22:01:39 -0700
committerJezra <jezra@jezra.net>2013-04-17 22:01:39 -0700
commit73c3ca50ddd83e49952b93b70c8bf0e660b77f87 (patch)
tree4744da3f76f6ff32fed83b7201c05e5903bada47
parentd9ddd711158e69a6eeb4900f68c80946705d1305 (diff)
Config and language files are now in ~/.config/blather
-rwxr-xr-xBlather.py108
-rw-r--r--[-rwxr-xr-x]QtUI.py (renamed from blather.py)43
-rw-r--r--README15
-rwxr-xr-xRecognizer.py56
-rw-r--r--language/README2
-rwxr-xr-xlanguage_updater.sh24
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