Author Topic: Can a list of numbers (0-9) in 1 voice command be split?  (Read 3036 times)

HuDz

  • Newbie
  • *
  • Posts: 7
Can a list of numbers (0-9) in 1 voice command be split?
« on: April 22, 2021, 12:25:05 PM »
Hi,

I currently have 10 voice commands i use for numbers (zero to nine), each number has a different keybind and this works fine with a pause in between.

If i speak the numbers fast, the log in VA picks up the sequence correct, so my question is, is it possible for VA to split this up and do a specific key bind for each number in the spoken order? This would be extremely useful. Cheers.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #1 on: April 22, 2021, 12:58:51 PM »
Splitting text (which is what the numbers you speak would be, as all output from the speech recognition engine is) can be done, though to recognize a command consisting of an arbitrary combination of numbers, you'll want to use wildcards (which are a somewhat unsupported feature, but as you mention the longer strings of numbers are recognized correctly, would likely work well enough in this case), and a static keyword that VoiceAttack can match against.

E.G. "enter *", or "numbers *", so that you could speak "enter 0824627". Do note that the speech recognition engine will interpret certain sequences of numbers as a specific format (E.G. a phone number), and may add markup.


If the keys you are looking to press are the regular (I.E. non-numpad) numeric keys, that could be done using the "Quick Input" action (in combination with the "{CMD_AFTER}" token).

Otherwise, something like this could work:
Code: [Select]
Set text [~input] to '{CMD_AFTER}'
Start Loop : Repeat From 0 to [{EXP: {TXTLEN:~input} - 1}], using indexer [~i]
    Write [Blue] '{TXTSUBSTR:~input:~i:1}' to log
End Loop
which will output each character as a log entry. This can be adapted to use a number of conditions instead, to check which number was spoken and press the relevant key using a keypress action.

If each number corresponds to a numpad key, on the other hand, that's only a slight modification:
Code: [Select]
Set text [~input] to '{CMD_AFTER}'
Start Loop : Repeat From 0 to [{EXP: {TXTLEN:~input} - 1}], using indexer [~i]
    Quick Input, '[NUM{TXTSUBSTR:~input:~i:1}]'
End Loop


Information of the actions and features used can be found in the documentation; Press F1 while VoiceAttack has focus to open VoiceAttackHelp.pdf in your default PDF viewer.

These topics may also be of use:
Control flow (If, Else, ElseIf, Loop, Jump) basics
Variables and tokens summed up


If you experience markup getting added, you can use the "{TXTNUM:}" token to strip non-numeric characters, though do note that "-", for example, is interpreted as part of a number if it's next to one.

HuDz

  • Newbie
  • *
  • Posts: 7
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #2 on: April 22, 2021, 05:42:30 PM »
Thanks for the reply, could you per chance send me this project file to have a play with, im struggling to wrap my head around all this.

Cheers.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #3 on: April 22, 2021, 05:51:25 PM »
Is there something specific that isn't working? What have you tried so far?

HuDz

  • Newbie
  • *
  • Posts: 7
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #4 on: April 22, 2021, 06:08:41 PM »
At the moment i am struggling to create the command you have made :-(

Trying to wrap my head around this, never used voice attack to do something this complex before.

Cheers,

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #5 on: April 22, 2021, 06:28:55 PM »
You'll want to use the "Loop Start - Repeat a Certain Number of Times" action, rather than the regular "Loop Start" action.


The For loop will repeat once for each character in the value of the "~input" text variable, by counting from 0 to the length of the value minus one, as the first character of that text value is at index 0 (the second character is at index 1, the third at index 2, etc...)

The loop will also set an indexer variable (which is why you need to use the "Range (For Loop)" option, as the "Number of times" option doesn't have that ability), which is used as an input for the "{TXTSUBSTR:}" token.

The "{TXTSUBSTR:}" token, as the documentation notes, takes three parameters: The first is the text value you want to get characters from, the second is the index at which the token will start getting the characters, and the third is the amount of characters that should be retrieved.

In these examples, the token is set up to get characters from the "~input" variable, starting at the index represented by the value of "~i" (the integer variable set by the For loop), and one character should be retrieved, as set using the literal value of "1"

As the For loop increments the indexer each time it repeats, the "{TXTSUBSTR:}" token will return each of the characters in the value of "~input", one-by-one.

HuDz

  • Newbie
  • *
  • Posts: 7
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #6 on: April 22, 2021, 06:43:16 PM »
Aah i understand now thanks. I believe i have this working see image.

So this is just going to output the text of the number to the log? how do I now tie the indexed number in the loop to a keypress? or do I tie the indexed number to another command? Ideally i would like to use LSHIFT as a modifier and the keys 1-9 (not numpad) for spoken numbers.

Cheers,

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #7 on: April 22, 2021, 06:49:19 PM »
As mentioned, if you're using the regular numeric keys, you can use the "Quick Input" action, I.E. you'd put the "{TXTSUBSTR:}" token into that action's "Text" field.

To hold down the shift key, you could use the relevant key indicators (as documented in the "Quick Input, Variable Keypress and Hotkey Key Indicators" section of VoiceAttackHelp.pdf), but that would press and release the key for each character.

A more efficient approach would be to have a keypress action before the loop that presses the shift key, and another after the loop that releases it, so that the key is held down while the characters are typed out.

HuDz

  • Newbie
  • *
  • Posts: 7
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #8 on: April 22, 2021, 07:38:06 PM »
Thank pal i appear to have this working now (sorry for being stupid).

Most of the numbers I will be speaking are 4, 6 and 10 digit, which don't appear to suffer issues with "-" etc.

However, occasionally when I speak "two", instead of "2" being output it comes up with " to ". What's the best way to get around this happening? Record my voice for the number and add it to MS dictionary?

Cheers,

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #9 on: April 22, 2021, 07:47:09 PM »
Single digit numbers are usually written out as words by the speech recognition engine, rather than digits (E.G. "three" instead of "3"), so you may find that even with accurate recognition, that poses a problem.

You can certainly try recording a custom pronunciation for the dictionary, but you may also (in addition) want to use the "{TXTWORDTONUM:}" token (which is actually intended specifically to work around the single digit issue; you can pass it the value of the "{CMD_AFTER}" token directly by wrapping the latter in double quotes, as mentioned in the documentation for tokens regarding the passing of literal values, which is what tokens are replaced with), and perhaps the "Replace with" option of the "Set a Text Value" action to explicitly replace "to" with "2", just in case.

HuDz

  • Newbie
  • *
  • Posts: 7
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #10 on: April 22, 2021, 08:13:23 PM »
Its also appearing as a word for me in the middle of a string of numbers (see image). I'll give {TXTWORDTONUM:} a try tomorrow.

Thanks for the help.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #11 on: April 22, 2021, 08:21:29 PM »
That'd be because the Microsoft Speech Recognition engine recognized "to", which then makes "one" a separate number.
If it had recognized "two" instead, that should have resulted in the proper digits, as they'd have been part of the longer number.

This can be worked around using a combination of the "{TXTWORDTONUM:}" token to replace "one" with "1", the "Replace with" feature to replace "to" with "2", and the "{TXTNUM:}" token (which would need to be applied in a separate "Set a Text Value" action, after the replace) to remove any whitespace (as that would also be typed out otherwise)

HuDz

  • Newbie
  • *
  • Posts: 7
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #12 on: April 23, 2021, 03:29:30 AM »
OK, so I think I have this working 100% how I want it now. it seems to work with any length number and strips out chars like (, ) & -. The codes probably not the most efficient but here's what I ended up with (see image).

Thanks for the help Pfeil this is going to make my life in DCS VR much easier :-)

Cheers,

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4758
  • RTFM
Re: Can a list of numbers (0-9) in 1 voice command be split?
« Reply #13 on: April 23, 2021, 10:41:08 AM »
That should certainly work, though there are a few modifications that can be made:

The "Set a Text Value" actions can both set the same variable, as the "{TXTNUM:}" token will get the previous value before the second action replaces it, unless you specifically prefer using separate variables for readability

There is no need for a jump; When a condition is evaluated, the first branch that evaluates to true is the one that is executed, and all subsequent branches are then ignored (as long as they are part of the same condition structure, I.E. using Else or Else If), regardless of whether the executing branch contains any actions

You can combine all of the character checks into a single branch using the condition builder: Right-click the begin block, and choose "Edit With Condition Builder", then add the different evaluations to a single And tab, and use the "Does Not Equal" operator (you could add them as Or tabs using the "Equals" operator instead, however as the condition doesn't need to execute any actions if all the statements evaluate to true, And is more suitable)


E.G.
Code: [Select]
Set text [~input] to '{CMD_AFTER}' (Replace 'to' with '2')
Set text [~input] to '{TXTNUM:~input}'
Press down Left Shift key
Start Loop : Repeat From 0 to [{EXP: {TXTLEN:~input} - 1}], using indexer [~i]
    Set text [~currentCharacter] to '{TXTSUBSTR:~input:~i:1}'
    Begin Condition : ([~currentCharacter] Does Not Equal '(' AND [~currentCharacter] Does Not Equal ')' AND [~currentCharacter] Does Not Equal '-')
        Write [Blue] '{TXT:~currentCharacter}' to log
        Quick Input, '{TXT:~currentCharacter}'
    End Condition
End Loop
Release Left Shift key

I opted to create a variable within the loop, which can aid readability and editability, and is computationally more efficient (as the "{TXTSUBSTR:}" token only needs to retrieve the characters once, rather than every time you use the value; not that you're likely to notice the difference in real-world terms)