Browse Source

Config and language files are now in ~/.config/blather

Jezra 11 years ago
parent
commit
73c3ca50dd
6 changed files with 173 additions and 75 deletions
  1. 108
    0
      Blather.py
  2. 26
    17
      QtUI.py
  3. 9
    6
      README
  4. 6
    50
      Recognizer.py
  5. 0
    2
      language/README
  6. 24
    0
      language_updater.sh

+ 108
- 0
Blather.py View File

@@ -0,0 +1,108 @@
1
+#!/usr/bin/env python2
2
+import sys
3
+import signal
4
+import gobject
5
+import os.path
6
+import subprocess
7
+from Recognizer import Recognizer
8
+
9
+#where are the files?
10
+conf_dir = os.path.expanduser("~/.config/blather")
11
+lang_dir = os.path.join(conf_dir, "language")
12
+command_file = os.path.join(conf_dir, "commands")
13
+strings_file = os.path.join(conf_dir, "sentences.corpus")
14
+lang_file = os.path.join(lang_dir,'lm')
15
+dic_file = os.path.join(lang_dir,'dic')
16
+#make the lang_dir if it doesn't exist
17
+if not os.path.exists(lang_dir):
18
+	os.makedirs(lang_dir)
19
+
20
+class Blather:
21
+	def __init__(self):
22
+		self.continuous_listen = False
23
+		self.commands = {}
24
+		self.read_commands()
25
+		self.recognizer = Recognizer(lang_file, dic_file)
26
+		self.recognizer.connect('finished',self.recognizer_finished)
27
+
28
+	def read_commands(self):
29
+		#read the.commands file
30
+		file_lines = open(command_file)
31
+		strings = open(strings_file, "w")
32
+		for line in file_lines:
33
+				print line
34
+				#trim the white spaces
35
+				line = line.strip()
36
+				#if the line has length and the first char isn't a hash
37
+				if len(line) and line[0]!="#":
38
+						#this is a parsible line
39
+						(key,value) = line.split(":",1)
40
+						print key, value
41
+						self.commands[key.strip()] = value.strip()
42
+						strings.write( key.strip()+"\n")
43
+		#close the strings file
44
+		strings.close()
45
+	
46
+	
47
+	def recognizer_finished(self, recognizer, text):
48
+		#is there a matching command?
49
+		if self.commands.has_key( text ):
50
+			cmd = self.commands[text]
51
+			print cmd
52
+			subprocess.call(cmd, shell=True)
53
+		else:
54
+			print "no matching command"
55
+		#if there is a UI and we are not continuous listen
56
+		if self.ui:
57
+			if not self.continuous_listen:
58
+				#stop listening
59
+				self.recognizer.pause()
60
+			#let the UI know that there is a finish
61
+			self.ui.finished(text)
62
+	
63
+	def run(self, args):
64
+		#TODO check for UI request
65
+		#is there an arg?
66
+		if len(args) > 1:
67
+			if args[1] == "-qt":
68
+				#import the ui from qt
69
+				from QtUI import UI
70
+			elif args[1] == "-gtk":
71
+				from GtkUI import UI
72
+			else:
73
+				print "no GUI defined"
74
+				sys.exit()
75
+			self.ui = UI(args)
76
+			self.ui.connect("command", self.process_command)
77
+			self.ui.run()
78
+		else:
79
+			blather.recognizer.listen()	
80
+
81
+	def process_command(self, UI, command):
82
+		if command == "listen":
83
+			self.recognizer.listen()
84
+		elif command == "stop":
85
+			self.recognizer.pause()
86
+		elif command == "continuous_listen":
87
+			self.continuous_listen = True
88
+			self.recognizer.listen()
89
+		elif command == "continuous_stop":
90
+			self.continuous_listen = False
91
+			self.recognizer.pause()
92
+		
93
+if __name__ == "__main__":
94
+	#make our blather object
95
+	blather = Blather()
96
+	#init gobject threads
97
+	gobject.threads_init()
98
+	#we want a main loop
99
+	main_loop = gobject.MainLoop()
100
+	#run the blather
101
+	blather.run(sys.argv)
102
+	#start the main loop
103
+	try:
104
+		main_loop.run()
105
+	except:
106
+		main_loop.quit()
107
+		sys.exit()
108
+	

blather.py → QtUI.py View File

@@ -6,14 +6,20 @@ import gobject
6 6
 from PySide.QtCore import Signal, Qt
7 7
 from PySide.QtGui import QApplication, QWidget, QMainWindow, QVBoxLayout
8 8
 from PySide.QtGui import QLabel, QPushButton, QCheckBox
9
-from Recognizer import Recognizer
10 9
 
11
-class Blather:
12
-	def __init__(self):
13
-		self.recognizer = Recognizer();
14
-		self.recognizer.connect('finished',self.recognizer_finished)
10
+class UI(gobject.GObject):
11
+	__gsignals__ = {
12
+		'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))
13
+	}
14
+	
15
+	def __init__(self,args):
16
+		gobject.GObject.__init__(self)
17
+		#start by making our app
18
+		self.app = QApplication(args)
15 19
 		#make a window
16 20
 		self.window = QMainWindow()
21
+		#give the window a name
22
+		self.window.setWindowTitle("BlatherQt")
17 23
 		center = QWidget()
18 24
 		self.window.setCentralWidget(center)
19 25
 		
@@ -42,32 +48,35 @@ class Blather:
42 48
 		if checked:
43 49
 			#disable lsbutton
44 50
 			self.lsbutton.setEnabled(False)
45
-			self.recognizer.listen()
51
+			self.lsbutton_stopped()
52
+			self.emit('command', "continuous_listen")
46 53
 		else:
47 54
 			self.lsbutton.setEnabled(True)
55
+			self.emit('command', "continuous_stop")
48 56
 	
49 57
 	def lsbutton_stopped(self):
50
-		self.recognizer.pause()
51 58
 		self.lsbutton.setText("Listen")
52 59
 		
53 60
 	def lsbutton_clicked(self):
54 61
 		val = self.lsbutton.text()
55 62
 		print val
56 63
 		if val == "Listen":
57
-			self.recognizer.listen()
64
+			self.emit("command", "listen")
58 65
 			self.lsbutton.setText("Stop")
59 66
 		else:
60 67
 			self.lsbutton_stopped()
68
+			self.emit("command", "stop")
61 69
 			
62 70
 	def run(self):
63 71
 		self.window.show()
64
-		
65
-if __name__ == "__main__":
66
-	app = QApplication(sys.argv)
67
-	b = Blather()
68
-	b.run()
69
-	
70
-	signal.signal(signal.SIGINT, signal.SIG_DFL)
71
-	#start the app running
72
-	sys.exit(app.exec_())
72
+		self.app.exec_()
73 73
 	
74
+	def finished(self, text):
75
+		print text
76
+		#if the continuous isn't pressed
77
+		if not self.ccheckbox.isChecked():
78
+			self.lsbutton_stopped()
79
+		
80
+	def quit(self):
81
+		#sys.exit()
82
+		pass

+ 9
- 6
README View File

@@ -3,15 +3,18 @@ Requirements
3 3
 
4 4
 pocketsphinx	
5 5
 gstreamer (and what ever plugin has pocket sphinx support)
6
-pyside 
6
+pyside (only required for the Qt based UI)
7 7
 
8
-0. move commands.tmp to commands and fill the file with sentences and command to run
8
+0. move commands.tmp to ~/.config/blather/commands and fill the file with sentences and command to run
9 9
 
10
-1. Run blather.py, this will generate a 'sentences.corpus' file based on sentences in the 'commands' file
10
+1. Run blather.py, this will generate ~/.config/blather/sentences.corpus based on sentences in the 'commands' file
11 11
 2. quit blather (there is a good chance it will just segfault)
12
-3. go to http://www.speech.cs.cmu.edu/tools/lmtool-new.html and upload the sentences.corpus file
13
-4. download the resulting XXXX.lm file to the 'language' directory and rename to file to 'lm'
14
-5. download the resulting XXXX.dic file to the 'language' directory and rename to file to 'dic'
12
+3. go to <http://www.speech.cs.cmu.edu/tools/lmtool-new.html> and upload the sentences.corpus file
13
+4. download the resulting XXXX.lm file to the ~/.config/blather/language directory and rename to file to 'lm'
14
+5. download the resulting XXXX.dic file to the ~/.config/blather/language directory and rename to file to 'dic'
15 15
 6. run blather.py
16
+    * for Qt GUI, run blather.py -qt
16 17
 7. start talking
17 18
 
19
+####Bonus
20
+once the sentences.corpus file has been created, run the language_updater.sh to automate the process of creating and downloading language files.

+ 6
- 50
Recognizer.py View File

@@ -2,22 +2,18 @@
2 2
 import pygst
3 3
 pygst.require('0.10')
4 4
 import gst
5
-import subprocess
6 5
 import os.path
7
-import time
8 6
 import gobject
9 7
 
10 8
 #define some global variables
11 9
 this_dir = os.path.dirname( os.path.abspath(__file__) )
12
-lang_dir = os.path.join(this_dir, "language")
13
-command_file = os.path.join(this_dir, "commands")
14
-strings_file = os.path.join(this_dir, "sentences.corpus")
10
+
15 11
 
16 12
 class Recognizer(gobject.GObject):
17 13
 	__gsignals__ = {
18
-		'finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,))
14
+		'finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,))
19 15
 	}
20
-	def __init__(self):
16
+	def __init__(self, language_file, dictionary_file):
21 17
 		gobject.GObject.__init__(self)
22 18
 		self.commands = {}
23 19
 		#build the pipeline
@@ -26,15 +22,12 @@ class Recognizer(gobject.GObject):
26 22
 		#get the Auto Speech Recognition piece
27 23
 		asr=self.pipeline.get_by_name('asr')
28 24
 		asr.connect('result', self.result)
29
-		asr.set_property('lm', os.path.join(lang_dir, 'lm'))
30
-		asr.set_property('dict', os.path.join(lang_dir, 'dic'))
25
+		asr.set_property('lm', language_file)
26
+		asr.set_property('dict', dictionary_file)
31 27
 		asr.set_property('configured', True)
32 28
 		#get the Voice Activity DEtectoR
33 29
 		self.vad = self.pipeline.get_by_name('vad')
34 30
 		self.vad.set_property('auto-threshold',True)
35
-		self.read_commands()
36
-		#init gobject threads
37
-		gobject.threads_init()
38 31
 		
39 32
 	def listen(self):
40 33
 		self.pipeline.set_state(gst.STATE_PLAYING)
@@ -45,42 +38,5 @@ class Recognizer(gobject.GObject):
45 38
 
46 39
 	def result(self, asr, text, uttid):
47 40
 		#emit finished
48
-		self.emit("finished", True)
49
-		print text
50
-		#is there a matching command?
51
-		if self.commands.has_key( text ):
52
-			cmd = self.commands[text]
53
-			print cmd
54
-			subprocess.call(cmd, shell=True)
55
-		else:
56
-			print "no matching command"
41
+		self.emit("finished", text)
57 42
 		
58
-	def read_commands(self):
59
-		#read the.commands file
60
-		file_lines = open(command_file)
61
-		strings = open(strings_file, "w")
62
-		for line in file_lines:
63
-				#trim the white spaces
64
-				line = line.strip()
65
-				#if the line has length and the first char isn't a hash
66
-				if len(line) and line[0]!="#":
67
-						#this is a parsible line
68
-						(key,value) = line.split(":",1)
69
-						print key, value
70
-						self.commands[key.strip()] = value.strip()
71
-						strings.write( key.strip()+"\n")
72
-		#close the strings file
73
-		strings.close()
74
-
75
-if __name__ == "__main__":
76
-	recognizer = Recognizer()
77
-	recognizer.listen()
78
-	main_loop = gobject.MainLoop()
79
-	#start the main loop
80
-	try:
81
-		main_loop.run()
82
-	except:
83
-		main_loop.quit()
84
-	
85
-
86
-

+ 0
- 2
language/README View File

@@ -1,2 +0,0 @@
1
-This is the directory where the language files go.
2
-Please read ../README

+ 24
- 0
language_updater.sh View File

@@ -0,0 +1,24 @@
1
+#!/bin/bash
2
+
3
+blatherdir=~/.config/blather
4
+sourcefile=$blatherdir/sentences.corpus
5
+langdir=$blatherdir/language
6
+tempfile=$blatherdir/url.txt
7
+lmtoolurl=http://www.speech.cs.cmu.edu/cgi-bin/tools/lmtool/run
8
+
9
+cd $blatherdir
10
+
11
+# upload corpus file, find the resulting dictionary file url
12
+curl -L -F corpus=@"$sourcefile" -F formtype=simple $lmtoolurl \
13
+  |grep -A 1 "base name" |grep http \
14
+  | sed -e 's/^.*\="//' | sed -e 's/\.tgz.*$//' | sed -e 's/TAR//' > $tempfile
15
+
16
+# download the .dic and .lm files
17
+curl -C - -O $(cat $tempfile).dic
18
+curl -C - -O $(cat $tempfile).lm
19
+
20
+# mv em to the right name/place
21
+mv *.dic $langdir/dic
22
+mv *.lm $langdir/lm
23
+
24
+rm $tempfile

Loading…
Cancel
Save