瀏覽代碼

Merge remote-tracking branch 'refs/remotes/origin/dev'

Conflicts:
	Docs/dev_env_install.md
nico 8 年之前
父節點
當前提交
dbb4552cee

+ 8 - 5
Docs/brain/brain.md

@@ -6,10 +6,11 @@ Brain is the link between input and output actions.
 
 An input action can be:
 - **an order:** Something that has been spoke out loud by the user.
-- **an event:** A date
+- **an event:** A date or a frequency (E.G: repeat each morning at 8:30)
 
 An output action is
-- a neuron: A module that will perform some actions like simply talking, run a script, run a command or a complex Ansible playbook.
+- a neuron: A module or plugin that will perform some actions like simply talking, run a script, run a command or a complex Ansible playbook.
+- a list of neurons
 
 Brain is expressed in YAML format (see YAML Syntax) and have a minimum of syntax, which intentionally tries to not be a programming language or script, 
 but rather a model of a configuration or a process.
@@ -26,7 +27,7 @@ Let's look a basic brain:
       - order: "say hello"
 ```
 
-Let's break this down in sections so we can understand how these files are built and what each piece means.
+Let's break this down in sections so we can understand how the file is built and what each piece means.
 
 The file starts with:
 ```
@@ -51,15 +52,17 @@ neurons:
 ```
 
 Neurons are modules that will be executed when the input action is triggered.
-Some neuron need parameters that can be passed as argument following the syntax bellow:
+Some neurons need parameters that can be passed as argument following the syntax bellow:
 ```
 neurons:
     - neuron_name:
         parameter1: "value1"
         parameter2: "value2"
 ```
+Not here that parameters are indented this one tabulation.
 
-In this example, the neuron say will make Jarvis speak out loud the phrase in parameter **message**.
+
+In this example, the neuron called "say" will make Jarvis speak out loud the phrase in parameter **message**.
 
 The last part, called **when** is a list of input action. This last works exactly the same way as neurons. You must place here at least one action.
 ```

+ 110 - 0
Docs/default_settings.md

@@ -0,0 +1,110 @@
+# JARVIS settings
+
+This part of the documentation deals with the main configuration of JARVIS. 
+This configuration is a file placed at the root of the project tree and called settings.yml.
+
+The syntax used is YAML.
+
+# General defaults
+
+In the settings.yml, the following settings are tunable:
+
+#### trigger
+
+The current hotword(also called a wake word or trigger word) detector is based on [Snowboy](https://snowboy.kitt.ai/).
+Common usage of hotword include Alexa on Amazon Echo, OK Google on some Android devices and Hey Siri on iPhones.
+With JARVIS project, you can set the Hotword you want. You can create your magic word by connecting to [Snowboy](https://snowboy.kitt.ai/) 
+and then download the trained model file.
+
+Once downloaded, place the file in **trigger/snowboy/resources**.
+
+Then, specify the name of the Snowboy model use the following syntax
+```
+trigger:
+  name: "my_model_name.pmdl"
+```
+
+#### default_speech_to_text
+
+A Speech To Text(STT) is an engine used to translate what you say into a text that can be processed by JARVIS core. 
+By default, JARVIS use google STT engine.
+
+You must provide an engine name in this variable following the syntax bellow
+```
+default_speech_to_text: "stt_name"
+```
+
+Available STT for JARVIS are:
+- google
+- bing
+
+#### default_text_to_speech
+A Text To Speech is an engine used to translate written text into a speech, into an audio stream.
+By default, JARVIS use Pico2wave TTS engine.
+
+You must provide a TTS engine name in this variable following the syntax bellow
+```
+default_text_to_speech: "tts_name"
+```
+
+Available TTS for JARVIS are:
+- pico2wave
+- voxygen
+
+#### random_wake_up_answers
+When JARVIS detects your trigger/hotword/magic word, he lets you know that he's operational and now waiting for order by answering randomly 
+one of the sentences provided in the variable random_wake_up_answers.
+
+This variable must contain a list of string following the syntax bellow
+```
+random_wake_up_answers:
+  - "You sentence"
+  - "Another sentence"
+```
+
+E.g
+```
+random_wake_up_answers:
+  - "Yes sir?"
+  - "I'm listening"
+  - "Sir?"
+  - "What can I do for you?"
+  - "Listening"
+  - "Yes?"
+```
+
+#### speech_to_text
+Speech to text configuration.
+Each STT has it own configuration. This configuration is passed as argument following the syntax bellow
+```
+speech_to_text:
+  - stt_name:
+      parameter_name: "value"
+```      
+
+```
+speech_to_text:
+  - google:
+      language: "fr-FR"
+  - bing
+```
+
+Please refer to the STT doc to know available parameter for each supported TTS
+#### text_to_speech
+Text to speech configuration
+Each TTS has it own configuration. This configuration is passed as argument following the syntax bellow
+```
+text_to_speech:
+  - tts_name:
+      parameter_name: "value"
+```
+
+E.g
+```
+text_to_speech:
+  - pico2wave:
+      language: "fr-FR"
+  - voxygen:
+      language: "fr"
+      voice: "michel"
+```

+ 30 - 19
Docs/dev_env_install.md

@@ -1,31 +1,23 @@
 # Dev environment installation
 
-This documentation deals with the manual installation of components for developement of JARVIS.
+This documentation aims at explaining the step by step manual deployment of JARVIS.
+
+Tested env
+- Ubuntu 16.04
 
-## System tools
-## Audio tools
-```
-sudo apt-get install libsmpeg0
-```
 
-## Text to spreech engine
-Install pico2wave on Linux
-```
-apt-get install libtts-pico-utils sudo apt-get install libsmpeg0
-```
 
+## Prerequisite
 
-install audio utils
+### Packages installation
+On Ubuntu distribution:
 ```
-apt-get install flac
+sudo apt-get install python-pip python-dev libsmpeg0 libtts-pico-utils sudo apt-get install libsmpeg0 flac
 ```
 
-## Python lib
-You must have python pip to install library
-```
+### Python lib
 
-```
-Then install libs
+Install libs
 ```
 pip install SpeechRecognition
 pip install pyaudio
@@ -33,4 +25,23 @@ pip install ansible
 pip install pygame
 pip install python2-pythondialog
 pip install jinja
-```
+```
+
+### Test your env
+Run the follwing command to capture audio from your microphone
+```
+
+```
+
+Then play the recorded audio file
+```
+
+```
+
+## Installation
+
+Clone the project
+```
+git clone <TODO set github address>
+```
+

+ 2 - 1
README.md

@@ -2,7 +2,8 @@
 
 JARVIS is voice controlled personal assistant. 
 
-TODO: insert video demo
+TODO: insert video demo EN
+TODO: insert video demo FR
 
 
 ## Installation

+ 10 - 0
core/ConfigurationManager/ConfigurationManager.py

@@ -143,3 +143,13 @@ class ConfigurationManager:
             raise NoSpeechToTextConfiguration("No text_to_speech in settings")
 
         return texts_to_speech
+
+    @classmethod
+    def get_stt_list(cls):
+        settings = cls.get_settings()
+        try:
+            speech_to_text = settings["speech_to_text"]
+        except KeyError:
+            raise NoSpeechToTextConfiguration("No speech_to_text in settings")
+
+        return speech_to_text

+ 3 - 1
core/MainController.py

@@ -12,7 +12,7 @@ class MainController:
         self.conf = ConfigurationManager().get_settings()
 
         # create an order listener object
-        self.order_listener = OrderListener(self)
+        self.order_listener = OrderListener(self.get_analyse_order_callback())
         # Wait that the jarvis trigger is pronounced by the user
         self.jarvis_triger = JarvisTrigger(self)
 
@@ -53,3 +53,5 @@ class MainController:
         order_analyser = OrderAnalyser(order, main_controller=self)
         order_analyser.start()
 
+    def get_analyse_order_callback(self):
+        return self.analyse_order

+ 13 - 10
core/OrderListener.py

@@ -4,25 +4,28 @@ from core import ConfigurationManager
 
 class OrderListener:
 
-    def __init__(self, main_controller=None):
+    def __init__(self, callback=None, stt=None):
         """
         This class is called after we catch the hotword that have woke up JARVIS.
         We now wait for an order spoken out loud by the user, translate the order into a text and run the action
          attached to this order from settings
-        :param main_controller:
-        :type main_controller: MainController
+        :param callback: callback function to call
+        :param stt: Speech to text plugin name to load. If not provided,
+        we will load the default one set in settings
         """
-        self.main_controller = main_controller
+        self.stt = stt
+        self.callback = callback
         # self.settings = main_controller.conf.settingLoader.get_config()
         self.settings = ConfigurationManager().get_settings()
 
     def load_stt_plugin(self):
-        default_stt_plugin = ConfigurationManager.get_default_speech_to_text()
+        if self.stt is None:
+            self.stt = ConfigurationManager.get_default_speech_to_text()
 
-        stt_args = ConfigurationManager.get_stt_args(default_stt_plugin)
+        stt_args = ConfigurationManager.get_stt_args(self.stt)
 
         # capitalizes the first letter (because classes have first letter upper case)
-        default_stt_plugin = default_stt_plugin.capitalize()
+        default_stt_plugin = self.stt.capitalize()
         self._run_stt_plugin(default_stt_plugin, stt_args)
 
     def _run_stt_plugin(self, stt_plugin, parameters=None):
@@ -40,10 +43,10 @@ class OrderListener:
         if klass is not None:
             # run the plugin
             if not parameters:
-                klass(self.main_controller)
+                klass(self.callback)
             elif isinstance(parameters, dict):
-                klass(self.main_controller, **parameters)
+                klass(self.callback, **parameters)
             else:
-                klass(self.main_controller, parameters)
+                klass(self.callback, parameters)
 
 

+ 49 - 8
core/ShellGui.py

@@ -2,6 +2,7 @@ from dialog import Dialog
 import locale
 
 from core import ConfigurationManager
+from core import OrderListener
 from neurons import Say
 
 
@@ -35,7 +36,22 @@ class ShellGui:
                 self.show_tts_test_menu()
 
     def show_stt_test_menu(self):
-        pass
+        # we get STT from settings
+        stt_list = ConfigurationManager.get_stt_list()
+        print stt_list
+        choices = self._get_choices_tuple_from_list(stt_list)
+
+        code, tag = self.d.menu("Select the STT to test:",
+                                choices=choices)
+
+        if code == self.d.CANCEL:
+            self.show_main_menu()
+
+        if code == self.d.OK:
+            print tag
+            self.d.infobox("Please talk now")
+            order_listener = OrderListener(callback=self.callback_stt, stt=str(tag))
+            order_listener.load_stt_plugin()
 
     def show_tts_test_menu(self, sentence_to_test=None):
         """
@@ -59,13 +75,7 @@ class ShellGui:
             tts_list = ConfigurationManager.get_tts_list()
 
             # create a list of tuple that can be used by the dialog menu
-            choices = list()
-            for tts in tts_list:
-                for name, settings in tts.iteritems():
-                    print name
-                    print settings
-                    tup = (str(name), str(settings))
-                    choices.append(tup)
+            choices = self._get_choices_tuple_from_list(tts_list)
 
             code, tag = self.d.menu("Sentence to test: %s" % sentence_to_test,
                                     choices=choices)
@@ -86,3 +96,34 @@ class ShellGui:
         """
         Say(message=sentence_to_test, tts=tag)
 
+    @staticmethod
+    def _get_choices_tuple_from_list(list_to_convert):
+        """
+        Return a list of tup that can be used in Dialog menu
+        :param stt_list:
+        :return:
+        """
+        # create a list of tuple that can be used by the dialog menu
+        choices = list()
+        for el in list_to_convert:
+            try:
+                for name, settings in el.iteritems():
+                    print name
+                    print settings
+                    tup = (str(name), str(settings))
+                    choices.append(tup)
+            except AttributeError:
+                # sometime there is no settings for the STT key
+                tup = (str(el), str("No settings"))
+                choices.append(tup)
+        return choices
+
+    def callback_stt(self, audio):
+        """
+        Callback function called after the STT has finish his job
+        :param audio: Text from the translated audio
+        """
+        code = self.d.msgbox("The STT engine think you said:\n %s" % audio, width=50)
+
+        if code == self.d.OK:
+            self.show_stt_test_menu()

+ 13 - 4
stt/google/Google.py

@@ -4,13 +4,20 @@ from core.OrderListener import OrderListener
 
 class Google(OrderListener):
 
-    def __init__(self, main_controller=None, **kwargs):
-        OrderListener.__init__(self, main_controller)
+    def __init__(self, callback=None, **kwargs):
+        """
+        Start recording the microphone and analyse audio with google api
+        :param callback: The callback function to call to send the text
+        :param kwargs:
+        """
+        OrderListener.__init__(self)
 
         """
         Start recording the microphone
         :return:
         """
+        # 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:
@@ -39,5 +46,7 @@ class Google(OrderListener):
             print("Could not request results from Google Speech Recognition service; {0}".format(e))
 
     def _analyse_audio(self, audio):
-        if self.main_controller is not None:
-            self.main_controller.analyse_order(audio)
+        # if self.main_controller is not None:
+        #     self.main_controller.analyse_order(audio)
+        if self.callback is not None:
+            self.callback(audio)