浏览代码

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 input action can be:
 - **an order:** Something that has been spoke out loud by the user.
 - **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
 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, 
 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.
 but rather a model of a configuration or a process.
@@ -26,7 +27,7 @@ Let's look a basic brain:
       - order: "say hello"
       - 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:
 The file starts with:
 ```
 ```
@@ -51,15 +52,17 @@ neurons:
 ```
 ```
 
 
 Neurons are modules that will be executed when the input action is triggered.
 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:
 neurons:
     - neuron_name:
     - neuron_name:
         parameter1: "value1"
         parameter1: "value1"
         parameter2: "value2"
         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.
 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
 # 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 SpeechRecognition
 pip install pyaudio
 pip install pyaudio
@@ -33,4 +25,23 @@ pip install ansible
 pip install pygame
 pip install pygame
 pip install python2-pythondialog
 pip install python2-pythondialog
 pip install jinja
 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. 
 JARVIS is voice controlled personal assistant. 
 
 
-TODO: insert video demo
+TODO: insert video demo EN
+TODO: insert video demo FR
 
 
 
 
 ## Installation
 ## Installation

+ 10 - 0
core/ConfigurationManager/ConfigurationManager.py

@@ -143,3 +143,13 @@ class ConfigurationManager:
             raise NoSpeechToTextConfiguration("No text_to_speech in settings")
             raise NoSpeechToTextConfiguration("No text_to_speech in settings")
 
 
         return texts_to_speech
         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()
         self.conf = ConfigurationManager().get_settings()
 
 
         # create an order listener object
         # 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
         # Wait that the jarvis trigger is pronounced by the user
         self.jarvis_triger = JarvisTrigger(self)
         self.jarvis_triger = JarvisTrigger(self)
 
 
@@ -53,3 +53,5 @@ class MainController:
         order_analyser = OrderAnalyser(order, main_controller=self)
         order_analyser = OrderAnalyser(order, main_controller=self)
         order_analyser.start()
         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:
 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.
         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
         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
          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 = main_controller.conf.settingLoader.get_config()
         self.settings = ConfigurationManager().get_settings()
         self.settings = ConfigurationManager().get_settings()
 
 
     def load_stt_plugin(self):
     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)
         # 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)
         self._run_stt_plugin(default_stt_plugin, stt_args)
 
 
     def _run_stt_plugin(self, stt_plugin, parameters=None):
     def _run_stt_plugin(self, stt_plugin, parameters=None):
@@ -40,10 +43,10 @@ class OrderListener:
         if klass is not None:
         if klass is not None:
             # run the plugin
             # run the plugin
             if not parameters:
             if not parameters:
-                klass(self.main_controller)
+                klass(self.callback)
             elif isinstance(parameters, dict):
             elif isinstance(parameters, dict):
-                klass(self.main_controller, **parameters)
+                klass(self.callback, **parameters)
             else:
             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
 import locale
 
 
 from core import ConfigurationManager
 from core import ConfigurationManager
+from core import OrderListener
 from neurons import Say
 from neurons import Say
 
 
 
 
@@ -35,7 +36,22 @@ class ShellGui:
                 self.show_tts_test_menu()
                 self.show_tts_test_menu()
 
 
     def show_stt_test_menu(self):
     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):
     def show_tts_test_menu(self, sentence_to_test=None):
         """
         """
@@ -59,13 +75,7 @@ class ShellGui:
             tts_list = ConfigurationManager.get_tts_list()
             tts_list = ConfigurationManager.get_tts_list()
 
 
             # create a list of tuple that can be used by the dialog menu
             # 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,
             code, tag = self.d.menu("Sentence to test: %s" % sentence_to_test,
                                     choices=choices)
                                     choices=choices)
@@ -86,3 +96,34 @@ class ShellGui:
         """
         """
         Say(message=sentence_to_test, tts=tag)
         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):
 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
         Start recording the microphone
         :return:
         :return:
         """
         """
+        # callback function to call after the translation speech/tex
+        self.callback = callback
         # obtain audio from the microphone
         # obtain audio from the microphone
         r = sr.Recognizer()
         r = sr.Recognizer()
         with sr.Microphone() as source:
         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))
             print("Could not request results from Google Speech Recognition service; {0}".format(e))
 
 
     def _analyse_audio(self, audio):
     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)