예제 #1
0
def cli_cmd_load_directory(args):
    # Set the logging level.
    _set_logging_level(args)

    # Initialise the specified engine. Return early if there was an error.
    engine = _init_engine(args)
    if engine is None:
        return 1

    # Connect the engine, load each command module and start the main
    # recognition loop. The loop will normally exit on engine.disconnect()
    # or a keyboard interrupt.
    LOG.debug("Recognizing with engine '%s'", args.engine)
    with engine.connection():
        if args.recursive:
            LOG.info("Loading command modules in sub-directories as "
                     "specified (recursive mode).")
        directory = CommandModuleDirectory(args.module_dir,
                                           recursive=args.recursive)
        directory.load()
        return_code = 0 if directory.loaded else 1

        # Return early if --no-input was specified.
        if args.no_input:
            return return_code

        _do_recognition(engine, args)

    # Return the success of module loading.
    return return_code
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "wsr_module_loader_plus.py")

    # Set any configuration options here as keyword arguments.
    engine = get_engine("sapi5inproc")

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    load_sleep_wake_grammar(True)

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Start the engine's main recognition loop
    try:
        # Recognize from WSR in a loop.
        print("Listening...")
        engine.recognize_forever()
    except KeyboardInterrupt:
        pass
예제 #3
0
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        #  when this module is run from PythonWin.  In this case we
        #  simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "dfly-loader-wsr.py")

    # Initialize and connect the engine.
    # Set any configuration options here as keyword arguments.
    engine = get_engine("sapi5inproc")
    engine.connect()

    # Load grammars.
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Define recognition callback functions.
    def on_begin():
        print("Speech start detected.")

    def on_recognition(words):
        print("Recognized: %s" % " ".join(words))

    def on_failure():
        print("Sorry, what was that?")

    # Recognize from WSR in a loop.
    try:
        engine.do_recognition(on_begin, on_recognition, on_failure)
    except KeyboardInterrupt:
        pass
예제 #4
0
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        #  when this module is run from PythonWin.  In this case we
        #  simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "dfly-loader-natlink.py")

    engine = get_engine("natlink")
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Recognize from Dragon in a loop (opens a dialogue window).
    engine.natlink.waitForSpeech()

    # Unload all grammars from the engine so that Dragon doesn't keep
    # recognizing them.
    for grammar in engine.grammars:
        grammar.unload()

    # Disconnect after the dialogue is closed.
    engine.disconnect()
예제 #5
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        #  when this module is run from PythonWin.  In this case we
        #  simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "dfly-loader-wsr.py")

    engine = get_engine("sapi5inproc")
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    engine.speak('beginning loop!')
    while 1:
        pythoncom.PumpWaitingMessages()
        time.sleep(.1)
예제 #6
0
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "sphinx_module_loader.py")

    # Initialize the engine.
    engine = get_engine("sphinx")

    # Try to import the local engine configuration object first. If there isn't one,
    # use the default engine configuration.
    log = logging.getLogger("config")
    try:
        import config
        engine.config = config
        log.info("Using local engine configuration module 'config.py'")
    except ImportError:
        pass
    except Exception as e:
        # Log errors caught when setting the configuration.
        log.exception("Failed to set config using 'config.py': %s" % e)
        log.warning("Falling back to the default engine configuration")

    # You can also set any configuration options here instead of using a
    # config.py file. For example:
    engine.config.START_ASLEEP = False
    engine.config.DECODER_CONFIG.set_float("-vad_threshold", 3.1)
    engine.config.LANGUAGE = LANGUAGE

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Load grammars.
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    class Observer(RecognitionObserver):
        def on_begin(self):
            print("=> Speech start detected.")

        def on_recognition(self, words):
            message = u"Recognized: %s" % u" ".join(words)
            print("=>", message)

        def on_failure(self):
            print("=> Sorry, what was that?")

    observer = Observer()
    observer.register()

    # Start the engine's main recognition loop
    try:
        engine.recognise_forever()
    except KeyboardInterrupt:
        pass
예제 #7
0
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "sphinx_module_loader.py")

    # Initialize the engine.
    engine = get_engine("sphinx")

    # Try to import the local engine configuration object first. If there isn't one,
    # use the default engine configuration.
    log = logging.getLogger("config")
    try:
        import config
        engine.config = config
        log.info("Using local engine configuration module 'config.py'")
    except ImportError:
        pass
    except Exception as e:
        # Log errors caught when setting the configuration.
        log.exception("Failed to set config using 'config.py': %s" % e)
        log.warning("Falling back to the default engine configuration")

    # You can also set any configuration options here instead of using a
    # config.py file. For example:
    # engine.config.START_ASLEEP = False

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Load grammars.
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Define recognition callback functions.
    def on_begin():
        print("Speech start detected.")

    def on_recognition(words):
        message = u"Recognized: %s" % u" ".join(words)

        # This only seems to be an issue with Python 2.7 on Windows.
        if six.PY2:
            encoding = sys.stdout.encoding or "ascii"
            message = message.encode(encoding, errors='replace')
        print(message)

    def on_failure():
        print("Sorry, what was that?")

    # Start the engine's main recognition loop
    try:
        engine.do_recognition(on_begin, on_recognition, on_failure)
    except KeyboardInterrupt:
        pass
예제 #8
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "module_loader.py")

    # Set any configuration options here as keyword arguments.
    # See Kaldi engine documentation for all available options and more info.
    engine = get_engine(
        'kaldi',
        model_dir='kaldi_model',  # default model directory
        # vad_aggressiveness=3,  # default aggressiveness of VAD
        # vad_padding_start_ms=150,  # default ms of required silence before VAD
        # vad_padding_end_ms=150,  # default ms of required silence after VAD
        # vad_complex_padding_end_ms=500,  # default ms of required silence after VAD for complex utterances
        # input_device_index=None,  # set to an int to choose a non-default microphone
        # lazy_compilation=True,  # set to True to parallelize & speed up loading
        # retain_dir=None,  # set to a writable directory path to retain recognition metadata and/or audio data
        # retain_audio=None,  # set to True to retain speech data wave files in the retain_dir (if set)
    )

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Load grammars.
    load_sleep_wake_grammar(True)
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Define recognition callback functions.
    def on_begin():
        print("Speech start detected.")

    def on_recognition(words):
        message = u"Recognized: %s" % u" ".join(words)

        # This only seems to be an issue with Python 2.7 on Windows.
        if six.PY2:
            encoding = sys.stdout.encoding or "ascii"
            message = message.encode(encoding, errors='replace')
        print(message)

    def on_failure():
        print("Sorry, what was that?")

    # Start the engine's main recognition loop
    engine.prepare_for_recognition()
    try:
        print("Listening...")
        engine.do_recognition(on_begin, on_recognition, on_failure)
    except KeyboardInterrupt:
        pass
예제 #9
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        #  when this module is run from PythonWin.  In this case we
        #  simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "dfly-loader-wsr.py")

    engine = get_engine("sapi5inproc")
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    WinEventProcType = ctypes.WINFUNCTYPE(
        None, ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD,
        ctypes.wintypes.HWND, ctypes.wintypes.LONG, ctypes.wintypes.LONG,
        ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)

    def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread,
                 dwmsEventTime):
        window = Window.get_foreground()
        if hwnd == window.handle:
            for grammar in engine.grammars:
                # Prevent 'notify_begin()' from being called.
                if grammar.name == "_recobs_grammar":
                    continue

                grammar.process_begin(window.executable, window.title,
                                      window.handle)

    def set_hook(win_event_proc, event_type):
        return ctypes.windll.user32.SetWinEventHook(
            event_type, event_type, 0, win_event_proc, 0, 0,
            win32con.WINEVENT_OUTOFCONTEXT)

    win_event_proc = WinEventProcType(callback)
    ctypes.windll.user32.SetWinEventHook.restype = ctypes.wintypes.HANDLE

    [
        set_hook(win_event_proc, et) for et in {
            win32con.EVENT_SYSTEM_FOREGROUND,
            win32con.EVENT_OBJECT_NAMECHANGE,
        }
    ]

    engine.speak('beginning loop!')
    while 1:
        pythoncom.PumpWaitingMessages()
        time.sleep(.1)
예제 #10
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "kaldi_module_loader_plus.py")

    if 'devices' in sys.argv:
        print('microphones:', get_engine('kaldi').print_mic_list())
        exit(0)
    # Set any configuration options here as keyword arguments.
    if 'test' in sys.argv:
        engine = get_engine('text')
    else:
        engine = get_engine(
            "kaldi",
            model_dir='kaldi_model',
            # tmp_dir='kaldi_model_zamia.tmp',  # default for temporary directory
            # vad_aggressiveness=3,  # default aggressiveness of VAD
            # vad_padding_start_ms=300,  # default ms of required silence before VAD
            vad_padding_end_ms=500,  # default ms of required silence after VAD
            # vad_complex_padding_end_ms=500,  # default ms of required silence after VAD for complex utterances
            audio_input_device='Blue',
            # auto_add_to_user_lexicon=True,  # set to True to possibly use cloud for pronunciations
            # lazy_compilation=True,  # set to True to parallelize & speed up loading
            # cloud_dictation=None,  # set to 'gcloud' to use cloud dictation
        )

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    load_sleep_wake_grammar(True)
    # load_noise_grammar()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Start the engine's main recognition loop
    if 'test' not in sys.argv:
        engine.prepare_for_recognition()
    try:
        # Loop forever
        print("Listening...")
        engine.do_recognition()
    except KeyboardInterrupt:
        pass
def main(args):
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "kaldi_module_loader_plus.py")

    os.environ.setdefault("GOOGLE_APPLICATION_CREDENTIALS", "gcloud.json")

    # Set any configuration options here as keyword arguments.
    engine = get_engine(
        "kaldi",
        model_dir='kaldi_model_zamia',
        # tmp_dir='kaldi_tmp',  # default for temporary directory
        # vad_aggressiveness=3,  # default aggressiveness of VAD
        # vad_padding_ms=300,
        #vad_padding_start_ms=300,  # default ms of required silence before VAD
        #vad_padding_end_ms=300,  # default ms of required silence after VAD
        #vad_complex_padding_end_ms=1000,  # default ms of required silence after VAD for complex utterances
        # input_device_index=None,  # set to an int to choose a non-default microphone
        auto_add_to_user_lexicon=
        True,  # set to True to possibly use cloud for pronunciations
        cloud_dictation_lang="en-US",  # set to 'gcloud' to use cloud dictation
    )

    if len(args) >= 1 and args[0] == "-l":
        # Show the list of attached microphone devices.
        # Note that this code should only be called after the engine has been initialized above with configuration options,
        # otherwise if this line of code happens before the engine is created, get_engine will create the engine with default arguments.
        get_engine("kaldi").print_mic_list()

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    load_sleep_wake_grammar(True)

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Start the engine's main recognition loop
    try:
        # Loop forever
        print("Listening...")
        engine.do_recognition()
    except KeyboardInterrupt:
        pass
예제 #12
0
def _load_cmd_module_dirs(args):
    # Load command modules from each specified directory.  Errors during
    #  loading will be caught and logged.
    recursive = args.recursive
    return_code = 0
    for d in args.module_dirs:
        module_directory = CommandModuleDirectory(d, recursive=recursive)
        module_directory.load()
        if not module_directory.loaded:
            return_code = 1

    # Return the overall success of module loading.
    return return_code
예제 #13
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "sphinx_module_loader.py")

    engine = get_engine("sphinx")
    assert isinstance(engine, SphinxEngine)

    # Try to import the local engine configuration object first. If there isn't one,
    # use the default engine configuration.
    log = logging.getLogger("config")
    try:
        import config
        engine.config = config
        log.info("Using local engine configuration module 'config.py'")
    except ImportError:
        pass
    except EngineError as e:
        # Log EngineErrors caught when setting the configuration.
        log.warning(e)
        log.warning("Falling back to using the default engine configuration "
                    "instead of 'config.py'")

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer(engine)
    observer.register()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # TODO Have a simple GUI for pausing, resuming, cancelling and stopping recognition, etc
    # TODO Change script to import all modules before loading the grammars into Pocket Sphinx

    # Start the engine's main recognition loop
    try:
        engine.recognise_forever()
    except KeyboardInterrupt:
        pass
예제 #14
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "sphinx_module_loader.py")

    engine = get_engine("sphinx")

    # Try to import the local engine configuration object first. If there isn't one,
    # use the default engine configuration.
    log = logging.getLogger("config")
    try:
        import config
        engine.config = config
        log.info("Using local engine configuration module 'config.py'")
    except ImportError:
        pass
    except Exception as e:
        # Log errors caught when setting the configuration.
        log.exception("Failed to set config using 'config.py': %s" % e)
        log.warning("Falling back to the default engine configuration")

    # You can also set any configuration options here instead of using a
    # config.py file. For example:
    # engine.config.START_ASLEEP = False

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Start the engine's main recognition loop
    try:
        engine.recognise_forever()
    except KeyboardInterrupt:
        pass
def main(args):
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "kaldi_module_loader_plus.py")

    # Set any configuration options here as keyword arguments.
    engine = get_engine(
        "kaldi",
        # model_dir='kaldi_model',
        # tmp_dir='kaldi_model.tmp',  # default for temporary directory
        # vad_aggressiveness=3,  # default aggressiveness of VAD
        # vad_padding_end_ms=300,  # default ms of required silence surrounding VAD
        # vad_complex_padding_end_ms=1200,
        # input_device_index=None,  # set to an int to choose a non-default microphone
        # auto_add_to_user_lexicon=True,  # set to True to possibly use cloud for pronunciations
        # cloud_dictation=None,  # set to 'gcloud' to use cloud dictation
    )

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    load_sleep_wake_grammar(True)

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Start the engine's main recognition loop
    engine.mimic("start listening")
    engine.prepare_for_recognition()
    try:
        # Loop forever
        print("Listening...")
        engine.do_recognition()
    except KeyboardInterrupt:
        pass
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "sphinx_module_loader.py")

    engine = get_engine("sphinx")

    # Try to import the local engine configuration object first. If there isn't one,
    # use the default engine configuration.
    log = logging.getLogger("config")
    try:
        import config
        engine.config = config
        log.info("Using local engine configuration module 'config.py'")
    except ImportError:
        pass
    except Exception as e:
        # Log errors caught when setting the configuration.
        log.exception("Failed to set config using 'config.py': %s" % e)
        log.warning("Falling back to the default engine configuration")

    # You can also set any configuration options here instead of using a
    # config.py file. For example:
    # engine.config.START_ASLEEP = False

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Register a recognition observer
    observer = Observer()
    observer.register()

    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Start the engine's main recognition loop
    try:
        engine.recognise_forever()
    except KeyboardInterrupt:
        pass
예제 #17
0
def main():
    logging.basicConfig(level=logging.INFO)

    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "wsr_module_loader_plus.py")

    # Initialize and connect the engine.
    # Set any configuration options here as keyword arguments.
    engine = get_engine("sapi5inproc")
    engine.connect()

    # Load grammars.
    load_sleep_wake_grammar(True)
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Define recognition callback functions.
    def on_begin():
        print("Speech start detected.")

    def on_recognition(words):
        message = u"Recognized: %s" % u" ".join(words)

        # This only seems to be an issue with Python 2.7 on Windows.
        if six.PY2:
            encoding = sys.stdout.encoding or "ascii"
            message = message.encode(encoding, errors='replace')
        print(message)

    def on_failure():
        print("Sorry, what was that?")

    # Start the engine's main recognition loop
    try:
        print("Listening...")
        engine.do_recognition(on_begin, on_recognition, on_failure)
    except KeyboardInterrupt:
        pass
예제 #18
0
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        #  when this module is run from PythonWin.  In this case we
        #  simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "dfly-loader-natlink.py")

    # Initialize and connect the engine.
    engine = get_engine("natlink")
    engine.connect()

    # Load grammars.
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Define recognition callback functions.
    def on_begin():
        print("Speech start detected.")

    def on_recognition(words):
        message = u"Recognized: %s" % u" ".join(words)

        # This only seems to be an issue with Python 2.7 on Windows.
        if six.PY2:
            encoding = sys.stdout.encoding or "ascii"
            message = message.encode(encoding, errors='replace')
        print(message)

    def on_failure():
        print("Sorry, what was that?")

    # Recognize from Dragon in a loop (opens a dialogue window).
    try:
        engine.do_recognition(on_begin, on_recognition, on_failure)
    except KeyboardInterrupt:
        pass

    # Disconnect after the dialogue is closed.
    engine.disconnect()
예제 #19
0
def main():
    try:
        path = os.path.dirname(__file__)
    except NameError:
        # The "__file__" name is not always available, for example
        # when this module is run from PythonWin.  In this case we
        # simply use the current working directory.
        path = os.getcwd()
        __file__ = os.path.join(path, "kaldi_module_loader_plus.py")

    # Set any configuration options here as keyword arguments.
    # See Kaldi engine documentation for all available options and more info.
    engine = get_engine(
        "kaldi",
        model_dir=
        "models/daanzu_20200328_1ep-mediumlm",  # default model directory
        vad_aggressiveness=0,  # default aggressiveness of VAD
        vad_padding_start_ms=10,  # default ms of required silence before VAD
        vad_padding_end_ms=10,  # default ms of required silence after VAD
        vad_complex_padding_end_ms=
        10,  # default ms of required silence after VAD for complex utterances
        # input_device_index=None,  # set to an int to choose a non-default microphone
        lazy_compilation=True,  # set to True to parallelize & speed up loading
        # retain_dir=None,  # set to a writable directory path to retain recognition metadata and/or audio data
        # retain_audio=None,  # set to True to retain speech data wave files in the retain_dir (if set)
    )

    ui = App(do_quit=engine.disconnect)

    def notify_status(status: AppStatus):
        if status == AppStatus.LOADING:
            print("Loading...")
            ui.set_status_line("Initializing...")
        elif status == AppStatus.SLEEPING:
            print("Sleeping...")
            ui.set_status_line("Asleep...")
        elif status == AppStatus.READY:
            print("Awake...")
            ui.set_status_line("Listening...")
        else:
            print(f"Unknown status! {status}")

    notify_status(AppStatus.LOADING)

    # Call connect() now that the engine configuration is set.
    engine.connect()

    # Load grammars.
    load_sleep_wake_grammar(initial_awake=True, notify_status=notify_status)
    load_ui_grammar(do_quit=lambda: engine.disconnect(),
                    do_restart=restart_process)
    directory = CommandModuleDirectory(path, excludes=[__file__])
    directory.load()

    # Define recognition callback functions.
    def on_begin():
        ui.set_visual_context("last speech start", datetime.datetime.now())

    last_utterances = []

    def on_recognition(words):
        s = " ".join(words)
        if len(s):
            ui.set_last_heard(f"Last heard: {s}")
            last_utterances.append(s)
            while len(last_utterances) > MAX_DISPLAYED_HISTORY:
                del last_utterances[0]
            ui.set_visual_context("History", "\n" + "\n".join(last_utterances))
        print("Recognized: %s" % " ".join(words))

    def on_failure():
        ui.set_visual_context("last speech failure", datetime.datetime.now())

    # Start the engine's main recognition loop
    engine.prepare_for_recognition()
    watchdog_observer = start_watchdog_observer(do_restart=restart_process)
    try:
        notify_status(AppStatus.READY)
        engine.do_recognition(
            begin_callback=on_begin,
            recognition_callback=on_recognition,
            failure_callback=on_failure,
            end_callback=None,
            post_recognition_callback=None,
        )
    except KeyboardInterrupt:
        print(f"Received keyboard interrupt so quitting...")

    # cleanup
    if watchdog_observer:
        watchdog_observer.stop()
        watchdog_observer.join()