diff --git a/Blather.py b/Blather.py index 70f2626..b2d5737 100755 --- a/Blather.py +++ b/Blather.py @@ -6,7 +6,7 @@ import sys import signal -import gobject +from gi.repository import GObject as gobject import os.path import subprocess #used to execute commands import shutil #used to copy plugins directory @@ -46,7 +46,7 @@ def __init__(self, opts): self.continuous_listen = opts.continuous self.commands = {} self.read_commands() - self.recognizer = Recognizer(lang_file, dic_file, opts.microphone ) + self.recognizer = Recognizer(lang_file, dic_file, strings_file, opts.microphone) self.recognizer.connect('finished',self.recognizer_finished) self.matchTime = 0 self.keywordTimeLimit = opts.keytime #set to 0 to always speak the keyword @@ -85,18 +85,16 @@ def read_commands(self): self.commands = {} self.keywords = [] 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 + print key, ":", value #get the keyword out of the commands file if value == "keyword" and key.strip().lower() not in self.keywords: self.keywords.append(key.strip().lower()) - continue self.commands[key.strip().lower()] = value.strip() strings.write( key.strip()+"\n") @@ -119,7 +117,7 @@ def log_history(self,text): def recognizer_finished(self, recognizer, text): #split the words spoken into an array - t = text.lower() + t = text.strip().lower().replace("-", "") textWords = t.split(" ") #get the keys array for all commands @@ -132,7 +130,7 @@ def recognizer_finished(self, recognizer, text): biggestKey = ret['biggestKey'] biggestKeySet = ret['biggestKeySet'] biggestKeyCount = ret['biggestKeyCount'] - + #find the match percentage percentMatch = self.calculate_match_percentage(biggestKeySet, biggestKeyCount) @@ -215,7 +213,6 @@ def load_resource(self,string): return False def search_for_matches(self, textWords): - #TODO: https://github.com/ajbogh/blather/issues/1 ret = {'biggestKey':'', 'biggestKeySet':{}, 'biggestKeyCount':0} currentTime = time.time() matchLimit = 1 diff --git a/GtkUI.py b/GtkUI.py index 05a5cd2..2647e56 100755 --- a/GtkUI.py +++ b/GtkUI.py @@ -2,10 +2,12 @@ # -- this code is licensed GPLv3 # Copyright 2013 Jezra import sys -import gobject +from gi.repository import GObject as gobject #Gtk -import pygtk -import gtk +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk as gtk +from gi.repository import Gdk as gdk class UI(gobject.GObject): __gsignals__ = { @@ -16,7 +18,7 @@ def __init__(self,args, continuous): gobject.GObject.__init__(self) self.continuous = continuous #make a window - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) + self.window = gtk.Window(gtk.WindowType.TOPLEVEL) self.window.set_default_size(325, 55) self.window.connect("delete_event", self.delete_event) #give the window a name @@ -43,7 +45,7 @@ def __init__(self,args, continuous): #create an accellerator group for this window accel = gtk.AccelGroup() #add the ctrl+q to quit - accel.connect_group(gtk.keysyms.q, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE, self.accel_quit ) + accel.connect(gdk.KEY_q, gdk.ModifierType.CONTROL_MASK, gtk.AccelFlags.VISIBLE, self.accel_quit ) #lock the group accel.lock() #add the group to the window @@ -91,5 +93,5 @@ def finished(self, text): self.label.set_text(text) def set_icon(self, icon): - gtk.window_set_default_icon_from_file(icon) + gtk.Window.set_icon_from_file(self.window, icon) diff --git a/README_Ubuntu.md b/README_Ubuntu.md new file mode 100644 index 0000000..1041d22 --- /dev/null +++ b/README_Ubuntu.md @@ -0,0 +1,8 @@ +Ubuntu with Python 2.7 installation steps: + +``` +sudo apt-get install --reinstall python-gi python-psutil python-gst-1.0 python-gst-1.0-dbg gstreamer1.0-pocketsphinx python-pyaudio swig python-pip python-dev build-essential + +pip install PocketSphinx +``` + \ No newline at end of file diff --git a/Recognizer.py b/Recognizer.py index 26ccd80..9f811cf 100755 --- a/Recognizer.py +++ b/Recognizer.py @@ -2,49 +2,68 @@ # -- this code is licensed GPLv3 # Copyright 2013 Jezra -import pygst -pygst.require('0.10') -import gst +import gi import os.path -import gobject +from gi.repository import GObject as gobject +import speech_recognition as sr + +r = sr.Recognizer() +m = sr.Microphone() #define some global variables this_dir = os.path.dirname( os.path.abspath(__file__) ) - class Recognizer(gobject.GObject): - __gsignals__ = { - 'finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)) - } - def __init__(self, language_file, dictionary_file, src = None): - gobject.GObject.__init__(self) - self.commands = {} - if src: - audio_src = 'alsasrc device="hw:%d,0"' % (src) - else: - audio_src = 'autoaudiosrc' - - #build the pipeline - cmd = audio_src+' ! audioconvert ! audioresample ! vader name=vad ! pocketsphinx name=asr ! appsink sync=false' - self.pipeline=gst.parse_launch( cmd ) - #get the Auto Speech Recognition piece - asr=self.pipeline.get_by_name('asr') - asr.connect('result', self.result) - 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) - - def listen(self): - self.pipeline.set_state(gst.STATE_PLAYING) - - def pause(self): - self.vad.set_property('silent', True) - self.pipeline.set_state(gst.STATE_PAUSED) - - def result(self, asr, text, uttid): - #emit finished - self.emit("finished", text) + __gsignals__ = { + 'finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)) + } + def __init__(self, language_file, dictionary_file, strings_file, src = None): + gobject.GObject.__init__(self) + + self.keywords = self.read_keywords(strings_file); + + print("A moment of silence, please...") + with m as source: r.adjust_for_ambient_noise(source) + print("Set minimum energy threshold to {}".format(r.energy_threshold)) + + def read_keywords(self, strings_file): + #read the.commands file + strings = open(strings_file) + keywords = [] + for line in strings: + line = line.strip() + keywords.append([line, 1]) + + #close the strings file + strings.close() + return keywords + + def callback(self, recognizer, audio): + print("Got it! Now to recognize it...") + # recognize speech using Sphinx + try: + text = recognizer.recognize_sphinx(audio, "en-US", self.keywords, None) + print("Sphinx thinks you said " + text) + self.result(text) + except sr.UnknownValueError: + print("Sphinx could not understand audio") + except sr.RequestError as e: + print("Sphinx error; {0}".format(e)) + + def listen(self): + print("Say something!") + self.stop_listening = r.listen_in_background(m, self.callback) + return + + def pause(self): + try: + self.stop_listening() + print("No longer listening") + except Exception: + pass + return + + def result(self, text): + #emit finished + self.emit("finished", text) diff --git a/language_updater.sh b/language_updater.sh index ec5c868..e37fe2e 100755 --- a/language_updater.sh +++ b/language_updater.sh @@ -25,6 +25,8 @@ curl -C - -O $(cat $tempfile).dic curl -C - -O $(cat $tempfile).lm # mv em to the right name/place +mkdir --parents $langdir + mv *.dic $langdir/dic mv *.lm $langdir/lm diff --git a/sr_test.py b/sr_test.py new file mode 100644 index 0000000..9c0719c --- /dev/null +++ b/sr_test.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python2 +import speech_recognition as sr + +r = sr.Recognizer() +m = sr.Microphone() + +try: + print("A moment of silence, please...") + with m as source: r.adjust_for_ambient_noise(source) + print("Set minimum energy threshold to {}".format(r.energy_threshold)) + while True: + print("Say something!") + with m as source: audio = r.listen(source) + print("Got it! Now to recognize it...") + try: + # recognize speech using Google Speech Recognition + value = r.recognize_google(audio) + + # we need some special handling here to correctly print unicode characters to standard output + if str is bytes: # this version of Python uses bytes for strings (Python 2) + print(u"You said {}".format(value).encode("utf-8")) + else: # this version of Python uses unicode for strings (Python 3+) + print("You said {}".format(value)) + except sr.UnknownValueError: + print("Oops! Didn't catch that") + except sr.RequestError as e: + print("Uh oh! Couldn't request results from Google Speech Recognition service; {0}".format(e)) +except KeyboardInterrupt: + pass \ No newline at end of file