[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacspeak] Omnivox: supporting user-supplied engine helpers (e.g. voices that cannot be redistributed)



Hi all, and Bart in particular,

I use Emacsvox with Omnivox on Windows. I would like to use a Slovak/Czech
speech engine that I can legally run on my own machine but that nobody may
redistribute: it is proprietary. Today I use it through NVDA and
speech-dispatcher. I would like to use it in Emacs too.

Omnivox already has the right architecture for this. ADR 0001 says that
user-supplied runtimes belong in a helper process, and the helper protocol
(JSON lines on stdin/stdout, versions 1-6) is engine-neutral. I have
started writing a helper for this engine outside the Omnivox tree.

What is missing is a way to register such a helper. The helper IDs are
hard-coded in omnivox-cli/src/engine.rs:
- rhvoice, flite, rutts, tgspeechbox, piper, mbrola, eloquence, dectalk;
- each is found through OMNIVOX_<ID>_HELPER or by a fixed file name next to
  omnivox.exe;
- the ID returned by the helper's describe must match the expected ID.

So the only way to plug in a new helper without patching Omnivox is to let it
pretend to be another engine. For example, pointing OMNIVOX_RUTTS_HELPER at
my helper makes it answer as "rutts". That works for a prototype, but the
voices appear under the wrong engine, and it would break as soon as someone
installs the real RuTTS companion.

Proposal: user-registered helpers

Let the user register additional helpers explicitly, for example with one
small manifest file per helper in a user configuration directory:

  %APPDATA%\omnivox\helpers.d\wintalker.json
  $XDG_CONFIG_HOME/omnivox/helpers.d/wintalker.json

  {
    "schema": 1,
    "engine_id": "wintalker",
    "program": "C:\\Users\\me\\speech\\omnivox-wintalker-helper.exe",
    "synthesis_idle_timeout_ms": 60000
  }

A simpler alternative would be one environment variable, for example
OMNIVOX_EXTRA_HELPERS="wintalker=C:\path\helper.exe;other=/abs/path". That is
the MBROLA approach (an explicit absolute path, opt-in only) made general.
I prefer manifests: they need no launcher changes, they are easy for
Emacsvox to write from a customize UI, and they have room for per-helper
settings. But either would solve my problem.

Rules I would suggest, in line with ADR 0001:

- Registration is only ever explicit and local. Omnivox never discovers
  such helpers from the working directory, PATH, the network or protocol
  input, and never downloads or distributes them.
- The program path must be absolute.
- The engine ID must not collide with a built-in ID, or it must use a
  reserved prefix such as "local." or "x-".
- The helper's descriptor.id must match the registered ID.
- Registered helpers go through exactly the same lifecycle as built-in
  ones: hello/describe validation, bounded timeouts, the 250 ms cancellation
  watchdog, circuit breaker and recovery probe, and fallback when the
  helper is missing or fails.
- They are appended after the built-in engines in the preference order. They
  are used only when selected explicitly (--engine, a voice selection or
  routing policy) and are never preferred implicitly.
- They take no part in the managed voice library, the acquisition or
  validation paths, or release manifests.
- Timeouts from the manifest are clamped to the existing bounds.

Emacsvox side: as far as I can see, its voice lists come from the Omnivox
inventory, so a registered engine should appear there without changes. The
only hard-coded list I found is the component installer's list of managed
IDs, which such helpers would not need. I have not tested this.

Is this something you would accept, or is there a better mechanism you have
in mind? I am happy to prepare a patch and tests if the direction is OK.
In the meantime I will keep testing the helper under the "rutts" ID.

Thanks,
Lubos Pintes



|Full archive May 1995 - present by Year|Search the archive|


If you have questions about this archive or had problems using it, please contact us.

Contact Info Page