Ejemplo n.º 1
0
    def run_matching_synapse_from_order(cls, order_to_process, brain, settings, is_api_call=False):
        """
        
        :param order_to_process: the spoken order sent by the user
        :param brain: Brain object
        :param settings: Settings object
        :param is_api_call: if True, the current call come from the API. This info must be known by launched Neuron
        :return: list of matched synapse
        """

        # get our singleton LIFO
        lifo_buffer = LifoManager.get_singleton_lifo()

        # if the LIFO is not empty, so, the current order is passed to the current processing synapse as an answer
        if len(lifo_buffer.lifo_list) > 0:
            # the LIFO is not empty, this is an answer to a previous call
            return lifo_buffer.execute(answer=order_to_process, is_api_call=is_api_call)

        else:  # the LIFO is empty, this is a new call
            # get a list of matched synapse from the order
            list_synapse_to_process = OrderAnalyser.get_matching_synapse(order=order_to_process, brain=brain)

            if not list_synapse_to_process:  # the order analyser returned us an empty list
                return HookManager.on_order_not_found()
            else:
                HookManager.on_order_found()

            lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process)
            lifo_buffer.api_response.user_order = order_to_process

            execdata = lifo_buffer.execute(is_api_call=is_api_call)
            HookManager.on_processed_synapses()
            return execdata
Ejemplo n.º 2
0
    def run_matching_synapse_from_order(cls, order_to_process, brain, settings, is_api_call=False):
        """
        
        :param order_to_process: the spoken order sent by the user
        :param brain: Brain object
        :param settings: Settings object
        :param is_api_call: if True, the current call come from the API. This info must be known by launched Neuron
        :return: list of matched synapse
        """

        # get our singleton LIFO
        lifo_buffer = LifoManager.get_singleton_lifo()

        # if the LIFO is not empty, so, the current order is passed to the current processing synapse as an answer
        if len(lifo_buffer.lifo_list) > 0:
            # the LIFO is not empty, this is an answer to a previous call
            return lifo_buffer.execute(answer=order_to_process, is_api_call=is_api_call)

        else:  # the LIFO is empty, this is a new call
            # get a list of matched synapse from the order
            list_synapse_to_process = OrderAnalyser.get_matching_synapse(order=order_to_process, brain=brain)

            if not list_synapse_to_process:  # the order analyser returned us an empty list
                return HookManager.on_order_not_found()
            else:
                HookManager.on_order_found()

            lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process)
            lifo_buffer.api_response.user_order = order_to_process

            execdata = lifo_buffer.execute(is_api_call=is_api_call)
            HookManager.on_processed_synapses()
            return execdata
Ejemplo n.º 3
0
 def unpausing_trigger_process(self):
     """ 
     If the trigger was in pause, this method will unpause it to listen again for the hotword    
     """
     logger.debug("Entering state: %s" % self.state)
     HookManager.on_waiting_for_trigger()
     self.trigger_instance.unpause()
     self.trigger_callback_called = False
     self.next_state()
Ejemplo n.º 4
0
    def say(self, message):
        """
        USe TTS to speak out loud the Message.
        A message can be a string, a list or a dict
        If it's a string, simply use the TTS with the message
        If it's a list, we select randomly a string in the list and give it to the TTS
        If it's a dict, we use the template given in parameter to create a string that we give to the TTS
        :param message: Can be a String or a dict or a list

        .. raises:: TTSModuleNotFound
        """
        logger.debug("[NeuronModule] Say() called with message: %s" % message)

        tts_message = None

        # we can save parameters from the neuron in memory
        Cortex.save_neuron_parameter_in_memory(self.kalliope_memory, message)

        if isinstance(message, str) or isinstance(message, six.text_type):
            logger.debug("[NeuronModule] message is string")
            tts_message = message

        if isinstance(message, list):
            logger.debug("[NeuronModule] message is list")
            tts_message = random.choice(message)

        if isinstance(message, dict):
            logger.debug("[NeuronModule] message is dict")
            tts_message = self._get_message_from_dict(message)

        if tts_message is not None:
            logger.debug("[NeuronModule] tts_message to say: %s" % tts_message)
            self.tts_message = tts_message
            Utils.print_success(tts_message)
            # save in kalliope memory the last tts message
            Cortex.save("kalliope_last_tts_message", tts_message)

            # process the audio only if the mute flag is false
            if self.settings.options.mute:
                logger.debug("[NeuronModule] mute is True, Kalliope is muted")
            else:
                logger.debug(
                    "[NeuronModule] mute is False, make Kalliope speaking")
                HookManager.on_start_speaking()
                # get the instance of the TTS module
                tts_folder = None
                if self.settings.resources:
                    tts_folder = self.settings.resources.tts_folder
                tts_module_instance = Utils.get_dynamic_class_instantiation(
                    package_name="tts",
                    module_name=self.tts.name,
                    parameters=self.tts.parameters,
                    resources_dir=tts_folder)

                # generate the audio file and play it
                tts_module_instance.say(tts_message)
                HookManager.on_stop_speaking()
Ejemplo n.º 5
0
 def pause_trigger_process(self):
     """
     The trigger has been awaken, we pause it
     :return:
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     self.trigger_instance.pause()
     # if here, then the trigger has been called and paused
     HookManager.on_triggered()
     self.next_state()
Ejemplo n.º 6
0
    def say(self, message):
        """
        USe TTS to speak out loud the Message.
        A message can be a string, a list or a dict
        If it's a string, simply use the TTS with the message
        If it's a list, we select randomly a string in the list and give it to the TTS
        If it's a dict, we use the template given in parameter to create a string that we give to the TTS
        :param message: Can be a String or a dict or a list

        .. raises:: TTSModuleNotFound
        """
        logger.debug("[NeuronModule] Say() called with message: %s" % message)

        tts_message = None

        # we can save parameters from the neuron in memory
        Cortex.save_neuron_parameter_in_memory(self.kalliope_memory, message)

        if isinstance(message, str) or isinstance(message, six.text_type):
            logger.debug("[NeuronModule] message is string")
            tts_message = message

        if isinstance(message, list):
            logger.debug("[NeuronModule] message is list")
            tts_message = random.choice(message)

        if isinstance(message, dict):
            logger.debug("[NeuronModule] message is dict")
            tts_message = self._get_message_from_dict(message)

        if tts_message is not None:
            logger.debug("[NeuronModule] tts_message to say: %s" % tts_message)
            self.tts_message = tts_message
            Utils.print_success(tts_message)
            # save in kalliope memory the last tts message
            Cortex.save("kalliope_last_tts_message", tts_message)

            # process the audio only if the mute flag is false
            if self.settings.options.mute:
                logger.debug("[NeuronModule] mute is True, Kalliope is muted")
            else:
                logger.debug("[NeuronModule] mute is False, make Kalliope speaking")
                HookManager.on_start_speaking()
                # get the instance of the TTS module
                tts_folder = None
                if self.settings.resources:
                    tts_folder = self.settings.resources.tts_folder
                tts_module_instance = Utils.get_dynamic_class_instantiation(package_name="tts",
                                                                            module_name=self.tts.name,
                                                                            parameters=self.tts.parameters,
                                                                            resources_dir=tts_folder)

                # generate the audio file and play it
                tts_module_instance.say(tts_message)
                HookManager.on_stop_speaking()
Ejemplo n.º 7
0
 def order_listener_callback(self, order):
     """
     Receive an order, try to retrieve it in the brain.yml to launch to attached plugins
     :param order: the sentence received
     :type order: str
     """
     logger.debug("[Order] Order listener callback called. Order to process: %s" % order)
     HookManager.on_stop_listening()
     self.order_to_process = order
     self.order_listener_callback_called = True
     # save in kalliope memory the last order
     Cortex.save('kalliope_last_order', order)
Ejemplo n.º 8
0
 def order_listener_callback(self, order):
     """
     Receive an order, try to retrieve it in the brain.yml to launch to attached plugins
     :param order: the sentence received
     :type order: str
     """
     logger.debug(
         "[MainController] Order listener callback called. Order to process: %s"
         % order)
     HookManager.on_stop_listening()
     self.order_to_process = order
     self.order_listener_callback_called = True
Ejemplo n.º 9
0
 def start_trigger_process(self):
     """
     This function will start the trigger thread that listen for the hotword
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     HookManager.on_waiting_for_trigger()
     self.trigger_instance = TriggerLauncher.get_trigger(settings=self.settings, callback=self.trigger_callback)
     self.trigger_callback_called = False
     self.trigger_instance.daemon = True
     # Wait that the kalliope trigger is pronounced by the user
     self.trigger_instance.start()
     self.next_state()
Ejemplo n.º 10
0
 def order_listener_callback(self, order):
     """
     Receive an order, try to retrieve it in the brain.yml to launch to attached plugins
     :param order: the sentence received
     :type order: str
     """
     logger.debug("[Order] Order listener callback called. Order to process: %s" % order)
     HookManager.on_stop_listening()
     self.order_to_process = order
     self.order_listener_callback_called = True
     # save in kalliope memory the last order
     Cortex.save('kalliope_last_order', order)
Ejemplo n.º 11
0
 def start_order_listener_thread(self):
     """
     Start the STT engine thread
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     HookManager.on_start_listening()
     # start listening for an order
     self.order_listener_callback_called = False
     self.order_listener = OrderListener(callback=self.order_listener_callback)
     self.order_listener.daemon = True
     self.order_listener.start()
     self.next_state()
Ejemplo n.º 12
0
 def start_order_listener_thread(self):
     """
     Start the STT engine thread
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     HookManager.on_start_listening()
     # start listening for an order
     self.order_listener_callback_called = False
     self.order_listener = OrderListener(callback=self.order_listener_callback)
     self.order_listener.daemon = True
     self.order_listener.start()
     self.next_state()
Ejemplo n.º 13
0
 def start_trigger_process(self):
     """
     This function will start the trigger thread that listen for the hotword
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     self.trigger_instance = TriggerLauncher.get_trigger(settings=self.settings, callback=self.trigger_callback)
     self.trigger_callback_called = False
     self.trigger_instance.daemon = True
     # Wait that the kalliope trigger is pronounced by the user
     self.trigger_instance.start()
     HookManager.on_start()
     self.next_state()
Ejemplo n.º 14
0
 def get_audio_from_stt(callback):
     """
     Call the default STT to get an audio sample and return it into the callback method
     :param callback: A callback function
     """
     HookManager.on_start_listening()
     # call the order listener
     ol = OrderListener(callback=callback)
     ol.start()
     ol.join()
     # wait that the STT engine has finish his job (or the neurotransmitter neuron will be killed)
     if ol.stt_instance is not None:
         ol.stt_instance.join()
     HookManager.on_stop_listening()
Ejemplo n.º 15
0
 def set_mute_status(mute=False):
     """
     Define is the mute status
     :param mute: Boolean. If false, Kalliope is voice is stopped
     """
     logger.debug("[SettingEditor] mute. Switch trigger process to mute : %s" % mute)
     settings = SettingLoader().settings
     if mute:
         Utils.print_info("Kalliope now muted, voice has been stopped.")
         HookManager.on_mute()
     else:
         Utils.print_info("Kalliope now speaking.")
         HookManager.on_unmute()
     settings.options.mute = mute
Ejemplo n.º 16
0
 def set_mute_status(mute=False):
     """
     Define is the mute status
     :param mute: Boolean. If false, Kalliope is voice is stopped
     """
     logger.debug(
         "[SettingEditor] mute. Switch trigger process to mute : %s" % mute)
     settings = SettingLoader().settings
     if mute:
         Utils.print_info("Kalliope now muted, voice has been stopped.")
         HookManager.on_mute()
     else:
         Utils.print_info("Kalliope now speaking.")
         HookManager.on_unmute()
     settings.options.mute = mute
Ejemplo n.º 17
0
 def waiting_for_trigger_callback_thread(self):
     """
     Method to print in debug that the main process is waiting for a trigger detection
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     if self.settings.options.deaf:  # the user asked to deaf inside the deaf neuron
         Utils.print_info("Kalliope is deaf")
         self.trigger_instance.pause()
     else:
         Utils.print_info("Waiting for trigger detection")
     # this loop is used to keep the main thread alive
     while not self.trigger_callback_called:
         sleep(0.1)
     # if here, then the trigger has been called
     HookManager.on_triggered()
     self.next_state()
Ejemplo n.º 18
0
 def waiting_for_trigger_callback_thread(self):
     """
     Method to print in debug that the main process is waiting for a trigger detection
     """
     logger.debug("[Order] Entering state: %s" % self.state)
     if self.settings.options.deaf:  # the user asked to deaf inside the deaf neuron
         Utils.print_info("Kalliope is deaf")
         self.trigger_instance.pause()
     else:
         Utils.print_info("Waiting for trigger detection")
     # this loop is used to keep the main thread alive
     while not self.trigger_callback_called:
         sleep(0.1)
     # if here, then the trigger has been called
     HookManager.on_triggered()
     self.next_state()
Ejemplo n.º 19
0
 def set_deaf_status(trigger_instance, deaf=False):
     """
     Define is the trigger is listening or not.
     :param trigger_instance: the trigger instance coming from the order. It will be paused or unpaused.
     :param deaf: Boolean. If true, kalliope is trigger is paused
     """
     logger.debug("[MainController] deaf . Switch trigger process to deaf : %s" % deaf)
     settings = SettingLoader().settings
     if deaf:
         trigger_instance.pause()
         Utils.print_info("Kalliope now deaf, trigger has been paused")
         HookManager.on_deaf()
     else:
         trigger_instance.unpause()
         Utils.print_info("Kalliope now listening for trigger detection")
         HookManager.on_undeaf()
     settings.options.deaf = deaf
Ejemplo n.º 20
0
    def analysing_order_thread(self):
        """
        Start the order analyser with the caught order to process
        """
        if self.order_to_process is None or self.order_to_process == "":
            logger.debug("[Order] No audio caught from analysing_order_thread")
            HookManager.on_stt_error()
        else:
            logger.debug("[Order] order in analysing_order_thread %s" % self.order_to_process)
            SynapseLauncher.run_matching_synapse_from_order(self.order_to_process,
                                                            self.brain,
                                                            self.settings,
                                                            is_api_call=False)

        if self.skip_trigger:
            self.start_order_listener()
        else:
            self.unpause_trigger()
Ejemplo n.º 21
0
    def analysing_order_thread(self):
        """
        Start the order analyser with the caught order to process
        """
        if self.order_to_process is None or self.order_to_process == "":
            logger.debug("[Order] No audio caught from analysing_order_thread")
            HookManager.on_stt_error()
        else:
            logger.debug("[Order] order in analysing_order_thread %s" % self.order_to_process)
            SynapseLauncher.run_matching_synapse_from_order(self.order_to_process,
                                                            self.brain,
                                                            self.settings,
                                                            is_api_call=False)

        if self.skip_trigger:
            self.start_order_listener()
        else:
            self.start_trigger()
Ejemplo n.º 22
0
 def set_mute_status(self, muted=False):
     """
     Define is the trigger is listening or not
     :param muted: Boolean. If true, kalliope is muted
     """
     logger.debug(
         "[MainController] Mute button pressed. Switch trigger process to muted: %s"
         % muted)
     if muted:
         self.trigger_instance.pause()
         self.is_trigger_muted = True
         Utils.print_info("Kalliope now muted")
         HookManager.on_mute()
     else:
         self.trigger_instance.unpause()
         self.is_trigger_muted = False
         Utils.print_info("Kalliope now listening for trigger detection")
         HookManager.on_unmute()
Ejemplo n.º 23
0
 def set_deaf_status(trigger_instance, deaf=False):
     """
     Define is the trigger is listening or not.
     :param trigger_instance: the trigger instance coming from the order. It will be paused or unpaused.
     :param deaf: Boolean. If true, kalliope is trigger is paused
     """
     logger.debug(
         "[MainController] deaf . Switch trigger process to deaf : %s" %
         deaf)
     settings = SettingLoader().settings
     if deaf:
         trigger_instance.pause()
         Utils.print_info("Kalliope now deaf, trigger has been paused")
         HookManager.on_deaf()
     else:
         trigger_instance.unpause()
         Utils.print_info("Kalliope now listening for trigger detection")
         HookManager.on_undeaf()
     settings.options.deaf = deaf
Ejemplo n.º 24
0
    def start_recording(self):
        # pyaudio can work but alsa-lib spiting out error messages, to avoid this I used a method to suppress the messages found on stackoverflow
        # https://stackoverflow.com/questions/7088672/pyaudio-working-but-spits-out-error-messages-each-time

        with self.noalsaerr():
            audio = pyaudio.PyAudio()

        FORMAT = pyaudio.paInt32
        if self.format == "paInt16":
            FORMAT = pyaudio.paInt16
        if self.format == "paInt24":
            FORMAT = pyaudio.paInt24

        stream = audio.open(format=FORMAT,
                            channels=self.channels,
                            rate=self.rate,
                            input=True,
                            frames_per_buffer=self.chunk)

        Utils.print_info("[ Recorder ] Is recording...")
        HookManager.on_start_listening()
        frames = []

        for i in range(0, int(self.rate / self.chunk * self.seconds)):
            data = stream.read(self.chunk)
            frames.append(data)
        stream.stop_stream()
        stream.close()
        audio.terminate()
        HookManager.on_stop_listening()
        waveFile = wave.open(self.output, 'wb')
        waveFile.setnchannels(2)
        waveFile.setsampwidth(audio.get_sample_size(FORMAT))
        waveFile.setframerate(self.rate)
        waveFile.writeframes(b''.join(frames))
        waveFile.close()
        Utils.print_info("[ Recorder ] Record saved to %s" % self.output)

        if self.playback:
            self.playback_file(self.output)
Ejemplo n.º 25
0
 def run(self):
     # run hook on_start
     HookManager.on_start()
     self.start_trigger()
Ejemplo n.º 26
0
 def run(self):
     # run hook on_start
     HookManager.on_start()
     self.start_trigger()
Ejemplo n.º 27
0
    def run(self):
        """
        Start the voice detector. For every `sleep_time` second it checks the
        audio buffer for triggering keywords. If detected, then call
        corresponding function in `detected_callback`, which can be a single
        function (single model) or a list of callback functions (multiple
        models). Every loop it also calls `interrupt_check` -- if it returns
        True, then breaks from the loop and return.

        :param detected_callback: a function or list of functions. The number of
                                  items must match the number of models in
                                  `decoder_model`.
        :param interrupt_check: a function that returns True if the main loop
                                needs to stop.
        :param float sleep_time: how much time in second every loop waits.
        :param audio_recorder_callback: if specified, this will be called after
                                        a keyword has been spoken and after the
                                        phrase immediately after the keyword has
                                        been recorded. The function will be
                                        passed the name of the file where the
                                        phrase was recorded.
        :param silent_count_threshold: indicates how long silence must be heard
                                       to mark the end of a phrase that is
                                       being recorded.
        :param recording_timeout: limits the maximum length of a recording.
        :return: None
        """
        if self.interrupt_check():
            logger.debug("detect voice return")
            return

        tc = type(self.detected_callback)
        if tc is not list:
            self.detected_callback = [self.detected_callback]
        if len(self.detected_callback) == 1 and self.num_hotwords > 1:
            self.detected_callback *= self.num_hotwords

        assert self.num_hotwords == len(self.detected_callback), \
            "Error: hotwords in your models (%d) do not match the number of " \
            "callbacks (%d)" % (self.num_hotwords, len(self.detected_callback))

        logger.debug("detecting...")

        SR = SpeechRecorder()

        while not self.kill_received:
            #if not self.paused:
            if self.interrupt_check():
                logger.debug("detect voice break")
                break
            data = self.ring_buffer.get()

            if len(data) == 0:
                time.sleep(self.sleep_time)
                continue
            self.saveMessage(
                data
            )  # Save trigger data so it can be append to the record for STT
            status = self.detector.RunDetection(data)

            if status > 0:  #key word found
                SR.start()  # Start the speech recorder
                Utils.print_info("Keyword " + self.keyword_names[status] +
                                 " detected")
                Cortex.save(
                    'kalliope_trigger_called', self.keyword_names[status]
                )  # I save it to the Cortex, to use it by another neuron
                # for changing the tts acording to the trigger name
                HookManager.on_triggered()
                callback = self.detected_callback[status - 1]
                if callback is not None:
                    callback()

            if status == -1:
                logger.warning(
                    "Error initializing streams or reading audio data")

        logger.debug("finished.")