Пример #1
0
class PreciseConnection:
    """Represents a socket connection routed to a precise process"""

    def __init__(self, connection, address):
        self.address = address
        self.connection = connection  # type: socket.socket
        self.stream = ReadWriteStream()
        self.runner = PreciseRunner(
            ListenerEngine(Listener(MODEL_NAME, CHUNK_SIZE), CHUNK_SIZE),
            1, stream=self.stream, on_activation=self.on_activation,
            on_prediction=self.on_prediction
        )
        self.runner.start()

    def on_activation(self):
        print(' --- ACTIVATION from:', self.address, '--- ')

    def on_prediction(self, conf):
        print('!' if conf > 0.5 else '.', end='', flush=True)

    def update(self):
        """Return whether connection still alive"""
        data = self.connection.recv(CHUNK_SIZE)
        self.stream.write(data)
        return bool(data)

    def close(self):
        print('Closing connection from', self.address)
        self.runner.stop()
        self.connection.close()
Пример #2
0
    def __init__(self, key_phrase="hey mycroft", config=None, lang="en-us"):
        super(PreciseHotword, self).__init__(key_phrase, config, lang)
        from precise_runner import (PreciseRunner, PreciseEngine,
                                    ReadWriteStream)
        local_conf = LocalConf(USER_CONFIG)
        if local_conf.get('precise', {}).get('dist_url') == \
                'http://bootstrap.mycroft.ai/artifacts/static/daily/':
            del local_conf['precise']['dist_url']
            local_conf.store()
            Configuration.updated(None)

        self.download_complete = True

        self.show_download_progress = Timer(0, lambda: None)
        precise_config = Configuration.get()['precise']
        precise_exe = self.install_exe(precise_config['dist_url'])
        self.precise_model = self.install_model(
            precise_config['model_url'],
            key_phrase.replace(' ', '-')).replace('.tar.gz', '.pb')

        self.has_found = False
        self.stream = ReadWriteStream()

        def on_activation():
            self.has_found = True

        self.runner = PreciseRunner(PreciseEngine(precise_exe,
                                                  self.precise_model),
                                    stream=self.stream,
                                    on_activation=on_activation)
        self.runner.start()
Пример #3
0
class Precise():
    
    def __init__(self):
        # engine data:      https://github.com/mycroftai/precise-data/tree/dist
        # precise models:   https://github.com/MycroftAI/precise-data/tree/models?files=1
        sensitivity = float(0.5)
        trigger_level = int(3)
        model_path = "models/hey-mycroft.pb"
        engine_path = "precise-engine/precise-engine"
        engine = PreciseEngine(
            engine_path, model_path)

        self.stream = ReadWriteStream()
        self.runner = PreciseRunner(
            engine,
            sensitivity=sensitivity,
            trigger_level=trigger_level,
            on_activation=self.on_activation
        )
        print("Starting precise")
        self.runner.start()
        while True:
            data = self.stream.read()
            self.update_runner(data)

    def update_runner(self, data):
        self.stream.write(data)

    def on_activation(self):
        print("Activation!")
Пример #4
0
def main():
    args = create_parser(usage).parse_args()
    
    print('chunk_size: ', args.chunk_size)

    def on_activation():
        activate_notify()

        if args.save_dir:
            global chunk_num
            nm = join(args.save_dir, args.save_prefix + session_id + '.' + str(chunk_num) + '.wav')
            save_audio(nm, audio_buffer)
            print()
            print('Saved to ' + nm + '.')
            chunk_num += 1

    def on_prediction(conf):
        print('!' if conf > 0.8 else '.', end='', flush=True)

    listener = Listener(args.model, args.chunk_size)
    audio_buffer = np.zeros(listener.pr.buffer_samples, dtype=float)

    def get_prediction(chunk):
        nonlocal audio_buffer
        audio = buffer_to_audio(chunk)
        audio_buffer = np.concatenate((audio_buffer[len(audio):], audio))
        return listener.update(chunk)

    engine = ListenerEngine(listener, args.chunk_size)
    engine.get_prediction = get_prediction
    runner = PreciseRunner(engine, args.threshold, on_activation=on_activation,
                           on_prediction=on_prediction)
    runner.start()
    Event().wait()  # Wait forever
Пример #5
0
 def __init__(self, connection, address):
     self.address = address
     self.connection = connection  # type: socket.socket
     self.stream = ReadWriteStream()
     self.runner = PreciseRunner(
         ListenerEngine(Listener(MODEL_NAME, CHUNK_SIZE), CHUNK_SIZE),
         1, stream=self.stream, on_activation=self.on_activation,
         on_prediction=self.on_prediction
     )
     self.runner.start()
Пример #6
0
    def load_runner(self) -> None:
        """Load precise runner."""
        if self.engine is None:
            # pylint: disable=E0401
            from precise_runner import PreciseEngine

            self.model_name = self.profile.get("wake.precise.model",
                                               "hey-mycroft-2.pb")
            self.model_path = self.profile.read_path(self.model_name)
            self.engine_path = os.path.expandvars(
                self.profile.get("wake.precise.engine_path", "precise-engine"))

            self._logger.debug("Loading Precise engine at %s",
                               self.engine_path)
            self.engine = PreciseEngine(self.engine_path,
                                        self.model_path,
                                        chunk_size=self.chunk_size)

        if self.runner is None:
            # pylint: disable=E0401
            from precise_runner import PreciseRunner, ReadWriteStream

            self.stream = ReadWriteStream()

            sensitivity = float(
                self.profile.get("wake.precise.sensitivity", 0.5))
            trigger_level = int(
                self.profile.get("wake.precise.trigger_level", 3))

            def on_prediction(prob: float) -> None:
                self.prediction_sem.release()

            def on_activation() -> None:
                self.detected = True
                self.send(self.myAddress, "activated")

            self.runner = PreciseRunner(
                self.engine,
                stream=self.stream,
                sensitivity=sensitivity,
                trigger_level=trigger_level,
                on_activation=on_activation,
                on_prediction=on_prediction,
            )

            assert self.runner is not None
            self.runner.start()

            self._logger.debug(
                "Loaded Mycroft Precise (model=%s, sensitivity=%s, trigger_level=%s)",
                self.model_path,
                sensitivity,
                trigger_level,
            )
Пример #7
0
 def __init__(self, args):
     super().__init__(args)
     self.listener = Listener(args.model, args.chunk_size)
     self.audio_buffer = np.zeros(self.listener.pr.buffer_samples,
                                  dtype=float)
     self.engine = ListenerEngine(self.listener, args.chunk_size)
     self.engine.get_prediction = self.get_prediction
     self.runner = PreciseRunner(self.engine,
                                 args.trigger_level,
                                 sensitivity=args.sensitivity,
                                 on_activation=self.on_activation,
                                 on_prediction=self.on_prediction)
     self.session_id, self.chunk_num = '%09d' % randint(0, 999999999), 0
    def __init__(self, args):
        super().__init__(args)

        if args.model == 'hey-mycroft':
            args.model = None

        self.engine = PreciseEngine(exe_file=None,
                                    model_file=args.model,
                                    chunk_size=args.chunk_size)
        self.runner = PreciseRunner(self.engine,
                                    args.trigger_level,
                                    sensitivity=args.sensitivity,
                                    on_activation=self.on_activation,
                                    on_prediction=self.on_prediction)
        self.session_id, self.chunk_num = '%09d' % randint(0, 999999999), 0
Пример #9
0
    def run(self):
        def on_activation():
            activate_notify()

        def on_prediction(conf):
            print('!' if conf > 0.5 else '.', end='', flush=True)

        args = self.args
        runner = PreciseRunner(ListenerEngine(
            PocketsphinxListener(args.key_phrase, args.dict_file,
                                 args.hmm_folder, args.threshold,
                                 args.chunk_size)),
                               3,
                               on_activation=on_activation,
                               on_prediction=on_prediction)
        runner.start()
        Event().wait()  # Wait forever
Пример #10
0
	def __init__(self):
		super().__init__()
		self._hotwordThread = None

		try:
			self._stream = ReadWriteStream()
			self._handler = PreciseRunner(
				PreciseEngine(
					exe_file=f'{self.Commons.rootDir()}/venv/bin/precise-engine',
					model_file=f'{self.Commons.rootDir()}/trained/hotwords/mycroft-precise/athena.pb'
				),
				sensitivity=self.ConfigManager.getAliceConfigByName('wakewordSensitivity'),
				stream=self._stream,
				on_activation=self.hotwordSpotted
			)
		except:
			self._enabled = False
Пример #11
0
def main():
    args = create_parser(usage).parse_args()

    def on_activation():
        Popen(['aplay', '-q', 'data/activate.wav'])

    def on_prediction(conf):
        print('!' if conf > 0.5 else '.', end='', flush=True)

    runner = PreciseRunner(ListenerEngine(
        PocketsphinxListener(args.key_phrase, args.dict_file, args.hmm_folder,
                             args.threshold, args.chunk_size)),
                           3,
                           on_activation=on_activation,
                           on_prediction=on_prediction)
    runner.start()
    Event().wait()  # Wait forever
Пример #12
0
def main():
    args = create_parser(usage).parse_args()
    sensitivity = 0.5

    def on_activation():
        activate_notify()

        if args.save_dir:
            global chunk_num
            nm = join(
                args.save_dir,
                args.save_prefix + session_id + '.' + str(chunk_num) + '.wav')
            save_audio(nm, audio_buffer)
            print()
            print('Saved to ' + nm + '.')
            chunk_num += 1

    def on_prediction(conf):
        if args.light_mode:
            print('!' if conf > 0.7 else '.', end='', flush=True)
        else:
            max_width = 80
            width = min(get_terminal_size()[0], max_width)
            units = int(round(conf * width))
            bar = 'X' * units + '-' * (width - units)
            cutoff = round((1.0 - sensitivity) * width)
            print(bar[:cutoff] + bar[cutoff:].replace('X', 'x'))

    listener = Listener(args.model, args.chunk_size)
    audio_buffer = np.zeros(listener.pr.buffer_samples, dtype=float)

    def get_prediction(chunk):
        nonlocal audio_buffer
        audio = buffer_to_audio(chunk)
        audio_buffer = np.concatenate((audio_buffer[len(audio):], audio))
        return listener.update(chunk)

    engine = ListenerEngine(listener, args.chunk_size)
    engine.get_prediction = get_prediction
    runner = PreciseRunner(engine,
                           args.threshold,
                           sensitivity=sensitivity,
                           on_activation=on_activation,
                           on_prediction=on_prediction)
    runner.start()
    Event().wait()  # Wait forever
class MycroftScript(BaseScript):
    usage = Usage(__doc__)

    def __init__(self, args):
        super().__init__(args)

        if args.model == 'hey-mycroft':
            args.model = None

        self.engine = PreciseEngine(exe_file=None,
                                    model_file=args.model,
                                    chunk_size=args.chunk_size)
        self.runner = PreciseRunner(self.engine,
                                    args.trigger_level,
                                    sensitivity=args.sensitivity,
                                    on_activation=self.on_activation,
                                    on_prediction=self.on_prediction)
        self.session_id, self.chunk_num = '%09d' % randint(0, 999999999), 0

    def on_activation(self):
        activate_notify()

        if self.args.save_dir:
            nm = join(
                self.args.save_dir, self.args.save_prefix + self.session_id +
                '.' + str(self.chunk_num) + '.wav')
            save_audio(nm, self.audio_buffer)
            print()
            print('Saved to ' + nm + '.')
            self.chunk_num += 1

    def on_prediction(self, conf):
        if self.args.basic_mode:
            print('!' if conf > 0.7 else '.', end='', flush=True)
        else:
            max_width = 80
            width = min(get_terminal_size()[0], max_width)
            units = int(round(conf * width))
            bar = 'X' * units + '-' * (width - units)
            cutoff = round((1.0 - self.args.sensitivity) * width)
            print(bar[:cutoff] + bar[cutoff:].replace('X', 'x'))

    def run(self):
        self.runner.start()
        Event().wait()  # Wait forever
Пример #14
0
    def __init__(self, key_phrase="hey mycroft", config=None, lang="en-us"):
        super().__init__(key_phrase, config, lang)
        global install_package
        from petact import install_package
        from precise_runner import (PreciseRunner, PreciseEngine,
                                    ReadWriteStream)
        local_conf = LocalConf(USER_CONFIG)
        if (local_conf.get('precise', {}).get('dist_url') ==
                'http://bootstrap.mycroft.ai/artifacts/static/daily/'):
            del local_conf['precise']['dist_url']
            local_conf.store()
            Configuration.updated(None)

        self.download_complete = True

        self.show_download_progress = Timer(0, lambda: None)
        precise_config = Configuration.get()['precise']

        precise_exe = self.update_precise(precise_config)

        local_model = self.config.get('local_model_file')
        if local_model:
            self.precise_model = expanduser(local_model)
        else:
            self.precise_model = self.install_model(
                precise_config['model_url'],
                key_phrase.replace(' ', '-')).replace('.tar.gz', '.pb')

        self.has_found = False
        self.stream = ReadWriteStream()

        def on_activation():
            self.has_found = True

        trigger_level = self.config.get('trigger_level', 3)
        sensitivity = self.config.get('sensitivity', 0.5)

        self.runner = PreciseRunner(
            PreciseEngine(precise_exe, self.precise_model),
            trigger_level,
            sensitivity,
            stream=self.stream,
            on_activation=on_activation,
        )
        self.runner.start()
Пример #15
0
    def load_runner(self) -> None:
        if self.engine is None:
            from precise_runner import PreciseEngine

            self.model_name = self.profile.get("wake.precise.model")
            self.model_path = self.profile.read_path(self.model_name)
            self.engine_path = self.profile.get("wake.precise.engine_path")

            self._logger.debug(f"Loading Precise engine at {self.engine_path}")
            self.engine = PreciseEngine(
                self.engine_path, self.model_path, chunk_size=self.chunk_size
            )

        if self.runner is None:
            from precise_runner import PreciseRunner

            self.stream = ByteStream()

            sensitivity = float(self.profile.get("wake.precise.sensitivity", 0.5))
            trigger_level = int(self.profile.get("wake.precise.trigger_level", 3))

            def on_prediction(prob: float) -> None:
                self.prediction_event.set()

            def on_activation() -> None:
                self.detected = True

            self.runner = PreciseRunner(
                self.engine,
                stream=self.stream,
                sensitivity=sensitivity,
                trigger_level=trigger_level,
                on_prediction=on_prediction,
                on_activation=on_activation,
            )

            assert self.runner is not None
            self.runner.start()

            self._logger.debug(
                "Loaded Mycroft Precise (model=%s, sensitivity=%s, trigger_level=%s)"
                % (self.model_path, sensitivity, trigger_level)
            )
def main():
    rospy.init_node('wake_word_detection_node')
    print("node is up")

    def on_activation():
        print("activate")
        playsound(res_path + "/attention.wav")
        try:
            requests.get('http://www.google.com')
            try:
                response = stop_speech_perception_service(True)
                print(response)
            except rospy.ServiceException as exc:
                print("Service did not process request: " + str(exc))
        except requests.ConnectionError:
            print("no internet")
            speak_pub.publish(
                "I'm sorry. I am not connected to the internet now and cannot answer"
            )
            set_emotion_service(state="SADNESS", timeout=5500, restore=True)

    def on_prediction(conf):
        print(".")

    listener = Listener(res_path + "/stevie_10_06.pb", chunk_size)
    audio_buffer = np.zeros(listener.pr.buffer_samples, dtype=float)

    def get_prediction(chunk):
        nonlocal audio_buffer
        audio = buffer_to_audio(chunk)
        audio_buffer = np.concatenate((audio_buffer[len(audio):], audio))
        return listener.update(chunk)

    engine = ListenerEngine(listener, chunk_size)
    engine.get_prediction = get_prediction
    runner = PreciseRunner(engine,
                           trigger_level=3,
                           sensitivity=0.5,
                           on_activation=on_activation,
                           on_prediction=on_prediction)
    runner.start()
    print("spinning")
    rospy.spin()
Пример #17
0
def main():
    args = create_parser(usage).parse_args()

    def on_activation():
        activate_notify()

        if args.save_dir:
            global chunk_num
            nm = join(
                args.save_dir,
                args.save_prefix + session_id + '.' + str(chunk_num) + '.wav')
            save_audio(nm, audio_buffer)
            print()
            print('Saved to ' + nm + '.')
            chunk_num += 1

    def on_prediction(conf):
        global detecting_flag
        # print('!' if conf > 0.5 else '.', end='', flush=True)
        if conf > 0.5:
            detecting_flag = True
        if conf < 0.5 and detecting_flag:
            print(colored("Yeah! I'm Here.", 'green'))
            detecting_flag = False

    sunshine_model = './ok-sunshine.net'
    listener = Listener(sunshine_model, args.chunk_size)
    audio_buffer = np.zeros(listener.pr.buffer_samples, dtype=float)

    def get_prediction(chunk):
        nonlocal audio_buffer
        audio = buffer_to_audio(chunk)
        audio_buffer = np.concatenate((audio_buffer[len(audio):], audio))
        return listener.update(chunk)

    engine = ListenerEngine(listener, args.chunk_size)
    engine.get_prediction = get_prediction
    runner = PreciseRunner(engine,
                           args.threshold,
                           on_activation=on_activation,
                           on_prediction=on_prediction)
    runner.start()
    Event().wait()  # Wait forever
Пример #18
0
    def async_listen(call):
        nonlocal runner, detected_event

        hass.states.async_set(OBJECT_DECODER, STATE_LISTENING, state_attrs)

        engine = PreciseEngine('precise-engine', model)
        runner = PreciseRunner(engine,
                               sensitivity=sensitivity,
                               trigger_level=trigger_level,
                               on_activation=lambda: detected_event.set())


        # Runs in a separate thread
        detected_event.clear()
        runner.start()
        yield from asyncio.get_event_loop().run_in_executor(None, detected_event.wait)

        if not terminated:
            runner.stop()
            runner = None

            hass.states.async_set(OBJECT_DECODER, STATE_IDLE, state_attrs)

            # Fire detected event
            hass.bus.async_fire(EVENT_HOTWORD_DETECTED, {
                'name': name,       # name of the component
                'model': model      # model used
            })
Пример #19
0
 def detect():
     event = threading.Event()
     runner = PreciseRunner(engine, on_activation=lambda: event.set())
     runner.start()
     event.wait()
     wake_statuses[system] = 'detected'
     runner.stop()
    def __init__(self, factory, client, queue, sample_rate=16000):
        super(WebsocketAudioListener, self).__init__()
        self.client = client
        self.factory = factory
        self.sample_rate = sample_rate
        self.vad = webrtcvad.Vad(1)
        self.queue = queue

        self.hotword_found = False
        self.hotword_stream = ReadWriteStream()

        def on_activation():
            self.hotword_found = True

        trigger_level = 1
        sensitivity = 0.5

        self.hotword_runner = PreciseRunner(
            PreciseEngine('/opt/backend/precise-engine/precise-engine',
                          '/opt/backend/hey-mycroft.pb'),
            trigger_level,
            sensitivity,
            stream=self.hotword_stream,
            on_activation=on_activation,
        )
        self.hotword_runner.start()

        BLOCKS_PER_SECOND = 50
        self.block_size = int(self.sample_rate /
                              float(BLOCKS_PER_SECOND))  # 320
        padding_ms = 600
        block_duration_ms = 1000 * \
            self.block_size // self.sample_rate  # 20
        num_padding_blocks = padding_ms // block_duration_ms  # 30
        self.ratio = 0.75

        self.ring_buffer = deque(maxlen=num_padding_blocks)
        self.triggered = False
        self.running = True
Пример #21
0
    def __init__(self, key_phrase="hey mycroft", config=None, lang="en-us"):
        super().__init__(key_phrase, config, lang)
        from petact import install_package
        from precise_runner import (
            PreciseRunner, PreciseEngine, ReadWriteStream
        )
        global install_package

        self.download_complete = True

        self.show_download_progress = Timer(0, lambda: None)
        precise_config = CONFIGURATION['precise']

        precise_exe = self.update_precise(precise_config)

        local_model = self.config.get('local_model_file')
        if local_model:
            self.precise_model = expanduser(local_model)
        else:
            self.precise_model = self.install_model(
                precise_config['model_url'], key_phrase.replace(' ', '-')
            ).replace('.tar.gz', '.pb')

        self.has_found = False
        self.stream = ReadWriteStream()

        def on_activation():
            self.has_found = True

        trigger_level = self.config.get('trigger_level', 3)
        sensitivity = self.config.get('sensitivity', 0.5)

        self.runner = PreciseRunner(
            PreciseEngine(precise_exe, self.precise_model),
            trigger_level, sensitivity,
            stream=self.stream, on_activation=on_activation,
        )
        self.runner.start()
Пример #22
0
    def __init__(self, rt, on_activation: Callable):
        super().__init__(rt, on_activation)

        exe_file = which('precise-engine')
        precise_folder = join(self.rt.paths.user_config, 'precise')
        if not exe_file:
            exe_file = join(precise_folder, 'precise-engine', 'precise-engine')
            download_extract_tar(
                self.program_url.format(arch=platform.machine()),
                precise_folder, check_md5=False, subdir='precise-engine',
                on_update=lambda: self.rt.interfaces.faceplate.text('Updating listener...'),
                on_complete=lambda: self.rt.interfaces.faceplate.reset()
            )
        log.debug('Using precise executable: ' + exe_file)

        model_folder = join(precise_folder, 'models', self.wake_word)
        model_file = join(model_folder, self.wake_word + '.pb')
        model_url = self.model_url.format(model_name=self.wake_word)
        download_extract_tar(model_url, model_folder, check_md5=True)

        from precise_runner import PreciseRunner, PreciseEngine
        engine = PreciseEngine(exe_file, model_file, chunk_size=1024)
        self.runner = PreciseRunner(engine, on_activation=on_activation)
Пример #23
0
    def __init__(self,
                 keyword=None,
                 sensitivity=None,
                 detected_callback=None
                ):
                 
        super(HotwordDetector, self).__init__()
        sl = SettingLoader()
        self.settings = sl.settings
        self.paused_loop = False
        self.detected_callback = detected_callback
        self.sensitivity = sensitivity
        trigger_level = 3
        self.keyword = keyword
        self.found_keyword = False

        if not os.path.exists(RESOURCE_FILE):
            if self.downloadPreciseEngine():
                Utils.print_info("[Precise] Download complete")
            else:
                raise PreciseEngineNotFound("Error downloading precise engine, check your internet connection or try again later.")

        engine = PreciseEngine(RESOURCE_FILE, self.keyword)

        self.stream = ReadWriteStream()
        self.runner = PreciseRunner(engine,
                                    sensitivity=float(self.sensitivity),
                                    trigger_level=trigger_level,
                                    on_activation=self.activation
                                    )
        
        self.runner.start()
        self.pause()                                    # To avoid that precise starts detecting without beeing ready, we pause it right after start
        if self.settings.machine.startswith("arm"):     # Because importing tensorflow takes up to 10 seconds, we sleep a while
            Utils.print_info("Starting precise trigger")
            time.sleep(10)
Пример #24
0
def main():
    args = create_parser(usage).parse_args()

    def on_activation():
        activate_notify()
        # TODO: trigger VMSE

    def on_prediction(conf):
        if args.basic_mode:
            print('!' if conf > 0.7 else '.', end='', flush=True)
        else:
            max_width = 80
            width = min(get_terminal_size()[0], max_width)
            units = int(round(conf * width))
            bar = 'X' * units + '-' * (width - units)
            cutoff = round((1.0 - args.sensitivity) * width)
            print(bar[:cutoff] + bar[cutoff:].replace('X', 'x'))

    listener = Listener(args.model, args.chunk_size)
    audio_buffer = np.zeros(listener.pr.buffer_samples, dtype=float)

    def get_prediction(chunk):
        nonlocal audio_buffer
        audio = buffer_to_audio(chunk)
        audio_buffer = np.concatenate((audio_buffer[len(audio):], audio))
        return listener.update(chunk)

    engine = ListenerEngine(listener, args.chunk_size)
    engine.get_prediction = get_prediction
    runner = PreciseRunner(engine,
                           args.trigger_level,
                           sensitivity=args.sensitivity,
                           on_activation=on_activation,
                           on_prediction=on_prediction)
    runner.start()
    Event().wait()  # Wait forever
Пример #25
0
class PreciseEngine(WakeWordEnginePlugin):
    program_url = (
        'https://raw.githubusercontent.com/MycroftAI/'
        'precise-data/dist/{arch}/precise-engine.tar.gz'
    )
    model_url = (
        'https://raw.githubusercontent.com/MycroftAI/'
        'precise-data/models/{model_name}.tar.gz'
    )

    def __init__(self, rt, on_activation: Callable):
        super().__init__(rt, on_activation)

        exe_file = which('precise-engine')
        precise_folder = join(self.rt.paths.user_config, 'precise')
        if not exe_file:
            exe_file = join(precise_folder, 'precise-engine', 'precise-engine')
            download_extract_tar(
                self.program_url.format(arch=platform.machine()),
                precise_folder, check_md5=False, subdir='precise-engine',
                on_update=lambda: self.rt.interfaces.faceplate.text('Updating listener...'),
                on_complete=lambda: self.rt.interfaces.faceplate.reset()
            )
        log.debug('Using precise executable: ' + exe_file)

        model_folder = join(precise_folder, 'models', self.wake_word)
        model_file = join(model_folder, self.wake_word + '.pb')
        model_url = self.model_url.format(model_name=self.wake_word)
        download_extract_tar(model_url, model_folder, check_md5=True)

        from precise_runner import PreciseRunner, PreciseEngine
        engine = PreciseEngine(exe_file, model_file, chunk_size=1024)
        self.runner = PreciseRunner(engine, on_activation=on_activation)

    def startup(self):
        self.runner.start()

    def shutdown(self):
        self.runner.stop()

    def continue_listening(self):
        self.runner.play()

    def pause_listening(self):
        self.runner.pause()
Пример #26
0
def main():
    parser = ArgumentParser('Implementation demo of precise-engine')
    parser.add_argument('engine', help='Location of binary engine file')
    parser.add_argument('model')
    args = parser.parse_args()

    def on_prediction(prob):
        print('!' if prob > 0.5 else '.', end='', flush=True)

    def on_activation():
        Popen(['aplay', '-q', 'data/activate.wav'])

    engine = PreciseEngine(args.engine, args.model)
    PreciseRunner(engine, on_prediction=on_prediction, on_activation=on_activation,
                  trigger_level=0).start()
    Event().wait()  # Wait forever
Пример #27
0
    def listen_for_wake_words(self, word_library, activation_notifier,
                              startdelay):
        def on_prediction(prob):
            pass

        def on_activation():
            if self.speech_locked:
                print("no activation, speech is locked")
                return
            print("ACTIVATION: {}".format(activation_notifier))

            msg = RosString()
            msg.data = activation_notifier
            self.command_triggered_pub.publish(msg)

            if activation_notifier != "heyrobot" and activation_notifier != "stop_listening":
                if self.engines[activation_notifier][2]:
                    self.start_stream_callback(activation_notifier)
            elif activation_notifier == "heyrobot":
                if self.engines[activation_notifier][2]:
                    self.start_countdown()
                    self.start_perpetual_stream_callback()
            else:
                print("auto 4")
                self.end_countdown()
                self.end_perpetual_stream()

        path = sys.argv[1]

        time.sleep(startdelay)
        print("{} ready".format(activation_notifier))

        engine = PreciseEngine('{}/.venv/bin/precise-engine'.format(path),
                               word_library)
        self.engines[activation_notifier][0] = PreciseRunner(
            engine,
            on_prediction=on_prediction,
            on_activation=on_activation,
            trigger_level=0)
        self.engines[activation_notifier][0].start()
    def __init__(self, model):

        print("*** MODEL ***", model)
        self.wake_word = rospy.Publisher(WAKE_WORD_TOPIC, Bool, queue_size=10)

        self.stream = ReadWriteStream()

        rospy.Subscriber(CONVERTED_AUDIO_TOPIC, Float32MultiArray,
                         self.audio_cb)

        engine = PreciseEngine(os.path.join(PRECISE_DIR,
                                            '.venv/bin/precise-engine'),
                               model,
                               chunk_size=1024)

        # stream = binary 16 bit mono!
        PreciseRunner(engine,
                      stream=self.stream,
                      on_prediction=self.on_prediction,
                      on_activation=self.on_activation,
                      trigger_level=3,
                      sensitivity=0.8).start()
Пример #29
0
    def __init__(self, key_phrase="hey mycroft", config=None, lang="en-us"):
        super(PreciseHotword, self).__init__(key_phrase, config, lang)
        from precise_runner import (
            PreciseRunner, PreciseEngine, ReadWriteStream
        )
        local_conf = LocalConf(USER_CONFIG)
        if local_conf.get('precise', {}).get('dist_url') == \
                'http://bootstrap.mycroft.ai/artifacts/static/daily/':
            del local_conf['precise']['dist_url']
            local_conf.store()
            Configuration.updated(None)

        self.download_complete = True

        self.show_download_progress = Timer(0, lambda: None)
        precise_config = Configuration.get()['precise']
        precise_exe = self.install_exe(precise_config['dist_url'])

        local_model = self.config.get('local_model_file')
        if local_model:
            self.precise_model = expanduser(local_model)
        else:
            self.precise_model = self.install_model(
                precise_config['model_url'], key_phrase.replace(' ', '-')
            ).replace('.tar.gz', '.pb')

        self.has_found = False
        self.stream = ReadWriteStream()

        def on_activation():
            self.has_found = True

        self.runner = PreciseRunner(
            PreciseEngine(precise_exe, self.precise_model),
            stream=self.stream, on_activation=on_activation
        )
        self.runner.start()
Пример #30
0
class PreciseWakeListener(RhasspyActor):
    """Listens for a wake word using Mycroft Precise."""
    def __init__(self) -> None:
        # pylint: disable=E0401
        from precise_runner import ReadWriteStream

        RhasspyActor.__init__(self)
        self.audio_buffer: bytes = bytes()
        self.audio_info: Dict[Any, Any] = {}
        self.chunk_delay = 0
        self.chunk_size = 2048
        self.detected: bool = False
        self.engine = None
        self.engine_path = ""
        self.model_name = ""
        self.model_path = ""
        self.prediction_sem = threading.Semaphore()
        self.preload = False
        self.receivers: List[RhasspyActor] = []
        self.recorder: Optional[RhasspyActor] = None
        self.runner = None
        self.send_not_detected = False
        self.stream: Optional[ReadWriteStream] = None

    def to_started(self, from_state: str) -> None:
        """Transition to started state."""
        self.recorder = self.config["recorder"]
        self.preload = self.config.get("preload", False)
        self.send_not_detected = self.config.get("not_detected", False)
        self.chunk_size = self.profile.get("wake.precise.chunk_size", 2048)
        self.chunk_delay = self.profile.get("wake.precise.chunk_delay", 0)

        if self.preload:
            try:
                self.load_runner()
            except Exception:
                pass

        self.transition("loaded")

    def in_loaded(self, message: Any, sender: RhasspyActor) -> None:
        """Handle messages in loaded state."""
        if isinstance(message, ListenForWakeWord):
            try:
                self.load_runner()
                self.receivers.append(message.receiver or sender)
                self.transition("listening")
                if message.record:
                    self.send(self.recorder, StartStreaming(self.myAddress))
            except Exception:
                self._logger.exception("in_loaded")

    def in_listening(self, message: Any, sender: RhasspyActor) -> None:
        """Handle messages in listening state."""
        try:
            if isinstance(message, AudioData):
                self.audio_info = message.info
                self.detected = False
                self.audio_buffer += message.data
                num_chunks = len(self.audio_buffer) // self.chunk_size

                if num_chunks > 0:
                    assert self.stream is not None
                    self.prediction_sem = threading.Semaphore()
                    for _ in range(num_chunks):
                        chunk = self.audio_buffer[:self.chunk_size]
                        self.stream.write(chunk)
                        self.audio_buffer = self.audio_buffer[self.chunk_size:]

                    if self.send_not_detected:
                        # Wait for all chunks to finish processing
                        for _ in range(num_chunks):
                            self.prediction_sem.acquire(timeout=0.1)

                        # Wait a little bit for the precise engine to finish processing
                        time.sleep(self.chunk_delay)
                        if not self.detected:
                            # Not detected
                            not_detected_event = WakeWordNotDetected(
                                self.model_name, audio_data_info=message.info)
                            for receiver in self.receivers:
                                self.send(receiver, not_detected_event)
            elif isinstance(message, StopListeningForWakeWord):
                self.receivers.remove(message.receiver or sender)
                if len(self.receivers) == 0:
                    if message.record:
                        self.send(self.recorder, StopStreaming(self.myAddress))
                    self.transition("loaded")
            elif isinstance(message, str):
                # Detected
                self._logger.debug("Hotword detected (%s)", self.model_name)
                detected_event = WakeWordDetected(
                    self.model_name, audio_data_info=self.audio_info)
                for receiver in self.receivers:
                    self.send(receiver, detected_event)
        except Exception:
            self._logger.exception("in_listening")

    def to_stopped(self, from_state: str) -> None:
        """Transition to stopped state."""
        self.stream = None

        if self.runner is not None:
            self.runner.stop()

    # -------------------------------------------------------------------------

    def load_runner(self) -> None:
        """Load precise runner."""
        if self.engine is None:
            # pylint: disable=E0401
            from precise_runner import PreciseEngine

            self.model_name = self.profile.get("wake.precise.model",
                                               "hey-mycroft-2.pb")
            self.model_path = self.profile.read_path(self.model_name)
            self.engine_path = os.path.expandvars(
                self.profile.get("wake.precise.engine_path", "precise-engine"))

            self._logger.debug("Loading Precise engine at %s",
                               self.engine_path)
            self.engine = PreciseEngine(self.engine_path,
                                        self.model_path,
                                        chunk_size=self.chunk_size)

        if self.runner is None:
            # pylint: disable=E0401
            from precise_runner import PreciseRunner, ReadWriteStream

            self.stream = ReadWriteStream()

            sensitivity = float(
                self.profile.get("wake.precise.sensitivity", 0.5))
            trigger_level = int(
                self.profile.get("wake.precise.trigger_level", 3))

            def on_prediction(prob: float) -> None:
                self.prediction_sem.release()

            def on_activation() -> None:
                self.detected = True
                self.send(self.myAddress, "activated")

            self.runner = PreciseRunner(
                self.engine,
                stream=self.stream,
                sensitivity=sensitivity,
                trigger_level=trigger_level,
                on_activation=on_activation,
                on_prediction=on_prediction,
            )

            assert self.runner is not None
            self.runner.start()

            self._logger.debug(
                "Loaded Mycroft Precise (model=%s, sensitivity=%s, trigger_level=%s)",
                self.model_path,
                sensitivity,
                trigger_level,
            )

    # -------------------------------------------------------------------------

    def get_problems(self) -> Dict[str, Any]:
        """Get problems at startup."""
        problems: Dict[str, Any] = {}
        try:
            # pylint: disable=E0401,W0611
            from precise_runner import PreciseRunner, ReadWriteStream  # noqa: F401
        except Exception:
            problems[
                "precise_runner not installed"] = "The precise_runner Python library is not installed. Try pip3 install precise_runner"

        engine_path = os.path.expandvars(
            self.profile.get("wake.precise.engine_path", "precise-engine"))

        if not os.path.exists(engine_path) and not shutil.which(engine_path):
            problems[
                "Missing precise-engine"] = 'The Mycroft Precise engine is not installed. Follow the <a href="https://github.com/MycroftAI/mycroft-precise#binary-install">binary install instructions</a>.'

        model_name = self.profile.get("wake.precise.model", "hey-mycroft-2.pb")
        model_path = self.profile.read_path(model_name)
        if not os.path.exists(model_path):
            problems[
                "Missing model"] = f"Your Mycroft Precise model could not be loaded from {model_path}"

        return problems
Пример #31
0
class PreciseHotword(HotWordEngine):
    """Precice is the default wakeword engine for mycroft.

    Precise is developed by Mycroft AI and produces quite good wake word
    spotting when trained on a decent dataset.
    """
    def __init__(self, key_phrase="hey mycroft", config=None, lang="en-us"):
        super().__init__(key_phrase, config, lang)
        from precise_runner import (
            PreciseRunner, PreciseEngine, ReadWriteStream
        )
        local_conf = LocalConf(USER_CONFIG)
        if (local_conf.get('precise', {}).get('dist_url') ==
                'http://bootstrap.mycroft.ai/artifacts/static/daily/'):
            del local_conf['precise']['dist_url']
            local_conf.store()
            Configuration.updated(None)

        self.download_complete = True

        self.show_download_progress = Timer(0, lambda: None)
        precise_config = Configuration.get()['precise']

        precise_exe = self.update_precise(precise_config)

        local_model = self.config.get('local_model_file')
        if local_model:
            self.precise_model = expanduser(local_model)
        else:
            self.precise_model = self.install_model(
                precise_config['model_url'], key_phrase.replace(' ', '-')
            ).replace('.tar.gz', '.pb')

        self.has_found = False
        self.stream = ReadWriteStream()

        def on_activation():
            self.has_found = True

        trigger_level = self.config.get('trigger_level', 3)
        sensitivity = self.config.get('sensitivity', 0.5)

        self.runner = PreciseRunner(
            PreciseEngine(precise_exe, self.precise_model),
            trigger_level, sensitivity,
            stream=self.stream, on_activation=on_activation,
        )
        self.runner.start()

    def update_precise(self, precise_config):
        """Continously try to download precise until successful"""
        precise_exe = None
        while not precise_exe:
            try:
                precise_exe = self.install_exe(precise_config['dist_url'])
            except TriggerReload:
                raise
            except Exception as e:
                LOG.error(
                    'Precise could not be downloaded({})'.format(repr(e)))
                if exists(self.install_destination):
                    precise_exe = self.install_destination
                else:
                    # Wait one minute before retrying
                    sleep(60)
        return precise_exe

    @property
    def folder(self):
        return join(expanduser('~'), '.mycroft', 'precise')

    @property
    def install_destination(self):
        return join(self.folder, 'precise-engine', 'precise-engine')

    def install_exe(self, url: str) -> str:
        url = url.format(arch=platform.machine())
        if not url.endswith('.tar.gz'):
            url = requests.get(url).text.strip()
        if install_package(
                url, self.folder,
                on_download=self.on_download, on_complete=self.on_complete
        ):
            raise TriggerReload
        return self.install_destination

    def install_model(self, url: str, wake_word: str) -> str:
        model_url = url.format(wake_word=wake_word)
        model_file = join(self.folder, posixpath.basename(model_url))
        try:
            install_package(
                model_url, self.folder,
                on_download=lambda: LOG.info('Updated precise model')
            )
        except (HTTPError, ValueError):
            if isfile(model_file):
                LOG.info("Couldn't find remote model.  Using local file")
            else:
                raise NoModelAvailable('Failed to download model:', model_url)
        return model_file

    @staticmethod
    def _snd_msg(cmd):
        with suppress(OSError):
            with open('/dev/ttyAMA0', 'w') as f:
                print(cmd, file=f)

    def on_download(self):
        LOG.info('Downloading Precise executable...')
        if isdir(join(self.folder, 'precise-stream')):
            rmtree(join(self.folder, 'precise-stream'))
        for old_package in glob(join(self.folder, 'precise-engine_*.tar.gz')):
            os.remove(old_package)
        self.download_complete = False
        self.show_download_progress = Timer(
            5, self.during_download, args=[True]
        )
        self.show_download_progress.start()

    def during_download(self, first_run=False):
        LOG.info('Still downloading executable...')
        if first_run:  # TODO: Localize
            self._snd_msg('mouth.text=Updating listener...')
        if not self.download_complete:
            self.show_download_progress = Timer(30, self.during_download)
            self.show_download_progress.start()

    def on_complete(self):
        LOG.info('Precise download complete!')
        self.download_complete = True
        self.show_download_progress.cancel()
        self._snd_msg('mouth.reset')

    def update(self, chunk):
        self.stream.write(chunk)

    def found_wake_word(self, frame_data):
        if self.has_found:
            self.has_found = False
            return True
        return False

    def stop(self):
        if self.runner:
            self.runner.stop()
Пример #32
0
class PreciseHotword(HotWordEngine):
    def __init__(self, key_phrase="hey mycroft", config=None, lang="en-us"):
        super(PreciseHotword, self).__init__(key_phrase, config, lang)
        from precise_runner import (
            PreciseRunner, PreciseEngine, ReadWriteStream
        )
        local_conf = LocalConf(USER_CONFIG)
        if local_conf.get('precise', {}).get('dist_url') == \
                'http://bootstrap.mycroft.ai/artifacts/static/daily/':
            del local_conf['precise']['dist_url']
            local_conf.store()
            Configuration.updated(None)

        self.download_complete = True

        self.show_download_progress = Timer(0, lambda: None)
        precise_config = Configuration.get()['precise']
        precise_exe = self.install_exe(precise_config['dist_url'])

        local_model = self.config.get('local_model_file')
        if local_model:
            self.precise_model = expanduser(local_model)
        else:
            self.precise_model = self.install_model(
                precise_config['model_url'], key_phrase.replace(' ', '-')
            ).replace('.tar.gz', '.pb')

        self.has_found = False
        self.stream = ReadWriteStream()

        def on_activation():
            self.has_found = True

        self.runner = PreciseRunner(
            PreciseEngine(precise_exe, self.precise_model),
            stream=self.stream, on_activation=on_activation
        )
        self.runner.start()

    @property
    def folder(self):
        return join(expanduser('~'), '.mycroft', 'precise')

    def install_exe(self, url: str) -> str:
        url = url.format(arch=platform.machine())
        if not url.endswith('.tar.gz'):
            url = requests.get(url).text.strip()
        if install_package(
                url, self.folder,
                on_download=self.on_download, on_complete=self.on_complete
        ):
            raise TriggerReload
        return join(self.folder, 'precise-engine', 'precise-engine')

    def install_model(self, url: str, wake_word: str) -> str:
        model_url = url.format(wake_word=wake_word)
        model_file = join(self.folder, posixpath.basename(model_url))
        try:
            install_package(
                model_url, self.folder,
                on_download=lambda: LOG.info('Updated precise model')
            )
        except (HTTPError, ValueError):
            if isfile(model_file):
                LOG.info("Couldn't find remote model.  Using local file")
            else:
                raise NoModelAvailable('Failed to download model:', model_url)
        return model_file

    @staticmethod
    def _snd_msg(cmd):
        with suppress(OSError):
            with open('/dev/ttyAMA0', 'w') as f:
                print(cmd, file=f)

    def on_download(self):
        LOG.info('Downloading Precise executable...')
        if isdir(join(self.folder, 'precise-stream')):
            rmtree(join(self.folder, 'precise-stream'))
        for old_package in glob(join(self.folder, 'precise-engine_*.tar.gz')):
            os.remove(old_package)
        self.download_complete = False
        self.show_download_progress = Timer(
            5, self.during_download, args=[True]
        )
        self.show_download_progress.start()

    def during_download(self, first_run=False):
        LOG.info('Still downloading executable...')
        if first_run:  # TODO: Localize
            self._snd_msg('mouth.text=Updating listener...')
        if not self.download_complete:
            self.show_download_progress = Timer(30, self.during_download)
            self.show_download_progress.start()

    def on_complete(self):
        LOG.info('Precise download complete!')
        self.download_complete = True
        self.show_download_progress.cancel()
        self._snd_msg('mouth.reset')

    def update(self, chunk):
        self.stream.write(chunk)

    def found_wake_word(self, frame_data):
        if self.has_found:
            self.has_found = False
            return True
        return False

    def stop(self):
        if self.runner:
            self.runner.stop()