Преглед на файлове

refactor STTs, add a mother class. Fix CTRL-C when listenning for order

nico преди 8 години
родител
ревизия
81d615f293
променени са 7 файла, в които са добавени 118 реда и са изтрити 105 реда
  1. 21 0
      kalliope/stt/Utils.py
  2. 23 20
      kalliope/stt/apiai/apiai.py
  3. 18 19
      kalliope/stt/bing/bing.py
  4. 19 24
      kalliope/stt/google/google.py
  5. 2 2
      kalliope/stt/houndify/README.md
  6. 22 24
      kalliope/stt/houndify/houndify.py
  7. 13 16
      kalliope/stt/wit/wit.py

+ 21 - 0
kalliope/stt/Utils.py

@@ -0,0 +1,21 @@
+import speech_recognition as sr
+
+from kalliope import Utils
+
+
+class SpeechRecognition(object):
+
+    def __init__(self):
+        self.recognizer = sr.Recognizer()
+        self.microphone = sr.Microphone()
+        self.stop_listening = None
+        with self.microphone as source:
+            # we only need to calibrate once, before we start listening
+            self.recognizer.adjust_for_ambient_noise(source)
+
+    def start_listening(self, callback):
+        Utils.print_info("Say something!")
+        self.recognizer.listen_in_background(self.microphone, callback=callback)
+
+    def interrupt(self):
+        self.stop_listening()

+ 23 - 20
kalliope/stt/apiai/apiai.py

@@ -2,9 +2,10 @@ import speech_recognition as sr
 
 from kalliope.core import Utils
 from kalliope.core.OrderListener import OrderListener
+from kalliope.stt.Utils import SpeechRecognition
 
 
-class Apiai(OrderListener):
+class Apiai(SpeechRecognition):
 
     def __init__(self, callback=None, **kwargs):
         """
@@ -12,27 +13,31 @@ class Apiai(OrderListener):
         :param callback: The callback function to call to send the text
         :param kwargs:
         """
-        OrderListener.__init__(self)
+        SpeechRecognition.__init__(self)
 
         # callback function to call after the translation speech/tex
         self.callback = callback
-        # obtain audio from the microphone
-        r = sr.Recognizer()
-        with sr.Microphone() as source:
-            # listen for 1 second to calibrate the energy threshold for ambient noise levels
-            r.adjust_for_ambient_noise(source)
-            Utils.print_info("Say something!")
-            audio = r.listen(source)
-
-        # recognize speech using Apiai Speech Recognition
-        try:
+        self.key = kwargs.get('key', None)
+        self.language = kwargs.get('language', "en")
+        self.session_id = kwargs.get('session_id', None)
+        self.show_all = kwargs.get('show_all', False)
 
-            key = kwargs.get('key', None)
-            language = kwargs.get('language', "en")
-            session_id= kwargs.get('session_id', None)
-            show_all = kwargs.get('show_all', False)
+        # start listening in the background
+        self.stop_listening = self.start_listening(self.apiai_callback)
 
-            captured_audio = r.recognize_api(audio, client_access_token=key, language=language, session_id=session_id, show_all=show_all)
+    def apiai_callback(self, recognizer, audio):
+        """
+        called from the background thread
+        :param recognizer:
+        :param audio:
+        :return:
+        """
+        try:
+            captured_audio = recognizer.recognize_api(audio,
+                                                      client_access_token=self.key,
+                                                      language=self.language,
+                                                      session_id=self.session_id,
+                                                      show_all=self.show_all)
             Utils.print_success("Apiai Speech Recognition thinks you said %s" % captured_audio)
             self._analyse_audio(captured_audio)
 
@@ -47,10 +52,8 @@ class Apiai(OrderListener):
 
     def _analyse_audio(self, audio):
         """
-        Confirm the audio exists annd run it in a Callback
+        Confirm the audio exists and run it in a Callback
         :param audio: the captured audio
         """
-        # if self.main_controller is not None:
-        #     self.main_controller.analyse_order(audio)
         if self.callback is not None:
             self.callback(audio)

+ 18 - 19
kalliope/stt/bing/bing.py

@@ -1,10 +1,10 @@
 import speech_recognition as sr
 
 from kalliope.core import Utils
-from kalliope.core.OrderListener import OrderListener
+from kalliope.stt.Utils import SpeechRecognition
 
 
-class Bing(OrderListener):
+class Bing(SpeechRecognition):
 
     def __init__(self, callback=None, **kwargs):
         """
@@ -12,26 +12,25 @@ class Bing(OrderListener):
         :param callback: The callback function to call to send the text
         :param kwargs:
         """
-        OrderListener.__init__(self)
+        SpeechRecognition.__init__(self)
 
         # callback function to call after the translation speech/tex
         self.callback = callback
-        # obtain audio from the microphone
-        r = sr.Recognizer()
-        with sr.Microphone() as source:
-            # listen for 1 second to calibrate the energy threshold for ambient noise levels
-            r.adjust_for_ambient_noise(source)
-            Utils.print_info("Say something!")
-            audio = r.listen(source)
-
-        # recognize speech using Bing Speech Recognition
-        try:
-
-            key = kwargs.get('key', None)
-            language = kwargs.get('language', "en-US")
-            show_all = kwargs.get('show_all', False)
+        self.key = kwargs.get('key', None)
+        self.language = kwargs.get('language', "en-US")
+        self.show_all = kwargs.get('show_all', False)
+        # start listening in the background
+        self.stop_listening = self.start_listening(self.bing_callback)
 
-            captured_audio = r.recognize_bing(audio, key=key, language=language, show_all=show_all)
+    def bing_callback(self, recognizer, audio):
+        """
+        called from the background thread
+        """
+        try:
+            captured_audio = recognizer.recognize_bing(audio,
+                                                       key=self.key,
+                                                       language=self.language,
+                                                       show_all=self.show_all)
             Utils.print_success("Bing Speech Recognition thinks you said %s" % captured_audio)
             self._analyse_audio(captured_audio)
 
@@ -46,7 +45,7 @@ class Bing(OrderListener):
 
     def _analyse_audio(self, audio):
         """
-        Confirm the audio exists annd run it in a Callback
+        Confirm the audio exists and run it in a Callback
         :param audio: the captured audio
         """
 

+ 19 - 24
kalliope/stt/google/google.py

@@ -1,10 +1,10 @@
 import speech_recognition as sr
 
 from kalliope.core import Utils
-from kalliope.core.OrderListener import OrderListener
+from kalliope.stt.Utils import SpeechRecognition
 
 
-class Google(OrderListener):
+class Google(SpeechRecognition):
 
     def __init__(self, callback=None, **kwargs):
         """
@@ -12,29 +12,26 @@ class Google(OrderListener):
         :param callback: The callback function to call to send the text
         :param kwargs:
         """
-        OrderListener.__init__(self)
+        SpeechRecognition.__init__(self)
 
         # callback function to call after the translation speech/tex
         self.callback = callback
-        # obtain audio from the microphone
-        r = sr.Recognizer()
-        with sr.Microphone() as source:
-            # listen for 1 second to calibrate the energy threshold for ambient noise levels
-            r.adjust_for_ambient_noise(source)
-            Utils.print_info("Say something!")
-            audio = r.listen(source)
-
-        # recognize speech using Google Speech Recognition
-        try:
-            # for testing purposes, we're just using the default API key
-            # to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")`
-            # instead of `r.recognize_google(audio)`
+        self.key = kwargs.get('key', None)
+        self.language = kwargs.get('language', "en-US")
+        self.show_all = kwargs.get('show_all', False)
 
-            key = kwargs.get('key', None)
-            language = kwargs.get('language', "en-US")
-            show_all = kwargs.get('show_all', False)
+        # start listening in the background
+        self.stop_listening = self.start_listening(self.google_callback)
 
-            captured_audio = r.recognize_google(audio, key=key, language=language, show_all=show_all)
+    def google_callback(self, recognizer, audio):
+        """
+        called from the background thread
+        """
+        try:
+            captured_audio = recognizer.recognize_google(audio,
+                                                         key=self.key,
+                                                         language=self.language,
+                                                         show_all=self.show_all)
             Utils.print_success("Google Speech Recognition thinks you said %s" % captured_audio)
             self._analyse_audio(audio_to_text=captured_audio)
 
@@ -50,10 +47,8 @@ class Google(OrderListener):
     def _analyse_audio(self, audio_to_text):
         """
         Confirm the audio exists and run it in a Callback
-        :param audio: the captured audio
+        :param audio_to_text: the captured audio
         """
-
-        # if self.main_controller is not None:
-        #     self.main_controller.analyse_order(audio)
         if self.callback is not None:
             self.callback(audio_to_text)
+

+ 2 - 2
kalliope/stt/houndify/README.md

@@ -1,9 +1,9 @@
 ### Houndify
 
-Not working yet ... in coming
+English only
 
 | parameter | required  | default | choices      | comment   |
 |:---------:|-----------|---------|--------------|-----------|
 | key       | Yes       | None    |              | User info |
 | client_id | Yes       | None    |              | User info |
-| language  | No        | en-US   | en-US        |           |
+

+ 22 - 24
kalliope/stt/houndify/houndify.py

@@ -1,10 +1,10 @@
 import speech_recognition as sr
 
 from kalliope.core import Utils
-from kalliope.core.OrderListener import OrderListener
+from kalliope.stt.Utils import SpeechRecognition
 
 
-class Houndify(OrderListener):
+class Houndify(SpeechRecognition):
 
     def __init__(self, callback=None, **kwargs):
         """
@@ -12,27 +12,28 @@ class Houndify(OrderListener):
         :param callback: The callback function to call to send the text
         :param kwargs:
         """
-        OrderListener.__init__(self)
+        SpeechRecognition.__init__(self)
 
         # callback function to call after the translation speech/tex
         self.callback = callback
-        # obtain audio from the microphone
-        r = sr.Recognizer()
-        with sr.Microphone() as source:
-            # listen for 1 second to calibrate the energy threshold for ambient noise levels
-            r.adjust_for_ambient_noise(source)
-            Utils.print_info("Say something!")
-            audio = r.listen(source)
-
-        # recognize speech using Houndify Speech Recognition
-        try:
-            client_id = kwargs.get('client_id', None)
-            key = kwargs.get('key', None)
-            language = kwargs.get('language', "en-US")
-            show_all = kwargs.get('show_all', False)
+        self.client_id = kwargs.get('client_id', None)
+        self.key = kwargs.get('key', None)
+        # only english supported
+        # self.language = kwargs.get('language', "en-US")
+        self.show_all = kwargs.get('show_all', False)
+
+        # start listening in the background
+        self.stop_listening = self.start_listening(self.houndify_callback)
 
-            captured_audio = r.recognize_houndify(audio, client_id=client_id, client_key=key,
-                                                  language=language, show_all=show_all)
+    def houndify_callback(self, recognizer, audio):
+        """
+        called from the background thread
+        """
+        try:
+            captured_audio = recognizer.recognize_houndify(audio,
+                                                           client_id=self.client_id,
+                                                           client_key=self.key,
+                                                           show_all=self.show_all)
             Utils.print_success("Houndify Speech Recognition thinks you said %s" % captured_audio)
             self._analyse_audio(captured_audio)
 
@@ -47,11 +48,8 @@ class Houndify(OrderListener):
 
     def _analyse_audio(self, audio):
         """
-            Confirm the audio exists annd run it in a Callback
-            :param audio: the captured audio
+        Confirm the audio exists and run it in a Callback
+        :param audio: the captured audio
         """
-
-        # if self.main_controller is not None:
-        #     self.main_controller.analyse_order(audio)
         if self.callback is not None:
             self.callback(audio)

+ 13 - 16
kalliope/stt/wit/wit.py

@@ -1,10 +1,10 @@
 import speech_recognition as sr
 
 from kalliope.core import Utils
-from kalliope.core.OrderListener import OrderListener
+from kalliope.stt.Utils import SpeechRecognition
 
 
-class Wit(OrderListener):
+class Wit(SpeechRecognition):
 
     def __init__(self, callback=None, **kwargs):
         """
@@ -12,24 +12,21 @@ class Wit(OrderListener):
         :param callback: The callback function to call to send the text
         :param kwargs:
         """
-        OrderListener.__init__(self)
+        SpeechRecognition.__init__(self)
 
         # callback function to call after the translation speech/tex
         self.callback = callback
-        # obtain audio from the microphone
-        r = sr.Recognizer()
-        with sr.Microphone() as source:
-            # listen for 1 second to calibrate the energy threshold for ambient noise levels
-            r.adjust_for_ambient_noise(source)
-            Utils.print_info("Say something!")
-            audio = r.listen(source)
-
-        # recognize speech using Wit.ai Speech Recognition
-        try:
-            key = kwargs.get('key', None)
-            show_all = kwargs.get('show_all', False)
+        self.key = kwargs.get('key', None)
+        self.show_all = kwargs.get('show_all', False)
+
+        # start listening in the background
+        self.stop_listening = self.start_listening(self.wit_callback)
 
-            captured_audio = r.recognize_wit(audio, key=key, show_all=show_all)
+    def wit_callback(self, recognizer, audio):
+        try:
+            captured_audio = recognizer.recognize_wit(audio,
+                                                      key=self.key,
+                                                      show_all=self.show_all)
             Utils.print_success("Wit.ai Speech Recognition thinks you said %s" % captured_audio)
             self._analyse_audio(captured_audio)