Danesprite on master
Remove unnecessary install requ… (compare)
Danesprite on major
Remove multiple engine options … Remove the dragonfly.util sub-p… Make dragonfly.accessibility su… (compare)
Danesprite on master
Clarify sections of the documen… (compare)
Danesprite on major
Remove dragonfly.rpc sub-packag… (compare)
Danesprite on master
Update sections of the document… (compare)
Danesprite on master
Remove unused test suite module (compare)
Danesprite on minor
Fix Kaldi marking of whether re… Add Kaldi optional local or onl… Update Kaldi version, to fix er… and 32 more (compare)
Danesprite on major
Remove training mode from the S… Remove built-in sleep/wake mode… (compare)
Danesprite on talon-dev
Danesprite on master
Add missing documentation file … (compare)
Danesprite on 0.35.0
Okay then, make sense. Given that some users set logging levels using the current names, maybe this should be held off until version 1.0.0. I intend to make a few other changes like this in that release, e.g. resolving issue #238 (Modularize dependencies).
Your changes removing the decorator
dependency look good to me.
Incidentally, the requirements for dragonfly.rpc
will be made optional extras in version 1.0.0. I will probably remove the relevant import statements from dragonfly/__init__.py
.
When working with extras it would be nice in some circumstances to remember the last extra recognized for that particular spec. Let's consider the following command select word [<left_or_right>] [<n>]
The user says select word left
and then again says select word
left extra would be remembered.
Now we could set a directional default in extras. However in more complex scenarios it's not that simple. Now wrapping this up in the function would work but it really does pollute grammar sets making them harder to read. Any thoughts on implementation or should I stick to using a function?
If you do go with a function, then you can get at the underlying rule by including a _rule
argument:
def function(_rule):
print(_rule)
print(_rule._defaults["left_or_right"])
An alternative is a separate command for explicitly changing your default value for left_or_right
. This would change it for all mappings using the extra.
I think Quintijn is right here though, repeating the last action is probably easier.
again do
command is similar to what Quintijn described. This looks much more complex than it is due to utilizing Caster asynchronous actions. It could be converted utilizing to pure dragonfly. This allows to repeat not only the last command but the last utterance. Useful for CCR chains or commands with dragonfly repetition elements.# migrated this function from elsewhere for completeness of the post.
def get_and_register_history(utterances=10):
history = RecognitionHistory(utterances)
history.register()
return history
_history = get_and_register_history(10)
class Again(MappingRule):
mapping = {
"again (<n> [(times|time)] | do)":
R(Function(lambda n: Again._create_asynchronous(n)), show=False),
}
extras = [ShortIntegerRef("n", 1, 50)]
defaults = {"n": 1}
@staticmethod
def _repeat(utterance):
Playback([(utterance, 0.0)]).execute()
return False
@staticmethod
def _create_asynchronous(n):
last_utterance_index = 2
if len(_history) == 0:
return
# ContextStack adds the word to history before executing it for WSR
if get_current_engine().name in ["sapi5shared", "sapi5", "sapi5inproc"]:
if len(_history) == 1: return
# Calculatees last utterance from recognition history and creates list of str for Dragonfly Playback
utterance = list(map(str, _history[len(_history) - last_utterance_index]))
if utterance[0] == "again": return
# Create AsynchronousAction
forward = [L(S(["cancel"], lambda: Again._repeat(utterance)))]
AsynchronousAction(
forward,
rdescript="Repeat Last Action",
time_in_seconds=0.2,
repetitions=int(n),
blocking=False).execute()
MYARG=foo42 python -m dragonfly ...
set
on its own command line first would work too I think, but that sets it for multiple commands
Element
in multiple Rule
s. Perhaps this should be mentioned in https://dragonfly2.readthedocs.io/en/latest/elements.html#refelementclasses ?
@westocl
Environment variables are a good way to go here. There is no way to specify arguments to the Python files in question, since they are in fact being imported as modules, not run as programs.
Regarding recognition callbacks, yes, the sequence of callbacks should be exactly the same when using the text backend. That is the whole point of that engine backend. :-)
@daanzu
Yep, mimic()
is supposed to do that.
I think reusing an element is fine in most cases. I would say just copy the element with copy.copy()
if it causes a problem. Mentioning this in the documentation sounds like a good idea to me.
If the engine.speak()
method for text-to-speech is used by anyone in this channel, I was wondering if there is any interest in changing Dragonfly to make use of the text-to-speech built into Windows for all engine back-ends, if it is available, instead of only with the WSR/SAPI 5 back-end. The Natlink back-end would still use Dragon's TTS.
I suppose this would be mostly interesting to Kaldi users.
@comodoro Okay then, I will have a look into this.
I hadn't considered the advantage for other languages. Windows has TTS support for quite a few languages or "voices" through SAPI 5. It should be possible to separate the TTS functionality from each engine class so that you could, for example, use the SAPI 5 TTS instead of Dragon's.
I don't think any of this would work on mobile unless pywin32 does. I would guess only x86/x86_64 devices would work.
$ echo "speak some words" | espeak --stdin
$ echo "speak some words" | festival --tts
@comodoro Ah, okay that is a shame. Thanks for elaborating on MS Mobile voices. I would never have guessed what it was from the name. Leave it to Microsoft to make things more complicated than they ought to be.
Both the TTS and STT parts of SAPI haven't really been actively worked on for a long time. It isn't too difficult to work with the API in Python, I suppose. Dragonfly's SAPI 5 engine back-end works using COM. I can see it is pretty simple to set the current TTS voice. The API error messages given could be more helpful though.
If there is a public API for utilising MS Mobile voices, it would probably require .NET. Since we are using CPython, that would be difficult. I'll just stick with SAPI for now. I suppose you could try Google TTS instead for Czech.