def process(self, data): self.client.emit(Message(data)) if "mycroft.stop" in data: self.client.emit(Message("mycroft.stop")) if "volume.up" in data: self.client.emit( Message("IncreaseVolumeIntent", metadata={'play_sound': True})) if "volume.down" in data: self.client.emit( Message("DecreaseVolumeIntent", metadata={'play_sound': True})) if "system.test.begin" in data: self.client.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.client.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.client.emit(Message("speak", metadata={ 'utterance': "I am testing one two three"})) record("/tmp/test.wav", 3.5) play_wav("/tmp/test.wav") # Test audio muting on arduino self.client.emit(Message("speak", metadata={ 'utterance': "LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG"})) mixer.setvolume(prev_vol)
class VolumeController: def __init__(self): # `Mixer` defaults to 'Master' # `mixers()` gives all available volume controls self.mixer = Mixer(mixers()[0]) # get the current volume self.current_vol = self.mixer.getvolume()[0] def get_handler(self, key): mapping = { 'toggle_mute': self.toggle_mute, 'vol_up': self.volume_up, 'vol_down': self.volume_down, } return mapping.get(key) def toggle_mute(self): if self.mixer.getmute()[0]: self.mixer.setmute(False) else: self.mixer.setmute(True) def volume_up(self): self.current_vol += 5 if self.current_vol > 100: self.current_vol = 100 self.mixer.setvolume(self.current_vol) def volume_down(self): self.current_vol -= 5 if self.current_vol < 0: self.current.vol = 0 self.mixer.setvolume(self.current_vol)
def process(self, data): self.client.emit(Message(data)) if "mycroft.stop" in data: self.client.emit(Message("mycroft.stop")) if "volume.up" in data: self.client.emit( Message("IncreaseVolumeIntent", metadata={'play_sound': True})) if "volume.down" in data: self.client.emit( Message("DecreaseVolumeIntent", metadata={'play_sound': True})) if "system.test.begin" in data: self.client.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.client.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.client.emit(Message("speak", metadata={ 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav") time.sleep(3.5) # Pause between tests so it's not so fast # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True)
def process(self, data): self.client.emit(Message(data)) if "mycroft.stop" in data: self.client.emit(Message("mycroft.stop")) if "volume.up" in data: self.client.emit( Message("IncreaseVolumeIntent", metadata={'play_sound': True})) if "volume.down" in data: self.client.emit( Message("DecreaseVolumeIntent", metadata={'play_sound': True})) if "system.test.begin" in data: self.client.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.client.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.client.emit(Message("speak", metadata={ 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav") time.sleep(3.5) # Pause between tests so it's not so fast # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: self.client.emit( Message("enclosure.eyes.timedspin", metadata={'length': 12000})) self.client.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl poweroff -i', shell=True) if "unit.reboot" in data: self.client.emit( Message("enclosure.eyes.spin")) self.client.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.setwifi" in data: self.client.emit(Message("wifisetup.start")) if "unit.factory-reset" in data: subprocess.call( 'rm ~/.mycroft/identity/identity.json', shell=True) self.client.emit( Message("enclosure.eyes.spin")) self.client.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True)
class MuteSkill(MycroftSkill): """ A Skill to control playback on a Kodi instance via the json-rpc interface. """ def __init__(self): super(MuteSkill, self).__init__(name="MuteSkill") self.last_volume = 11 self.default_volume = 11 def initialize(self): self.load_data_files(dirname(__file__)) self.mixer = Mixer() @intent_handler(IntentBuilder('MuteIntent').require("MuteKeyword").build()) def handle_mute_intent(self, message): temp_volume = self.mixer.getvolume()[0] if temp_volume > 0: self.last_volume = temp_volume LOG.info(self.last_volume) self.mixer.setvolume(0) @intent_handler( IntentBuilder('UnMuteIntent').require("UnMuteKeyword").build()) def handle_un_mute_intent(self, message): if self.last_volume == 0: self.last_volume = self.default_volume self.mixer.setvolume(self.last_volume) def stop(self): pass
def action3(self): sound = Mixer() vol = sound.getvolume()[ 0] # we can take either 0 or 1 it does not matter vol -= self.step * self.amplifier self.amplifier = 1 # reset the amplifier sound.setvolume(vol) os.system('notify-send "Volume down to %s"' % vol)
def __update_volume(self, level=0): mixer = Mixer() volume = mixer.getvolume()[0] code = self.get_volume_code(volume) + level code = self.fix_code(code) if code in self.VOLUMES: volume = self.VOLUMES[code] mixer.setvolume(volume) return code, volume
def process(self, data): self.ws.emit(Message(data)) if "Command: system.version" in data: self.ws.emit(Message("enclosure.start")) if "mycroft.stop" in data: create_signal('buttonPress') # FIXME - Must use WS instead self.ws.emit(Message("mycroft.stop")) if "volume.up" in data: self.ws.emit(Message("IncreaseVolumeIntent", {'play_sound': True})) if "volume.down" in data: self.ws.emit(Message("DecreaseVolumeIntent", {'play_sound': True})) if "system.test.begin" in data: self.ws.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.ws.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.ws.emit( Message("speak", {'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav").communicate() # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: self.ws.emit(Message("enclosure.eyes.timedspin", {'length': 12000})) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl poweroff -i', shell=True) if "unit.reboot" in data: self.ws.emit(Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.setwifi" in data: self.ws.emit(Message("mycroft.wifi.start")) if "unit.factory-reset" in data: subprocess.call('rm ~/.mycroft/identity/identity2.json', shell=True) self.ws.emit(Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True)
def initialize(voice_command, sentences): if system() == "Windows": press('volumedown', presses=5) else: m = Mixer() current_volume = m.getvolume() # Get the current Volume m.setvolume(current_volume - 10) # Set the volume to -10%. return True, ""
def action2(self): sound = Mixer() vol = sound.getvolume( )[0] # we can take either 0 or 1 from what I gathered, it does not matter vol += self.step * self.amplifier self.amplifier = 1 # reset the amplifier try: sound.setvolume(vol) os.system('notify-send "Volume up to %s"' % vol) except Exception: os.system('notify-send "Volume is already up to it\'s maximum"')
def __update_volume(self, change=0): """ Tries to change volume level :param change: +1 or -1; the step to change by :return: new code (0..11), whether volume changed """ mixer = Mixer() old_level = self.volume_to_level(mixer.getvolume()[0]) new_level = self.bound_level(old_level + change) self.enclosure.eyes_volume(new_level) mixer.setvolume(self.level_to_volume(new_level)) return new_level, new_level != old_level
def set_volume(request, username, value): global volume_who, volume_direction m = Mixer() if value > m.getvolume()[0]: volume_direction = "up" volume_who = username elif value < m.getvolume()[0]: volume_direction = "down" else: return volume() # no change, quit volume_who = username m.setvolume(value) return volume()
def __update_volume(self, level=0): """ Tries to change volume level :param level: +1 or -1; the step to change by :return: new code (0..11), whether volume changed """ mixer = Mixer() volume = mixer.getvolume()[0] old_code = self.get_volume_code(volume) new_code = self.fix_code(old_code + level) if new_code in self.VOLUMES: volume = self.VOLUMES[new_code] mixer.setvolume(volume) return new_code, new_code != old_code
def __update_volume(self, change=0): """ Attempt to change audio level Args: change (int): +1 or -1; the step to change by Returns: int: new level code (0..11) bool: whether level changed """ mixer = Mixer() old_level = self.__volume_to_level(mixer.getvolume()[0]) new_level = self.__bound_level(old_level + change) self.enclosure.eyes_volume(new_level) mixer.setvolume(self.__level_to_volume(new_level)) return new_level, new_level != old_level
class RaspberryGPIOPlugin: buttons = { 12: "volume_up", 11: "volume_down", 8: "skip", 10: "play_pause", } def __init__(self, player): self.player = player self._alsa_mixer = Mixer(control="PCM") self.is_pressed = False GPIO.setmode(GPIO.BOARD) input_buttons = [k for k in self.buttons.keys()] GPIO.setup(input_buttons, GPIO.IN, pull_up_down=GPIO.PUD_UP) def __call__(self): for port_number, callback_name in self.buttons.items(): if GPIO.input(port_number) == 0: getattr(self, callback_name)() return else: self.is_pressed = False def _change_volume(self, change): new_volume = self.current_volume + change self._alsa_mixer.setvolume(new_volume) @property def current_volume(self): return self._alsa_mixer.getvolume()[0] @debounced def skip(self): self.player.skip() @debounced def play_pause(self): self.player.play_pause() def volume_up(self): self._change_volume(1) def volume_down(self): self._change_volume(-1)
def click(self, button): if button == 1: mixer = Mixer(self.mutedev) mixer.setmute(not bool(mixer.getmute()[0])) elif button == 4: mixer = Mixer(self.voldev) try: mixer.setvolume(mixer.getvolume()[0] + self.step) except ALSAAudioError: return elif button == 5: mixer = Mixer(self.voldev) try: mixer.setvolume(mixer.getvolume()[0] - self.step) except ALSAAudioError: return self.update()
def notify(self, timestamp): with self.LOCK: if self.data.__contains__(timestamp): volume = None self.alarm_on = True delay = self.__calculate_delay(self.max_delay) while self.alarm_on and datetime.now() < delay: play_mp3(self.file_path).communicate() self.speak_dialog('alarm.stop') time.sleep(self.repeat_time + 2) if not volume and datetime.now() >= delay: mixer = Mixer() volume = mixer.getvolume()[0] mixer.setvolume(100) delay = self.__calculate_delay(self.extended_delay) if volume: Mixer().setvolume(volume) self.remove(timestamp) self.alarm_on = False self.save()
def notify(self, timestamp): with self.LOCK: if self.data.__contains__(timestamp): volume = None self.reminder_on = True delay = self.__calculate_delay(self.max_delay) while self.reminder_on and datetime.now() < delay: self.speak_dialog('reminder.notify', data=self.build_feedback_payload(timestamp)) time.sleep(1) self.speak_dialog('reminder.stop') time.sleep(self.repeat_time) if not volume and datetime.now() >= delay: mixer = Mixer() volume = mixer.getvolume()[0] mixer.setvolume(100) delay = self.__calculate_delay(self.extended_delay) if volume: Mixer().setvolume(volume) self.remove(timestamp) self.reminder_on = False self.save()
def notify(self, timestamp): with self.LOCK: if self.data.__contains__(timestamp): volume = None self.reminder_on = True delay = self.__calculate_delay(self.max_delay) while self.reminder_on and datetime.now() < delay: self.speak_dialog( 'reminder.notify', data=self.build_feedback_payload(timestamp)) time.sleep(1) self.speak_dialog('reminder.stop') time.sleep(self.repeat_time) if not volume and datetime.now() >= delay: mixer = Mixer() volume = mixer.getvolume()[0] mixer.setvolume(100) delay = self.__calculate_delay(self.extended_delay) if volume: Mixer().setvolume(volume) self.remove(timestamp) self.reminder_on = False self.save()
class Sound: _VOLUME_DELTA = 5 def __init__(self): self._mixer = Mixer("PCM") self._volume_before_muted = None self._old_volumes, self._current_volume = self._init_volume() def _init_volume(self): old_volumes = self._mixer.getvolume() # use floor_to_base_int to round down to a multiple of _VOLUME_DELTA min_volume = floor_to_base_int(min(old_volumes), self._VOLUME_DELTA) self._mixer.setvolume(min_volume) return old_volumes, min_volume def reset_volume(self): for channel in range(2): self._mixer.setvolume(self._old_volumes[channel], channel) def _change_volume(self, operation=None, exact_value=None): if operation is not None: new_volume = operation(self._current_volume, self._VOLUME_DELTA) elif exact_value is not None: new_volume = exact_value else: return if new_volume > 100: new_volume = 100 elif new_volume < 0: new_volume = 0 if new_volume != self._current_volume: self._mixer.setvolume(new_volume) self._current_volume = new_volume def volume_up(self): if self._volume_before_muted is None: self._change_volume(add) else: self._change_volume(exact_value=self._volume_before_muted) self._volume_before_muted = None def volume_down(self): if self._volume_before_muted is None: self._change_volume(sub) def mute(self): self._volume_before_muted = self._current_volume self._change_volume(exact_value=0)
def process(self, data): # TODO: Look into removing this emit altogether. # We need to check if any other serial bus messages # are handled by other parts of the code if "mycroft.stop" not in data: self.ws.emit(Message(data)) if "Command: system.version" in data: # This happens in response to the "system.version" message # sent during the construction of Enclosure() self.ws.emit(Message("enclosure.started")) if "mycroft.stop" in data: if has_been_paired(): create_signal('buttonPress') self.ws.emit(Message("mycroft.stop")) if "volume.up" in data: self.ws.emit( Message("VolumeSkill:IncreaseVolumeIntent", {'play_sound': True})) if "volume.down" in data: self.ws.emit( Message("VolumeSkill:DecreaseVolumeIntent", {'play_sound': True})) if "system.test.begin" in data: self.ws.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.ws.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.ws.emit(Message("speak", { 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav").communicate() # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: self.ws.emit( Message("enclosure.eyes.timedspin", {'length': 12000})) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl poweroff -i', shell=True) if "unit.reboot" in data: self.ws.emit(Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.setwifi" in data: self.ws.emit(Message("mycroft.wifi.start")) if "unit.factory-reset" in data: self.ws.emit(Message("enclosure.eyes.spin")) subprocess.call( 'rm ~/.mycroft/identity/identity2.json', shell=True) self.ws.emit(Message("mycroft.wifi.reset")) self.ws.emit(Message("mycroft.disable.ssh")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("reset to factory defaults")})) wait_while_speaking() self.ws.emit(Message("enclosure.mouth.reset")) self.ws.emit(Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.enable-ssh" in data: # This is handled by the wifi client self.ws.emit(Message("mycroft.enable.ssh")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh enabled")})) if "unit.disable-ssh" in data: # This is handled by the wifi client self.ws.emit(Message("mycroft.disable.ssh")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh disabled")}))
i = 0 while True: sleep(0.1) update() i += 1 if i >= 20: conf_file = open("../conf/wake.json") conf = jload(conf_file) s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect("mastersocket") s.send(jdumps({"request": "get_delta"})) delta = int(s.recv(4096)) if delta != 0: mixer.setvolume(min(100, mixer.getvolume()[0] + delta)) client.clear() client.add("blup.mp3") client.play() s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect("mastersocket") s.send(jdumps({"request": "get_sw_state"})) data = int(s.recv(4096)) print data if data: show_menu(background, hex_to_rgb(conf["general"]["back_color"]))
def handle_set_volume(self, message): mixer = Mixer() level = self.get_volume_level(message, mixer.getvolume()[0]) mixer.setvolume(self.level_to_volume(level)) self.speak_dialog('set.volume', data={'volume': level})
def process(self, data): # TODO: Look into removing this emit altogether. # We need to check if any other serial bus messages # are handled by other parts of the code if "mycroft.stop" not in data: self.ws.emit(Message(data)) if "Command: system.version" in data: # This happens in response to the "system.version" message # sent during the construction of Enclosure() self.ws.emit(Message("enclosure.started")) if "mycroft.stop" in data: if has_been_paired(): create_signal('buttonPress') self.ws.emit(Message("mycroft.stop")) if "volume.up" in data: self.ws.emit(Message("mycroft.volume.increase", {'play_sound': True})) if "volume.down" in data: self.ws.emit(Message("mycroft.volume.decrease", {'play_sound': True})) if "system.test.begin" in data: self.ws.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.ws.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.ws.emit(Message("speak", { 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav").communicate() # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: # Eyes to soft gray on shutdown self.ws.emit(Message("enclosure.eyes.color", {'r': 70, 'g': 65, 'b': 69})) self.ws.emit( Message("enclosure.eyes.timedspin", {'length': 12000})) self.ws.emit(Message("enclosure.mouth.reset")) time.sleep(0.5) # give the system time to pass the message self.ws.emit(Message("system.shutdown")) if "unit.reboot" in data: # Eyes to soft gray on reboot self.ws.emit(Message("enclosure.eyes.color", {'r': 70, 'g': 65, 'b': 69})) self.ws.emit(Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) time.sleep(0.5) # give the system time to pass the message self.ws.emit(Message("system.reboot")) if "unit.setwifi" in data: self.ws.emit(Message("system.wifi.setup", {'lang': self.lang})) if "unit.factory-reset" in data: self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("reset to factory defaults")})) subprocess.call( 'rm ~/.mycroft/identity/identity2.json', shell=True) self.ws.emit(Message("system.wifi.reset")) self.ws.emit(Message("system.ssh.disable")) wait_while_speaking() self.ws.emit(Message("enclosure.mouth.reset")) self.ws.emit(Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) time.sleep(5) # give the system time to process all messages self.ws.emit(Message("system.reboot")) if "unit.enable-ssh" in data: # This is handled by the wifi client self.ws.emit(Message("system.ssh.enable")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh enabled")})) if "unit.disable-ssh" in data: # This is handled by the wifi client self.ws.emit(Message("system.ssh.disable")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh disabled")})) if "unit.enable-learning" in data or "unit.disable-learning" in data: enable = 'enable' in data word = 'enabled' if enable else 'disabled' LOG.info("Setting opt_in to: " + word) new_config = {'opt_in': enable} user_config = LocalConf(USER_CONFIG) user_config.merge(new_config) user_config.store() self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("learning " + word)}))
x1, y1 = lm_list[4][1], lm_list[4][2] x2, y2 = lm_list[8][1], lm_list[8][2] cx, cy = (x1 + x2) // 2, (y1 + y2) // 2 cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED) cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED) cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3) cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED) length = math.hypot(x2 - x1, y2 - y1) # Hand range 50 - 300 vol = np.interp(length, [50, 300], [0, 100]) vol_bar = np.interp(length, [50, 300], [400, 150]) vol_per = np.interp(length, [50, 300], [0, 100]) mixer.setvolume(int(vol)) vol = mixer.getvolume() if length < 50: cv2.circle(img, (cx, cy), 15, (255, 0, 0), cv2.FILLED) cv2.rectangle(img, (50, 150), (85, 400), (250, 0, 0), 3) cv2.rectangle(img, (50, int(vol_bar)), (85, 400), (255, 0, 0), cv2.FILLED) cv2.putText(img, f'{int(vol_per)} %', (50, 450), cv2.FONT_HERSHEY_PLAIN, 2, (250, 0, 0), 3) cTime = time.time() fps = 1 / (cTime - pTime) pTime = cTime cv2.putText(img, f'FPS: {int(fps)}', (10, 70), cv2.FONT_HERSHEY_PLAIN, 2,
def process(self, data): self.ws.emit(Message(data)) if "Command: system.version" in data: self.ws.emit(Message("enclosure.start")) if "mycroft.stop" in data: create_signal('buttonPress') # FIXME - Must use WS instead self.ws.emit(Message("mycroft.stop")) if "volume.up" in data: self.ws.emit( Message("IncreaseVolumeIntent", {'play_sound': True})) if "volume.down" in data: self.ws.emit( Message("DecreaseVolumeIntent", {'play_sound': True})) if "system.test.begin" in data: self.ws.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.ws.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.ws.emit(Message("speak", { 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav").communicate() # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: self.ws.emit( Message("enclosure.eyes.timedspin", {'length': 12000})) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl poweroff -i', shell=True) if "unit.reboot" in data: self.ws.emit( Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.setwifi" in data: self.ws.emit(Message("mycroft.wifi.start")) if "unit.factory-reset" in data: subprocess.call( 'rm ~/.mycroft/identity/identity2.json', shell=True) self.ws.emit( Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True)
class ALSA(IntervalModule): """ Shows volume of ALSA mixer. You can also use this for inputs, btw. Requires pyalsaaudio .. rubric:: Available formatters * `{volume}` — the current volume in percent * `{muted}` — the value of one of the `muted` or `unmuted` settings * `{card}` — the associated soundcard * `{mixer}` — the associated ALSA mixer """ interval = 1 settings = ("format", ( "format_muted", "optional format string to use when muted" ), ("mixer", "ALSA mixer"), ("mixer_id", "ALSA mixer id"), ( "card", "ALSA sound card" ), ("increment", "integer percentage of max volume to in/decrement volume on mousewheel" ), "muted", "unmuted", "color_muted", "color", "channel") muted = "M" unmuted = "" color_muted = "#AAAAAA" color = "#FFFFFF" format = "♪: {volume}" format_muted = None mixer = "Master" mixer_id = 0 card = 0 channel = 0 increment = 5 alsamixer = None has_mute = True on_upscroll = "increase_volume" on_downscroll = "decrease_volume" on_leftclick = "switch_mute" on_rightclick = on_leftclick def init(self): self.create_mixer() try: self.alsamixer.getmute() except ALSAAudioError: self.has_mute = False self.fdict = { "card": self.alsamixer.cardname(), "mixer": self.mixer, } def create_mixer(self): self.alsamixer = Mixer(control=self.mixer, id=self.mixer_id, cardindex=self.card) def run(self): self.create_mixer() muted = False if self.has_mute: muted = self.alsamixer.getmute()[self.channel] == 1 self.fdict["volume"] = self.alsamixer.getvolume()[self.channel] self.fdict["muted"] = self.muted if muted else self.unmuted if muted and self.format_muted is not None: output_format = self.format_muted else: output_format = self.format self.output = { "full_text": output_format.format(**self.fdict), "color": self.color_muted if muted else self.color, } def switch_mute(self): if self.has_mute: muted = self.alsamixer.getmute()[self.channel] self.alsamixer.setmute(not muted) def increase_volume(self, delta=None): vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume( min(100, vol + (delta if delta else self.increment))) def decrease_volume(self, delta=None): vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume( max(0, vol - (delta if delta else self.increment)))
class AutoVolume(MycroftSkill): def __init__(self): MycroftSkill.__init__(self) def initialize(self): self.filename = os.path.join(get_ipc_directory(), "mic_level") self.audio_service = AudioService(self.bus) self.mixer = Mixer() self.schedule_repeating_event(self.auto_set_volume, None, 5, 'AutoVolume') self.schedule_repeating_event(self.mesure_mic_thresh, None, 1, 'AutoVolume_messure') self.autovolume = True if self.settings.get('High volume') is None: self.settings['High volume'] = 75 if self.settings.get('Normal volume') is None: self.settings['Normal volume'] = 60 if self.settings.get('Low volume') is None: self.settings['Low volume'] = 35 self.add_event('recognizer_loop:record_begin', self.handle_listener_started) self.add_event('recognizer_loop:record_end', self.handle_listener_ended) wait_while_speaking() with io.open(self.filename, 'r') as fh: while True: line = fh.readline() if line == "": break # Ex:Energy: cur=4 thresh=1.5 parts = line.split("=") meter_thresh = float(parts[-1]) if self.settings.get('Highest messurement') is None: self.settings['Highest messurement'] = meter_thresh if self.settings.get('Lowest messurement') is None: self.settings['Lowest messurement'] = meter_thresh self.volume = int(self.settings.get('Low volume')) self.meter_thresh = 0 self.meter_high = meter_thresh self.meter_low = meter_thresh self.meter_thresh_list = [] self.meter_thresh_list.append(meter_thresh) def handle_listener_started(self, message): self.autovolume = False def handle_listener_ended(self, message): time.sleep(5) self.autovolume = True @intent_file_handler('activate.intent') def handle_activate(self, message): self.autovolume = True self.speak_dialog("activate") @intent_file_handler('deactivate.intent') def handle_deactivate(self, message): self.autovolume = False self.speak_dialog("deactivate") @intent_file_handler('reset.intent') def handle_reset(self, message): self.speak_dialog("reset") wait_while_speaking() with io.open(self.filename, 'r') as fh: while True: line = fh.readline() if line == "": break # Ex:Energy: cur=4 thresh=1.5 parts = line.split("=") meter_thresh = float(parts[-1]) self.settings['Highest messurement'] = meter_thresh self.settings['Lowest messurement'] = meter_thresh self.volume = int(self.settings.get('Low volume')) self.meter_thresh = 0 self.meter_high = meter_thresh self.meter_low = meter_thresh self.meter_thresh_list = [] self.meter_thresh_list.append(meter_thresh) def mesure_mic_thresh(self, message): if self.autovolume and not self.audio_service.is_playing: wait_while_speaking() with io.open(self.filename, 'r') as fh: while True: line = fh.readline() if line == "": break # Ex:Energy: cur=4 thresh=1.5 parts = line.split("=") meter_thresh = float(parts[-1]) self.meter_thresh_list.append(meter_thresh) if len(self.meter_thresh_list) > 120: self.meter_thresh_list.pop(1) self.meter_thresh = sum(self.meter_thresh_list) / float( len(self.meter_thresh_list)) if self.meter_thresh < self.settings.get( 'Lowest messurement'): self.settings['Lowest messurement'] = self.meter_thresh if self.meter_thresh > self.settings.get( 'Highest messurement'): self.settings[ 'Highest messurement'] = self.meter_thresh def auto_set_volume(self, message): if self.autovolume and not self.audio_service.is_playing: wait_while_speaking() volume = int(self.settings.get('Normal volume')) range = self.settings.get( 'Highest messurement') - self.settings.get( 'Lowest messurement') high_level = self.settings.get('Highest messurement') - ( (10 * range) / 100) low_level = self.settings.get('Lowest messurement') + ( (10 * range) / 100) if self.meter_thresh > high_level: volume = self.settings.get('High volume') if self.meter_thresh < low_level: volume = self.settings.get('Low volume') if volume != self.volume and volume is not None: self.mixer.setvolume(int(volume)) self.volume = volume self.log.info("Mic thresh: " + str(self.meter_thresh) + " Low level: " + str(low_level) + " High level: " + str(high_level)) self.log.info("Setting volume to :" + str(volume) + "%")
class ALSA(IntervalModule): """ Shows volume of ALSA mixer. You can also use this for inputs, btw. Requires pyalsaaudio .. rubric:: Available formatters * `{volume}` — the current volume in percent * `{muted}` — the value of one of the `muted` or `unmuted` settings * `{card}` — the associated soundcard * `{mixer}` — the associated ALSA mixer """ interval = 1 settings = ( "format", ("format_muted", "optional format string to use when muted"), ("mixer", "ALSA mixer"), ("mixer_id", "ALSA mixer id"), ("card", "ALSA sound card"), ("increment", "integer percentage of max volume to in/decrement volume on mousewheel" ), "muted", "unmuted", "color_muted", "color", "channel", ("map_volume", "volume display/setting as in AlsaMixer. increment option is ignored then." )) muted = "M" unmuted = "" color_muted = "#AAAAAA" color = "#FFFFFF" format = "♪: {volume}" format_muted = None mixer = "Master" mixer_id = 0 card = -1 channel = 0 increment = 5 map_volume = False alsamixer = None has_mute = True on_upscroll = "increase_volume" on_downscroll = "decrease_volume" on_leftclick = "switch_mute" on_rightclick = on_leftclick def init(self): self.create_mixer() try: self.alsamixer.getmute() except ALSAAudioError: self.has_mute = False self.fdict = { "card": self.alsamixer.cardname(), "mixer": self.mixer, } self.dbRng = self.alsamixer.getrange() self.dbMin = self.dbRng[0] self.dbMax = self.dbRng[1] def create_mixer(self): self.alsamixer = Mixer(control=self.mixer, id=self.mixer_id, cardindex=self.card) def run(self): self.create_mixer() muted = False if self.has_mute: muted = self.alsamixer.getmute()[self.channel] == 1 self.fdict["volume"] = self.get_cur_volume() self.fdict["muted"] = self.muted if muted else self.unmuted self.fdict["db"] = self.get_db() if muted and self.format_muted is not None: output_format = self.format_muted else: output_format = self.format self.data = self.fdict self.output = { "full_text": output_format.format(**self.fdict), "color": self.color_muted if muted else self.color, } def switch_mute(self): if self.has_mute: muted = self.alsamixer.getmute()[self.channel] self.alsamixer.setmute(not muted) def get_cur_volume(self): if self.map_volume: dbCur = self.get_db() * 100.0 dbMin = self.dbMin * 100.0 dbMax = self.dbMax * 100.0 dbCur_norm = self.exp10((dbCur - dbMax) / 6000.0) dbMin_norm = self.exp10((dbMin - dbMax) / 6000.0) vol = (dbCur_norm - dbMin_norm) / (1 - dbMin_norm) vol = int(round(vol * 100, 0)) return vol else: return self.alsamixer.getvolume()[self.channel] def get_new_volume(self, direction): if direction == "inc": volume = (self.fdict["volume"] + 1) / 100 elif direction == "dec": volume = (self.fdict["volume"] - 1) / 100 dbMin = self.dbMin * 100 dbMax = self.dbMax * 100 dbMin_norm = self.exp10((dbMin - dbMax) / 6000.0) vol = volume * (1 - dbMin_norm) + dbMin_norm if direction == "inc": dbNew = min(self.dbMax, ceil( ((6000.0 * log10(vol)) + dbMax) / 100)) elif direction == "dec": dbNew = max(self.dbMin, floor( ((6000.0 * log10(vol)) + dbMax) / 100)) volNew = int( round(self.map_db(dbNew, self.dbMin, self.dbMax, 0, 100), 0)) return volNew def increase_volume(self, delta=None): if self.map_volume: vol = self.get_new_volume("inc") self.alsamixer.setvolume(vol) else: vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume( min(100, vol + (delta if delta else self.increment))) def decrease_volume(self, delta=None): if self.map_volume: vol = self.get_new_volume("dec") self.alsamixer.setvolume(vol) else: vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume( max(0, vol - (delta if delta else self.increment))) def get_db(self): db = (((self.dbMax - self.dbMin) / 100) * self.alsamixer.getvolume()[self.channel]) + self.dbMin db = int(round(db, 0)) return db def map_db(self, value, dbMin, dbMax, volMin, volMax): dbRange = dbMax - dbMin volRange = volMax - volMin volScaled = float(value - dbMin) / float(dbRange) return volMin + (volScaled * volRange) def exp10(self, x): return exp(x * log(10))
class AlsaSync(Thread): ''' Synchronises a dummy ALSA mixer control with a volume control register of the DSP. ''' def __init__(self): self.alsa_control = None self.volume_register = None self.dsp = Adau145x self.volume_register_length = self.dsp.WORD_LENGTH self.finished = False self.pollinterval = 0.1 self.spi = SpiHandler self.dspdata = None self.dspvol = None self.alsavol = None self.mixername = None Thread.__init__(self) def set_volume_register(self, volume_register): logging.debug("Using volume register %s", volume_register) self.volume_register = volume_register # When setting a new Volume register, always update ALSA to # state of the DSP self.read_dsp_data() self.update_alsa(self.dspvol) def set_alsa_control(self, alsa_control): from alsaaudio import Mixer try: self.mixer = Mixer(alsa_control) logging.debug("using existing ALSA control %s", alsa_control) except: try: logging.debug("ALSA control %s does not exist, creating it", alsa_control) self.mixer = self.create_mixer(alsa_control) except Exception as e: logging.error("can't create ALSA mixer control %s (%s)", alsa_control, e) if self.mixer == None: logging.error("ALSA mixer %s not found", alsa_control) self.mixername = alsa_control def update_alsa(self, value): if value is None: return from alsaaudio import MIXER_CHANNEL_ALL vol = int(value) self.mixer.setvolume(vol, MIXER_CHANNEL_ALL) self.alsavol = vol def update_dsp(self, value): if value is None: return # convert percent to multiplier volume = percent2amplification(value) # write multiplier to DSP dspdata = datatools.int_data(self.dsp.decimal_repr(volume), self.volume_register_length) self.spi.write(self.volume_register, dspdata) self.dspdata = dspdata self.dspvol = value def read_alsa_data(self): from alsaaudio import Mixer volumes = Mixer(self.mixername).getvolume() channels = 0 vol = 0 for i in range(len(volumes)): channels += 1 vol += volumes[i] if channels > 0: vol = vol / channels if vol != self.alsavol: logging.debug("ALSA volume changed from {}% to {}%".format( self.alsavol, vol)) self.alsavol = vol return True else: return False def read_dsp_data(self): if self.volume_register is None: self.dspdata = None self.dspvol = None return False dspdata = self.spi.read(self.volume_register, self.volume_register_length) if dspdata != self.dspdata: # Convert to percent and round to full percent vol = int(amplification2percent(self.dsp.decimal_val(dspdata))) if vol < 0: vol = 0 elif vol > 100: vol = 100 logging.debug("DSP volume changed from {}% to {}%".format( self.dspvol, vol)) self.dspvol = vol self.dspdata = dspdata return True else: return False def check_sync(self): alsa_changed = self.read_alsa_data() dsp_changed = self.read_dsp_data() # Check if one of the control has changed and update the other # one. If both have changed, ALSA takes precedence if alsa_changed: logging.debug("Updating DSP volume from ALSA") self.update_dsp(self.alsavol) elif dsp_changed: logging.debug("Updating ALSA volume from DSP") self.update_alsa(self.dspvol) def run(self): reg_set = True try: while not (self.finished): if self.mixer is None: logging.error( "ALSA mixer not available, aborting volume synchronisation" ) break if self.volume_register is None: # Volume control register can change when a new program is # uploaded, just go on and try again later if reg_set: logging.error( "ALSA mixer not availble, volume register unknown in profile" ) reg_set = False time.sleep(1) continue else: reg_set = True self.check_sync() time.sleep(self.pollinterval) except Exception as e: logging.error("ALSA sync crashed: %s", e) def finish(self): self.finished = True @staticmethod def create_mixer(name): with tempfile.NamedTemporaryFile(mode='w', dir="/tmp", delete=False) as asoundstate: content = ALSA_STATE_FILE.replace("%VOLUME%", name) logging.debug("asoundstate file %s", content) asoundstate.write(content) asoundstate.close() try: command = "/usr/sbin/alsactl -f {} restore".format( asoundstate.name) logging.debug("runnning %s", command) os.system(command) except: logging.error("") try: from alsaaudio import Mixer return Mixer(name) except: logging.error("can't create mixer named %s")
def handle_set_volume(self, message): mixer = Mixer() code, volume = self.get_volume(message, mixer.getvolume()[0]) mixer.setvolume(volume) self.speak_dialog('set.volume', data={'volume': code})
def process(self, data): # TODO: Look into removing this emit altogether. # We need to check if any other serial bus messages # are handled by other parts of the code if "mycroft.stop" not in data: self.bus.emit(Message(data)) if "Command: system.version" in data: # This happens in response to the "system.version" message # sent during the construction of Enclosure() self.bus.emit(Message("enclosure.started")) if "mycroft.stop" in data: if has_been_paired(): create_signal('buttonPress') self.bus.emit(Message("mycroft.stop")) if "volume.up" in data: self.bus.emit(Message("mycroft.volume.increase", {'play_sound': True})) if "volume.down" in data: self.bus.emit(Message("mycroft.volume.decrease", {'play_sound': True})) if "system.test.begin" in data: self.bus.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.bus.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.bus.emit(Message("speak", { 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav").communicate() # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: # Eyes to soft gray on shutdown # self.bus.emit(Message("enclosure.eyes.color", # {'r': 70, 'g': 65, 'b': 69})) # self.bus.emit( # Message("enclosure.eyes.timedspin", # {'length': 12000})) # self.bus.emit(Message("enclosure.mouth.reset")) time.sleep(0.5) # give the system time to pass the message self.bus.emit(Message("system.shutdown")) if "unit.reboot" in data: # Eyes to soft gray on reboot # self.bus.emit(Message("enclosure.eyes.color", # {'r': 70, 'g': 65, 'b': 69})) # self.bus.emit(Message("enclosure.eyes.spin")) # self.bus.emit(Message("enclosure.mouth.reset")) time.sleep(0.5) # give the system time to pass the message self.bus.emit(Message("system.reboot")) if "unit.setwifi" in data: self.bus.emit(Message("system.wifi.setup", {'lang': self.lang})) if "unit.factory-reset" in data: self.bus.emit(Message("speak", { 'utterance': mycroft.dialog.get("reset to factory defaults")})) subprocess.call( 'rm ~/.mycroft/identity/identity2.json', shell=True) self.bus.emit(Message("system.wifi.reset")) self.bus.emit(Message("system.ssh.disable")) wait_while_speaking() # self.bus.emit(Message("enclosure.mouth.reset")) # self.bus.emit(Message("enclosure.eyes.spin")) # self.bus.emit(Message("enclosure.mouth.reset")) time.sleep(5) # give the system time to process all messages self.bus.emit(Message("system.reboot")) if "unit.enable-ssh" in data: # This is handled by the wifi client self.bus.emit(Message("system.ssh.enable")) self.bus.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh enabled")})) if "unit.disable-ssh" in data: # This is handled by the wifi client self.bus.emit(Message("system.ssh.disable")) self.bus.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh disabled")})) if "unit.enable-learning" in data or "unit.disable-learning" in data: enable = 'enable' in data word = 'enabled' if enable else 'disabled' LOG.info("Setting opt_in to: " + word) new_config = {'opt_in': enable} user_config = LocalConf(USER_CONFIG) user_config.merge(new_config) user_config.store() self.bus.emit(Message("speak", { 'utterance': mycroft.dialog.get("learning " + word)}))
def handle_set_volume(self, message): mixer = Mixer() level = self.get_volume_level(message, mixer.getvolume()[0]) mixer.setvolume(self.level_to_volume(level))
class ALSA(): def init(self): self.muted = "M" self.unmuted = "" self.color_muted = "#AAAAAA" self.color = "#FFFFFF" self.format = "♪: {volume}" self.format_muted = None self.mixer = "Master" self.mixer_id = 0 self.card = 0 self.channel = 0 self.increment = 5 self.map_volume = False self.alsamixer = None self.has_mute = True self.create_mixer() try: self.alsamixer.getmute() except ALSAAudioError: self.has_mute = False self.fdict = { "card": self.alsamixer.cardname(), "mixer": self.mixer, } self.dbRng = self.alsamixer.getrange() self.dbMin = self.dbRng[0] self.dbMax = self.dbRng[1] def create_mixer(self): self.alsamixer = Mixer( control=self.mixer, id=self.mixer_id, cardindex=self.card) def run(self): self.create_mixer() muted = False if self.has_mute: muted = self.alsamixer.getmute()[self.channel] == 1 self.fdict["volume"] = self.get_cur_volume() self.fdict["muted"] = self.muted if muted else self.unmuted self.fdict["db"] = self.get_db() if muted and self.format_muted is not None: output_format = self.format_muted else: output_format = self.format self.output = { "full_text": output_format.format(**self.fdict), "color": self.color_muted if muted else self.color, } def switch_mute(self): if self.has_mute: muted = self.alsamixer.getmute()[self.channel] self.alsamixer.setmute(not muted) def get_cur_volume(self): if self.map_volume: dbCur = self.get_db() * 100.0 dbMin = self.dbMin * 100.0 dbMax = self.dbMax * 100.0 dbCur_norm = self.exp10((dbCur - dbMax) / 6000.0) dbMin_norm = self.exp10((dbMin - dbMax) / 6000.0) vol = (dbCur_norm - dbMin_norm) / (1 - dbMin_norm) vol = int(round(vol * 100, 0)) return vol else: return self.alsamixer.getvolume()[self.channel] def get_new_volume(self, direction): if direction == "inc": volume = (self.fdict["volume"] + 1) / 100 elif direction == "dec": volume = (self.fdict["volume"] - 1) / 100 dbMin = self.dbMin * 100 dbMax = self.dbMax * 100 dbMin_norm = self.exp10((dbMin - dbMax) / 6000.0) vol = volume * (1 - dbMin_norm) + dbMin_norm if direction == "inc": dbNew = min(self.dbMax, ceil(((6000.0 * log10(vol)) + dbMax) / 100)) elif direction == "dec": dbNew = max(self.dbMin, floor(((6000.0 * log10(vol)) + dbMax) / 100)) volNew = int(round(self.map_db(dbNew, self.dbMin, self.dbMax, 0, 100), 0)) return volNew def increase_volume(self, delta=None): if self.map_volume: vol = self.get_new_volume("inc") self.alsamixer.setvolume(vol) else: vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume(min(100, vol + (delta if delta else self.increment))) def decrease_volume(self, delta=None): if self.map_volume: vol = self.get_new_volume("dec") self.alsamixer.setvolume(vol) else: vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume(max(0, vol - (delta if delta else self.increment))) def get_db(self): db = (((self.dbMax - self.dbMin) / 100) * self.alsamixer.getvolume()[self.channel]) + self.dbMin db = int(round(db, 0)) return db def map_db(self, value, dbMin, dbMax, volMin, volMax): dbRange = dbMax - dbMin volRange = volMax - volMin volScaled = float(value - dbMin) / float(dbRange) return volMin + (volScaled * volRange) def exp10(self, x): return exp(x * log(10))
def set_volume(val): id = alsaaudio.mixers(SOUND_CARD).index(SOUND_MIXER) mixer = Mixer(SOUND_MIXER, id, SOUND_CARD) mixer.setvolume(val)
class VolumeSkill(MycroftSkill): """ Control the audio volume for the Mycroft system Terminology: "Level" = Mycroft volume levels, from 0 to 11 "Volume" = ALSA mixer setting, from 0 to 100 """ MIN_LEVEL = 0 MAX_LEVEL = 11 # TODO: Translation layer (have to match word in Level.voc) VOLUME_WORDS = {'loud': 11, 'normal': 9, 'quiet': 7} def __init__(self): super(VolumeSkill, self).__init__("VolumeSkill") self.default_level = self.config.get('default_level') self.min_volume = self.config.get('min_volume') self.max_volume = self.config.get('max_volume') self.volume_sound = join(dirname(__file__), "blop-mark-diangelo.wav") try: self.mixer = Mixer("PCM") except Exception: # Retry instanciating the mixer try: self.mixer = Mixer() except Exception as e: self.log.error('Couldn\'t allocate mixer, {}'.format(repr(e))) def initialize(self): self.log.info("********** Reeg handlers") intent = IntentBuilder("IncreaseVolume").require("Volume").require( "Increase").build() self.register_intent(intent, self.handle_increase_volume) intent = IntentBuilder("DecreaseVolume").require("Volume").require( "Decrease").build() self.register_intent(intent, self.handle_decrease_volume) intent = IntentBuilder("MuteVolume").require("Volume").require( "Mute").build() self.register_intent(intent, self.handle_mute_volume) intent = IntentBuilder("UnmuteVolume").require("Volume").require( "Unmute").build() self.register_intent(intent, self.handle_unmute_volume) try: # Register handlers for messagebus events self.add_event('mycroft.volume.increase', self.handle_increase_volume) self.add_event('mycroft.volume.decrease', self.handle_decrease_volume) self.add_event('mycroft.volume.mute', self.handle_mute_volume) self.add_event('mycroft.volume.unmute', self.handle_unmute_volume) self.log.info("********** Handlers registered") except: pass @intent_handler( IntentBuilder("SetVolume").require("Volume").require("Level")) def handle_set_volume(self, message): level = self.__get_volume_level(message, self.mixer.getvolume()[0]) self.mixer.setvolume(self.__level_to_volume(level)) self.speak_dialog('set.volume', data={'volume': level}) @intent_handler( IntentBuilder("QueryVolume").require("Volume").require("Query")) def handle_query_volume(self, message): level = self.__get_volume_level(message, self.mixer.getvolume()[0]) self.speak_dialog('volume.is', data={'volume': level}) def __communicate_volume_change(self, message, dialog, code, changed): play_sound = message.data.get('play_sound', False) if play_sound: if changed: play_wav(self.volume_sound) else: if not changed: dialog = 'already.max.volume' self.speak_dialog(dialog, data={'volume': code}) # @intent_handler(IntentBuilder("IncreaseVolume").require( # "Volume").require("Increase")) def handle_increase_volume(self, message): self.__communicate_volume_change(message, 'increase.volume', *self.__update_volume(+1)) # @intent_handler(IntentBuilder("DecreaseVolume").require( # "Volume").require("Decrease")) def handle_decrease_volume(self, message): self.__communicate_volume_change(message, 'decrease.volume', *self.__update_volume(-1)) # @intent_handler(IntentBuilder("MuteVolume").require( # "Volume").require("Mute")) def handle_mute_volume(self, message): speak_message = message.data.get('speak_message', True) if speak_message: self.speak_dialog('mute.volume') wait_while_speaking() self.mixer.setvolume(0) # @intent_handler(IntentBuilder("UnmuteVolume").require( # "Volume").require("Unmute")) def handle_unmute_volume(self, message): self.mixer.setvolume(self.__level_to_volume(11)) speak_message = message.data.get('speak_message', True) if speak_message: self.speak_dialog('reset.volume', data={'volume': self.default_level}) def __volume_to_level(self, volume): """ Convert a 'volume' to a 'level' Args: volume (int): min_volume..max_volume Returns: int: the equivalent level """ range = self.MAX_LEVEL - self.MIN_LEVEL prop = float(volume - self.min_volume) / self.max_volume level = int(round(self.MIN_LEVEL + range * prop)) if level > self.MAX_LEVEL: level = self.MAX_LEVEL elif level < self.MIN_LEVEL: level = self.MIN_LEVEL return level def __level_to_volume(self, level): """ Convert a 'level' to a 'volume' Args: level (int): 0..MAX_LEVEL Returns: int: the equivalent volume """ range = self.max_volume - self.min_volume prop = float(level) / self.MAX_LEVEL volume = int(round(self.min_volume + int(range) * prop)) return volume @staticmethod def __bound_level(level): if level > VolumeSkill.MAX_LEVEL: level = VolumeSkill.MAX_LEVEL elif level < VolumeSkill.MIN_LEVEL: level = VolumeSkill.MIN_LEVEL return level def __update_volume(self, change=0): """ Attempt to change audio level Args: change (int): +1 or -1; the step to change by Returns: int: new level code (0..11) bool: whether level changed """ old_level = self.__volume_to_level(self.mixer.getvolume()[0]) new_level = self.__bound_level(old_level + change) self.enclosure.eyes_volume(new_level) self.mixer.setvolume(self.__level_to_volume(new_level)) return new_level, new_level != old_level def __get_volume_level(self, message, default=None): level_str = message.data.get('Level', default) level = self.default_level try: level = self.VOLUME_WORDS[level_str] except KeyError: try: level = int(level_str) if (level > self.MAX_LEVEL): # Guess that the user said something like 100 percent # so convert that into a level value level = self.MAX_LEVEL * level / 100 except ValueError: pass level = self.__bound_level(level) return level
def process(self, data): self.ws.emit(Message(data)) if "Command: system.version" in data: # This happens in response to the "system.version" message # sent during the construction of Enclosure() self.ws.emit(Message("enclosure.started")) if "mycroft.stop" in data: create_signal('buttonPress') self.ws.emit(Message("mycroft.stop")) if "volume.up" in data: self.ws.emit( Message("VolumeSkill:IncreaseVolumeIntent", {'play_sound': True})) if "volume.down" in data: self.ws.emit( Message("VolumeSkill:DecreaseVolumeIntent", {'play_sound': True})) if "system.test.begin" in data: self.ws.emit(Message('recognizer_loop:sleep')) if "system.test.end" in data: self.ws.emit(Message('recognizer_loop:wake_up')) if "mic.test" in data: mixer = Mixer() prev_vol = mixer.getvolume()[0] mixer.setvolume(35) self.ws.emit(Message("speak", { 'utterance': "I am testing one two three"})) time.sleep(0.5) # Prevents recording the loud button press record("/tmp/test.wav", 3.0) mixer.setvolume(prev_vol) play_wav("/tmp/test.wav").communicate() # Test audio muting on arduino subprocess.call('speaker-test -P 10 -l 0 -s 1', shell=True) if "unit.shutdown" in data: self.ws.emit( Message("enclosure.eyes.timedspin", {'length': 12000})) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl poweroff -i', shell=True) if "unit.reboot" in data: self.ws.emit( Message("enclosure.eyes.spin")) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.setwifi" in data: self.ws.emit(Message("mycroft.wifi.start")) if "unit.factory-reset" in data: self.ws.emit( Message("enclosure.eyes.spin")) subprocess.call( 'rm ~/.mycroft/identity/identity2.json', shell=True) self.ws.emit(Message("mycroft.wifi.reset")) self.ws.emit(Message("mycroft.disable.ssh")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("reset to factory defaults")})) time.sleep(5) self.ws.emit(Message("enclosure.mouth.reset")) subprocess.call('systemctl reboot -i', shell=True) if "unit.enable-ssh" in data: # This is handled by the wifi client self.ws.emit(Message("mycroft.enable.ssh")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh enabled")})) if "unit.disable-ssh" in data: # This is handled by the wifi client self.ws.emit(Message("mycroft.disable.ssh")) self.ws.emit(Message("speak", { 'utterance': mycroft.dialog.get("ssh disabled")}))
class ALSA(IntervalModule): """ Shows volume of ALSA mixer. You can also use this for inputs, btw. Requires pyalsaaudio .. rubric:: Available formatters * `{volume}` — the current volume in percent * `{muted}` — the value of one of the `muted` or `unmuted` settings * `{card}` — the associated soundcard * `{mixer}` — the associated ALSA mixer """ interval = 1 settings = ( "format", ("format_muted", "optional format string to use when muted"), ("mixer", "ALSA mixer"), ("mixer_id", "ALSA mixer id"), ("card", "ALSA sound card"), ("increment", "integer percentage of max volume to in/decrement volume on mousewheel"), "muted", "unmuted", "color_muted", "color", "channel" ) muted = "M" unmuted = "" color_muted = "#AAAAAA" color = "#FFFFFF" format = "♪: {volume}" format_muted = None mixer = "Master" mixer_id = 0 card = 0 channel = 0 increment = 5 alsamixer = None has_mute = True def init(self): self.create_mixer() try: self.alsamixer.getmute() except ALSAAudioError: self.has_mute = False self.fdict = { "card": self.alsamixer.cardname(), "mixer": self.mixer, } def create_mixer(self): self.alsamixer = Mixer( control=self.mixer, id=self.mixer_id, cardindex=self.card) def run(self): self.create_mixer() muted = False if self.has_mute: muted = self.alsamixer.getmute()[self.channel] == 1 self.fdict["volume"] = self.alsamixer.getvolume()[self.channel] self.fdict["muted"] = self.muted if muted else self.unmuted if muted and self.format_muted is not None: output_format = self.format_muted else: output_format = self.format self.output = { "full_text": output_format.format(**self.fdict), "color": self.color_muted if muted else self.color, } def on_leftclick(self): self.on_rightclick() def on_rightclick(self): if self.has_mute: muted = self.alsamixer.getmute()[self.channel] self.alsamixer.setmute(not muted) def on_upscroll(self): vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume(min(100, vol + self.increment)) def on_downscroll(self): vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume(max(0, vol - self.increment))
class Harold(object): def __init__(self, mplfifo, ser, mpout, beep=True): self.playing = False self.mixer = Mixer(control='PCM') self.fifo = mplfifo self.ser = ser self.mpout = mpout self.beep = beep def write(self, *args, **kwargs): delay = kwargs.pop("delay", 0.5) kws = {"file": self.fifo} kws.update(kwargs) print(*args, **kws) time.sleep(delay) def __call__(self): if not self.playing: userlog = open("/home/pi/logs/user_log.csv", "a") # Lower the volume during quiet hours... Don't piss off the RA! self.mixer.setvolume(85 if quiet_hours() else 100) varID = self.ser.readline() print(varID) # mplayer will play any files sent to the FIFO file. if self.beep: self.write("loadfile", DING_SONG) if "ready" not in varID: # Turn the LEDs off LED.on(False) print("Turning off LEDs") # Get the username from the ibutton print("Getting User Data") uid, homedir = read_ibutton(varID) # Print the user's name (Super handy for debugging...) print("User: '******'\n") song = get_user_song(homedir, uid) print("Now playing '" + song + "'...\n") varID = varID[:-2] userlog.write("\n" + time.strftime('%Y/%m/%d %H:%M:%S') + "," + uid + "," + song) self.write("loadfile '" + song.replace("'", "\\'") + "'\nget_time_length", delay=0.0) line = self.mpout.readline().strip() # timeout = time.time() + 5 # Five second time out to wait for song time. while not line.startswith("ANS_LENGTH="): line = self.mpout.readline().strip() if line.startswith("Playing"): # Check if mplayer can play file. if self.mpout.readline().strip() == "": self.starttime = time.time() self.endtime = time.time() self.playing = True break elif line.startswith("ANS_LENGTH="): duration = float(line.strip().split("=")[-1]) self.starttime = time.time() self.endtime = time.time() + min(30, duration) self.playing = True else: pass userlog.close() elif time.time() >= self.endtime: self.write("stop") self.playing = False self.ser.flushInput() LED.on(True) print("Stopped\n") elif time.time() >= self.starttime+28: # Fade out the music at the end. vol = int(self.mixer.getvolume()[0]) while vol > 60: vol -= 1 + (100 - vol)/30. self.mixer.setvolume(int(vol)) time.sleep(0.1)
i = 0 while True : sleep(0.1) update() i+=1 if i >= 20 : conf_file = open("../conf/wake.json") conf = jload(conf_file) s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect("mastersocket") s.send(jdumps({"request": "get_delta"})) delta = int(s.recv(4096)) if delta != 0 : mixer.setvolume(min(100, mixer.getvolume()[0] + delta)) client.clear() client.add("blup.mp3") client.play() s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect("mastersocket") s.send(jdumps({"request": "get_sw_state"})) data = int(s.recv(4096)) print data if data : show_menu(background, hex_to_rgb(conf["general"]["back_color"]))
class ALSA(IntervalModule): """ Shows volume of ALSA mixer. You can also use this for inputs, btw. Requires pyalsaaudio .. rubric:: Available formatters * `{volume}` — the current volume in percent * `{muted}` — the value of one of the `muted` or `unmuted` settings * `{card}` — the associated soundcard * `{mixer}` — the associated ALSA mixer """ interval = 1 settings = ( "format", ("format_muted", "optional format string to use when muted"), ("mixer", "ALSA mixer"), ("mixer_id", "ALSA mixer id"), ("card", "ALSA sound card"), ("increment", "integer percentage of max volume to in/decrement volume on mousewheel"), "muted", "unmuted", "color_muted", "color", "channel", ("map_volume", "volume display/setting as in AlsaMixer. increment option is ignored then.") ) muted = "M" unmuted = "" color_muted = "#AAAAAA" color = "#FFFFFF" format = "♪: {volume}" format_muted = None mixer = "Master" mixer_id = 0 card = 0 channel = 0 increment = 5 map_volume = False alsamixer = None has_mute = True on_upscroll = "increase_volume" on_downscroll = "decrease_volume" on_leftclick = "switch_mute" on_rightclick = on_leftclick def init(self): self.create_mixer() try: self.alsamixer.getmute() except ALSAAudioError: self.has_mute = False self.fdict = { "card": self.alsamixer.cardname(), "mixer": self.mixer, } self.dbRng = self.alsamixer.getrange() self.dbMin = self.dbRng[0] self.dbMax = self.dbRng[1] def create_mixer(self): self.alsamixer = Mixer( control=self.mixer, id=self.mixer_id, cardindex=self.card) def run(self): self.create_mixer() muted = False if self.has_mute: muted = self.alsamixer.getmute()[self.channel] == 1 self.fdict["volume"] = self.get_cur_volume() self.fdict["muted"] = self.muted if muted else self.unmuted self.fdict["db"] = self.get_db() if muted and self.format_muted is not None: output_format = self.format_muted else: output_format = self.format self.data = self.fdict self.output = { "full_text": output_format.format(**self.fdict), "color": self.color_muted if muted else self.color, } def switch_mute(self): if self.has_mute: muted = self.alsamixer.getmute()[self.channel] self.alsamixer.setmute(not muted) def get_cur_volume(self): if self.map_volume: dbCur = self.get_db() * 100.0 dbMin = self.dbMin * 100.0 dbMax = self.dbMax * 100.0 dbCur_norm = self.exp10((dbCur - dbMax) / 6000.0) dbMin_norm = self.exp10((dbMin - dbMax) / 6000.0) vol = (dbCur_norm - dbMin_norm) / (1 - dbMin_norm) vol = int(round(vol * 100, 0)) return vol else: return self.alsamixer.getvolume()[self.channel] def get_new_volume(self, direction): if direction == "inc": volume = (self.fdict["volume"] + 1) / 100 elif direction == "dec": volume = (self.fdict["volume"] - 1) / 100 dbMin = self.dbMin * 100 dbMax = self.dbMax * 100 dbMin_norm = self.exp10((dbMin - dbMax) / 6000.0) vol = volume * (1 - dbMin_norm) + dbMin_norm if direction == "inc": dbNew = min(self.dbMax, ceil(((6000.0 * log10(vol)) + dbMax) / 100)) elif direction == "dec": dbNew = max(self.dbMin, floor(((6000.0 * log10(vol)) + dbMax) / 100)) volNew = int(round(self.map_db(dbNew, self.dbMin, self.dbMax, 0, 100), 0)) return volNew def increase_volume(self, delta=None): if self.map_volume: vol = self.get_new_volume("inc") self.alsamixer.setvolume(vol) else: vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume(min(100, vol + (delta if delta else self.increment))) def decrease_volume(self, delta=None): if self.map_volume: vol = self.get_new_volume("dec") self.alsamixer.setvolume(vol) else: vol = self.alsamixer.getvolume()[self.channel] self.alsamixer.setvolume(max(0, vol - (delta if delta else self.increment))) def get_db(self): db = (((self.dbMax - self.dbMin) / 100) * self.alsamixer.getvolume()[self.channel]) + self.dbMin db = int(round(db, 0)) return db def map_db(self, value, dbMin, dbMax, volMin, volMax): dbRange = dbMax - dbMin volRange = volMax - volMin volScaled = float(value - dbMin) / float(dbRange) return volMin + (volScaled * volRange) def exp10(self, x): return exp(x * log(10))
class Player: def __init__(self): self.logged_in = threading.Event() self.end_of_track = threading.Event() self.queue_playlist = [] self.prev_playlist = [] self.min_volume = 70 config = spotify.Config() config.load_application_key_file(filename='/home/pi/django_projects/mysite/spotify_app/spotify_appkey.key') self.session = spotify.Session(config=config) self.loop = spotify.EventLoop(self.session) self.loop.start() self.current_track = None # Connect an audio sink self.audio = spotify.AlsaSink(self.session) self.mixer = Mixer('PCM', 0) self.session.on(spotify.SessionEvent.CONNECTION_STATE_UPDATED, self.on_connection_state_updated) self.session.on(spotify.SessionEvent.END_OF_TRACK, self.on_end_of_track) def login(self, username, password): self.session.login(username, password) self.logged_in.wait() self.player = self.session.player def logout(self): self.session.logout() def play(self, track_uri): track = self.session.get_track(track_uri).load() self.current_track = track self.player.load(track) self.player.play() def queue(self, track_uri): track = self.session.get_track(track_uri).load() self.queue_playlist.append(track) def pause(self): self.player.pause() def stop(self): self.current_track = None self.player.unload() def play_prev(self): if len(self.prev_playlist) == 0: self.play(self.current_track.link.uri) else: self.queue_playlist.insert(0, self.current_track) self.play(self.prev_playlist.pop(0).link.uri) def play_next(self): self.prev_playlist.insert(0, self.current_track) if len(self.queue_playlist) == 0: self.current_track = None else: self.play(self.queue_playlist.pop(0).link.uri); def set_audio_output(self, output): subprocess.call(["amixer", "cset", "numid=3", str(output)]) def search(self, query): search = self.session.search(query); search.load() return search.tracks def get_playlist(self): return self.queue_playlist def is_playing(self): if self.current_track == None: return False else: return True def remove_from_queue(self, index): self.queue_playlist.pop(int(index)) def set_volume(self, volume): if int(volume) == self.min_volume: volume = 0 self.mixer.setvolume(int(volume)) def get_volume(self): return self.mixer.getvolume()[0] def on_connection_state_updated(self, session): if session.connection.state is spotify.ConnectionState.LOGGED_IN: self.logged_in.set() else: self.logged_in.clear() def on_end_of_track(self, self2): self.play_next()