class InstallationAudio: def __init__(self): self.speech_engine = sr.Recognizer() self.speech_engine.pause_threshold = 0.5 with sr.Microphone(device_index=None) as source: self.speech_engine.adjust_for_ambient_noise(source) self.tts = Text_to_Speech() self.tts.start('male') audio.init() def recognize_input(self): self.play_bling_sound() try: with sr.Microphone(device_index=None) as source: audio = self.speech_engine.listen(source) try: text = self.speech_engine.recognize_google(audio, language="de-DE") print(text) except: text = "Audio konnte nicht aufgenommen werden" return text except: traceback.print_exc() print("[WARNING] Text konnte nicht übersetzt werden...") return "Das habe ich leider nicht verstanden." def say(self, text): self.tts.say(text) while self.tts.is_reading: time.sleep(0.1) def play_bling_sound(self): TOP_DIR = os.path.dirname(os.path.abspath(__file__)) DETECT_DONG = os.path.join(TOP_DIR.rstrip('setup'), "resources/sounds/bling.wav") with open(DETECT_DONG, "rb") as wavfile: input_wav = wavfile.read() data = io.BytesIO(input_wav) track = audio.Sound(data) audio.Channel(0).play(track)
class AudioOutput: """ ------------------------- AudioOutput: - responsible for the "normal" audio output - don´t use it for playing music (this is the task of the "MusicPlayer" class) ------------------------- """ def __init__(self, voice): # The channel are splittet on the buffers: # Channel(0): notification # Channel(1): music # Channel(2): playback self.listen = False # music means "Backgroundmusic" or something like that self.music = [] # playback are similar to music, but don´t contain "music" self.playback = [] # notifications reduce the loudness from music but don´t pause it self.notification = [] # mixer0: notification, mixer1: music self.mixer = [] self.music_player = MusicPlayer(self) mixer.pre_init(44100, -16, 1, 512) self.tts = Text_to_Speech() self.tts.start(voice) self.stopped = True def start(self): logging.info("[ACTION] Starting audio output module...") self.stopped = False mixer.init() time.sleep(2) ot = Thread(target=self.run) ot.daemon = True ot.start() return self def run(self): while not self.stopped: try: if self.listen: mixer.Channel(0).set_volume(0.1) mixer.Channel(1).set_volume(0.1) mixer.Channel(2).set_volume(0.1) self.music_player.set_volume(0.1) if not self.notification == [] and mixer.Channel( 0).get_busy() == 0 and not self.tts.is_reading: if mixer.Channel(0).get_busy() == 1: mixer.Channel(1).set_volume(0.10) mixer.Channel(2).set_volume(0.10) if isinstance(self.notification[0], str): logging.info(f'Saying "{self.notification[0]}"') # if the notification is a string (a message to say), pass through to tts self.tts.say(self.notification[0]) self.notification.pop(0) else: logging.info( f'Playing the track "{self.notification[0]}"') # else pass through to mixer-manager track = mixer.Sound(self.notification[0]) self.notification.pop(0) mixer.Channel(0).play(track) if not self.music == [] and mixer.Channel(2).get_busy() == 0: print(self.music) if isinstance(self.music[0], str): logging.info(f'Play music with name {self.music[0]}') topic = self.music[0] self.music.pop(0) self.music_player.play(by_name=topic) else: logging.info(f'Play track with path {self.music[0]}') track = mixer.Sound(self.music[0]) mixer.Channel(2).play(track) self.playback.pop(0) if not self.playback == [] and mixer.Channel( 1).get_busy() == 0: track = mixer.Sound(self.playback[0]) self.playback.pop(0) mixer.Channel(1).play(track) if not mixer.Channel(0).get_busy() is 1 and mixer.Channel( 1).get_volume != 1 and mixer.Channel( 2).get_volume != 1: mixer.Channel(1).set_volume(1) mixer.Channel(2).set_volume(1) time.sleep(0.2) except: traceback.print_exc() def say(self, text): # Forwards the given text to the text-to-speech function and waits # until the announcement has ended. if text == '' or text is None: text = 'Das sollte nicht passieren. Eines meiner internen Module antwortet nicht mehr.' self.notification.append(text) while text in self.notification: time.sleep(0.2) def detected_hotword(self): self.listen = True self.music_player.set_volume(10) def continue_after_hotword(self): self.listen = False self.music_player.set_volume(100) def play_music(self, name, as_next=False): if as_next: self.music.insert(0, name) else: self.music.append(name) def play_playback(self, buff, as_next): if not as_next: self.playback.append(buff) else: self.playback.insert(0, buff) def play_notification(self, buff, as_next): if not as_next: self.notification.append(buff) else: self.notification.insert(0, buff) def play_bling_sound(self): TOP_DIR = os.path.dirname(os.path.abspath(__file__)) DETECT_DONG = os.path.join(TOP_DIR, "resources/sounds/bling.wav") with open(DETECT_DONG, "rb") as wavfile: input_wav = wavfile.read() data = io.BytesIO(input_wav) self.play_notification(data, as_next=True) @staticmethod def pause(channel): mixer.Channel(channel).pause() @staticmethod def resume(channel): mixer.Channel(channel).unpause() @staticmethod def set_volume(channel, volume): mixer.Channel(channel).set_volume(volume) @staticmethod def stop_notification(): mixer.Channel(0).stop() @staticmethod def stop_music(): mixer.Channel(1).stop() @staticmethod def stop_playback(): mixer.Channel(2).stop() def stop(self): self.stopped = True self.music_player.stop() mixer.stop() self.tts.stop()