def transcribe(self, audio): def send_unknown_intent(): """ Send message that nothing was transcribed. """ self.emitter.emit('recognizer_loop:speech.recognition.unknown') try: # Invoke the STT engine on the audio clip text = self.stt.execute(audio) if text is not None: text = text.lower().strip() LOG.debug("STT: " + text) else: send_unknown_intent() LOG.info('no words were transcribed') self.save_utt(text, audio) return text except sr.RequestError as e: LOG.error("Could not request Speech Recognition {0}".format(e)) except ConnectionError as e: LOG.error("Connection Error: {0}".format(e)) self.emitter.emit("recognizer_loop:no_internet") except RequestException as e: LOG.error(e.__class__.__name__ + ': ' + str(e)) except sr.UnknownValueError: LOG.error("Speech Recognition could not understand audio") except Exception as e: send_unknown_intent() LOG.exception(e) LOG.error("Speech Recognition Error") self.play_error() self.save_utt("", audio) return None
def send(self, msg_dict): """ Send to all registered GUIs. """ for connection in GUIWebsocketHandler.clients: try: connection.send(msg_dict) except Exception as e: LOG.exception(repr(e))
def on_gui_show_page(self, message): try: page, namespace, index = _get_page_data(message) # Pass the request to the GUI(s) to pull up a page template with namespace_lock: self.show(namespace, page, index) except Exception as e: LOG.exception(repr(e))
def on_gui_delete_namespace(self, message): """ Bus handler for removing namespace. """ try: namespace = message.data['__from'] with namespace_lock: self.remove_namespace(namespace) except Exception as e: LOG.exception(repr(e))
def on_gui_delete_page(self, message): """ Bus handler for removing pages. """ page, namespace, _ = _get_page_data(message) try: with namespace_lock: self.remove_pages(namespace, page) except Exception as e: LOG.exception(repr(e))
def on_gui_set_value(self, message): data = message.data namespace = data.get("__from", "") # Pass these values on to the GUI renderers for key in data: if key not in RESERVED_KEYS: try: self.set(namespace, key, data[key]) except Exception as e: LOG.exception(repr(e))
def _stop(self): """Stop and close an open stream.""" try: if not self.stream.is_stopped(): self.stream.stop_stream() self.stream.close() except Exception: LOG.exception('Failed to stop mic input stream') # Let's pretend nothing is wrong... self.stream = None self.audio.terminate()
def reload(self): """Reload configuration and restart consumer and producer.""" self.stop() for hw in self.hotword_engines: try: self.hotword_engines[hw]["engine"].stop() except Exception as e: LOG.exception(e) # load config self._load_config() # restart self.start_async()
def on_error(e): """Speak and log the error.""" if not isinstance(e, AbortEvent): # Convert "MyFancySkill" to "My Fancy Skill" for speaking handler_name = camel_case_split(self.name) msg_data = {'skill': handler_name} msg = dialog.get('skill.error', self.lang, msg_data) self.speak(msg) LOG.exception(msg) else: LOG.info("Skill execution aborted") # append exception information in message skill_data['exception'] = repr(e)
def save_phonemes(self, key, phonemes): """ Cache phonemes Args: key: Hash key for the sentence phonemes: phoneme string to save """ cache_dir = get_cache_directory("tts") pho_file = os.path.join(cache_dir, key + ".pho") try: with open(pho_file, "w") as cachefile: cachefile.write(json.dumps(phonemes)) except Exception: LOG.exception("Failed to write {} to cache".format(pho_file))
def videos(self): try: # load video catalog videos = [ch.as_json() for ch in self.media_collection.entries] # set skill_id for idx, v in enumerate(videos): videos[idx]["skill"] = self.skill_id # set url if len(videos[idx].get("streams", [])): videos[idx]["url"] = videos[idx]["streams"][0] else: videos[idx]["url"] = videos[idx].get("stream") or \ videos[idx].get("url") # return sorted return self.sort_videos(videos) except Exception as e: LOG.exception(e) return []
def run(self): restart_attempts = 0 with self.mic as source: LOG.info("Adjusting for ambient noise, be silent!!!") self.recognizer.adjust_for_ambient_noise(source) LOG.info("Ambient noise profile has been created") while self.state.running: try: audio = self.recognizer.listen(source, self.emitter, self.stream_handler) if audio is not None: self.queue.put((AUDIO_DATA, audio, source)) else: LOG.warning("Audio contains no data.") except IOError as e: # IOError will be thrown if the read is unsuccessful. # If self.recognizer.overflow_exc is False (default) # input buffer overflow IOErrors due to not consuming the # buffers quickly enough will be silently ignored. LOG.exception('IOError Exception in AudioProducer') if e.errno == pyaudio.paInputOverflowed: pass # Ignore overflow errors elif restart_attempts < MAX_MIC_RESTARTS: # restart the mic restart_attempts += 1 LOG.info('Restarting the microphone...') source.restart() LOG.info('Restarted...') else: LOG.error('Restarting mic doesn\'t seem to work. ' 'Stopping...') raise except Exception: LOG.exception('Exception in AudioProducer') raise else: # Reset restart attempt counter on sucessful audio read restart_attempts = 0 finally: if self.stream_handler is not None: self.stream_handler.stream_stop()
def _display(self, message): """ Handler for ovos.ccanvas.play. Starts window of a picturelist. Also determines if the user requested a special service. Args: message: message bus message, not used but required """ try: pictures = message.data['pictures'] prefered_service = self.get_prefered(message.data.get("utterance", "")) if isinstance(pictures[0], str): uri_type = pictures[0].split(':')[0] else: uri_type = pictures[0][0].split(':')[0] # check if user requested a particular service if prefered_service and uri_type in prefered_service.supported_uris(): selected_service = prefered_service # check if default supports the uri elif self.default and uri_type in self.default.supported_uris(): LOG.debug("Using default backend ({})".format(self.default.name)) selected_service = self.default else: # Check if any other service can play the media LOG.debug("Searching the services") for s in self.services: if uri_type in s.supported_uris(): LOG.debug("Service {} supports URI {}".format(s, uri_type)) selected_service = s break else: LOG.info('No service found for uri_type: ' + uri_type) return selected_service.clear_pictures() selected_service.add_pictures(pictures) selected_service.window() self.current = selected_service except Exception as e: LOG.exception(e)
def get_mixer(self, control="Master"): if self._mixer is None: try: mixer = alsaaudio.Mixer(control) except Exception as e: try: mixer = alsaaudio.Mixer(control) except Exception as e: try: if control != "Master": LOG.warning("could not allocate requested mixer, " "falling back to 'Master'") mixer = alsaaudio.Mixer("Master") else: raise except Exception as e: LOG.error("Couldn't allocate mixer") LOG.exception(e) raise self._mixer = mixer return self.mixer
def remove_pages(self, namespace, pages): """ Remove the listed pages from the provided namespace. Args: namespace (str): The namespace to modify pages (list): List of page names (str) to delete """ try: index = self.__find_namespace(namespace) if index is None: return else: # Remove any pages that doesn't exist in the namespace pages = [p for p in pages if p in self.loaded[index].pages] # Make sure to remove pages from the back indexes = [self.loaded[index].pages.index(p) for p in pages] indexes = sorted(indexes) indexes.reverse() for page_index in indexes: self.__remove_page(namespace, page_index) except Exception as e: LOG.exception(repr(e))
def show(self, namespace, page, index): """ Show a page and load it as needed. Args: page (str or list): page(s) to show namespace (str): skill namespace index (int): ??? TODO: Unused in code ??? TODO: - Update sync to match. - Separate into multiple functions/methods """ LOG.debug("GUIConnection activating: " + namespace) pages = page if isinstance(page, list) else [page] # find namespace among loaded namespaces try: index = self.__find_namespace(namespace) if index is None: # This namespace doesn't exist, insert them first so they're # shown. self.__insert_new_namespace(namespace, pages) return else: # Namespace exists if index > 0: # Namespace is inactive, activate it by moving it to # position 0 self.__move_namespace(index, 0) # Find if any new pages needs to be inserted new_pages = [p for p in pages if p not in self.loaded[0].pages] if new_pages: self.__insert_pages(namespace, new_pages) else: # No new pages, just switch self.__switch_page(namespace, pages) except Exception as e: LOG.exception(repr(e))
def run(self): """Start and reload mic and STT handling threads as needed. Wait for KeyboardInterrupt and shutdown cleanly. """ try: self.start_async() except Exception: LOG.exception('Starting producer/consumer threads for listener ' 'failed.') return # Handle reload of consumer / producer if config changes while self.state.running: try: time.sleep(1) except KeyboardInterrupt as e: LOG.error(e) self.stop() raise # Re-raise KeyboardInterrupt except Exception: LOG.exception('Exception in RecognizerLoop') raise
def _normalized_numbers(self, sentence): """normalized numbers to word equivalent. Args: sentence (str): setence to speak Returns: stf: normalized sentences to speak """ try: from lingua_franca.format import pronounce_number numbers = re.findall(r'-?\d+', sentence) normalized_num = [ (num, pronounce_number(int(num))) for num in numbers ] for num, norm_num in normalized_num: sentence = sentence.replace(num, norm_num, 1) except TypeError: LOG.exception("type error in mimic2_tts.py _normalized_numbers()") except ImportError: LOG.warning("lingua_franca not installed, can not normalize numbers") return sentence
def __switch_page(self, namespace, pages): """ Switch page to an already loaded page. Args: pages (list): pages (str) to switch to namespace (str): skill namespace """ try: num = self.loaded[0].pages.index(pages[0]) except Exception as e: LOG.exception(repr(e)) num = 0 LOG.debug('Switching to already loaded page at ' 'index {} in namespace {}'.format(num, namespace)) self.send({ "type": "mycroft.events.triggered", "namespace": namespace, "event_name": "page_gained_focus", "data": { "number": num } })
def handle_speak(message): utt = message.data["utterance"] utt = translate_text(utt, "pt") # source lang is auto detected print("MYCROFT:", utt) bus = listen_for_message("speak", handle_speak) print("Write in any language and mycroft will answer in {lang}".format(lang=OUTPUT_LANG)) while True: try: utt = input("YOU:") lang = detect_lang("utt") # source lang is auto detected, this is optional if lang != MYCROFT_LANG: utt = translate_text(utt) send_message("recognizer_loop:utterance", {"utterances": [utt]}, bus=bus # re-utilize the bus connection ) except KeyboardInterrupt: break except Exception as e: LOG.exception(e) bus.remove_all_listeners("speak") bus.close()