VoxCommando
VoxNastics (User Guides and Mods) => XML Exchange => Topic started by: Haddood on July 31, 2014, 08:17:15 AM
-
VC does a wonderful job by allowing user to control the required confidence to accept the voice command. however, in open mic implementation the obstacles toward practical usable SR are many ... one of them is the confidence level might change based on the distance, noise, wind (if windows are open) ...etc.
the following command will trigger whenever there is a recognized command with a low confidence (if prefix is used, it must pass its required confidence setting). if the exact command is repeated twice, VC will assume this is no coincidence and will perform the command ... eliminating the possible frustration of saying the command multiple times with no response ...
Example: VC what time is it? (low confidence nothing happens)
VC what time is it? (low confidence, but no coincidence that it is equal to previous command, so vc will VC.TellVox VC what time is it with 100% confidence ;D ;D
Now the adaptive part is optional, where I average the first and second command detected confidence, then average that with confidence required in options ... and change the option using VC.SetOption for temporary immediate override and a command I wrote which modifies the options.xml for permanent adjustment even after restart and for the next round of calculations ...
in theory with time the required confidence level should settle around the level where most commands pass ... why in theory, it is for the following limitations:
VC do not offer an event when a command is recognized with its confidence as payload like in low confidence case; that means the confidence level will only go down and never up (one work around is to disable the permanent change so when VC restarts it goes back to your preferred confidence level, some minor adjustments to the command is required as well)
James did solve the the issue with a python script see: http://voxcommando.com/forum/index.php?topic=1689.msg14689#msg14689
I noticed when I set the required confidence level very high (like 98) for testing purposes even VC.TellVox will trigger recognized with low confidence (not sure if it is a bug or the macro is too demanding for VC) See nime5ter post belowif the previous happens, sometimes VC will go into infinit loop keep on triggering the command over and over with the new confidence 100, that will pull the average quickly very close to 100 ... I had to kill VC using task manager (again not sure if it is a bug or the macro is too demanding for VC) See nime5ter post below
- this job is not best suited for macro ... to make it bullet proof it must be done on program level so it happens on the fly, without possible interruptions from other macros ...maybe converting it to python will do the trick
if you are interested in testing this command please let me know your feedback and any adjustments that improve its performance ... (copy code from nime5ter post below, debugged)
Command to adjust the confidence when command passes required confidence level.. (for this to work the python script mentioned above must be loaded)
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.0.0.3-->
<command id="519" name="Adaptive Confidence Posetive" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{6}&&False</ifParams>
<then>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>Command will be ignored... aborting</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.StopMacro</cmdType>
<params />
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevCommand</param>
<param>123</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>CurrentCommand</param>
<param>486</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{4}&&1.0</ifParams>
<then>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>Confidence 100%. probably triggered by VC.TellVox ... ignoring</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.StopMacro</cmdType>
<params />
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{5}&&True</ifParams>
<then>
<action>
<cmdType>File.Read</cmdType>
<params>
<param>options.xml</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>Option\sname="RequiredConfidence"\svalue="(.*)"</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>PY.ExecString</cmdType>
<params>
<param>result=round(({4}*100+3*{Match.1})/4)</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.SetOption</cmdType>
<params>
<param>RequiredConfidence</param>
<param>0.{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.AddText</cmdType>
<params>
<param>Confidence: in options {Match.1}, Current {4}, avg {LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.TriggerEvent</cmdType>
<params>
<param>Option.Set</param>
<param>RequiredConfidence</param>
<param>{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<event>VC.Reco</event>
</command>
Command to adjust Confidence if 2 commands with low confidence
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.0.0.3-->
<command id="479" name="Adabtive Confidence" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevConfidence</param>
<param>{Var.CurrentConfidence}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>CurrentConfidence</param>
<param>{2}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevCommand</param>
<param>{Var.CurrentCommand}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>File.Read</cmdType>
<params>
<param>options.xml</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>Option\sname="PrefixString"\svalue="(.*)"</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>([^{Match.1}\s].*)</param>
<param>-</param>
<param>{1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>CurrentCommand</param>
<param>{Match.1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{Var.CurrentCommand}&&{Var.PrevCommand}</ifParams>
<then>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>Option\sname="RequiredConfidence"\svalue="(.*)"</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>PY.ExecString</cmdType>
<params>
<param>result=round(({2}+{Var.PrevConfidence})/2)</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>AvgConfidence</param>
<param>{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>Same command twice with Low Confidence</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.AddText</cmdType>
<params>
<param>Confidence: {Var.PrevConfidence} , {2}, avg {Var.AvgConfidence}, Current Confidence {Match.1} </param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevConfidence</param>
<param>X</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevCommand</param>
<param>ABC</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>PY.ExecString</cmdType>
<params>
<param>result=round(({Match.1}+{Var.AvgConfidence})/2)</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>AvgConfidence</param>
<param>{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.SetOption</cmdType>
<params>
<param>RequiredConfidence</param>
<param>{Var.AvgConfidence}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.TriggerEvent</cmdType>
<params>
<param>Option.Change </param>
<param>RequiredConfidence</param>
<param>{Var.AvgConfidence}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.Pause</cmdType>
<params>
<param>1000</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.TellVox</cmdType>
<params>
<param>{1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>commands did not match ...ignoring</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.AddText</cmdType>
<params>
<param>{Var.CurrentCommand} vs {Var.PrevCommand}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
</else>
</if>
<event>VC.Reco.TooLow</event>
</command>
command to permanently change options (use at your own risk)
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.0.0.3-->
<command id="508" name="Change Option" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="command that changes the options file
payload 1: is name
payload 2: is value
payload 3: if Set to true VC will restart 
">
<action>
<cmdType>File.Read</cmdType>
<params>
<param>options.xml</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>File.Copy</cmdType>
<params>
<param>options.xml</param>
<param>options.xml.bak</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegExReplace</cmdType>
<params>
<param><Option name="{1}" value=".*" /></param>
<param><Option name="{1}" value="{2}" /></param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>File.Write</cmdType>
<params>
<param>options.xml</param>
<param>{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{1}&&PrefixString</ifParams>
<then>
<action>
<cmdType>File.GetFiles</cmdType>
<params>
<param>C:\Extensions\Vox Commando\srgs</param>
<param>*.cfg</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>File.Delete</cmdType>
<params>
<param>{Match.{i}}</param>
</params>
<cmdRepeat>{#M}</cmdRepeat>
</action>
</then>
<else />
</if>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{3}&&True</ifParams>
<then>
<action>
<cmdType>VC.RestartFull</cmdType>
<params />
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<event>Option.Change </event>
</command>
-
Hi Haddood, nice work. I've tested the first command and it show me in the history window a error in the python maths. I deletet the outer brackets and now it works.
old py action: result=round(({Match.1}+{Var.AvgConfidence})/2)
new py action: result=round({Match.1}+{Var.AvgConfidence})/2
Kalle
-
This is a clever idea. Thanks for sharing.
We count on Haddood to stress test VC! The problems you've been running into with your command have to do with a bug when overriding required confidence using the VC.SetOption action. It turns out that while the description claims it takes an integer between 1-100, it's actually expecting a decimal value between 0 and 1.
This is the culprit behind all of the issues you had -- including causing the subsequent VC.TellVox action to trigger this command over and over, leading to your endless loop. (I don't have the time to explain in detail, sorry.)
Anyhow: James will fix the bug in the next 48 hours or so, and thank you for discovering it. In the meantime, there is a workaround until that gets implemented, which I include in my xml below.
One other thing: the regular expression that captures the command name even if we say a prefix first only works some of the time. If I have a prefix such as "Jarvis", followed by a command that starts with an "s", then the regex cuts off the "s" of my command name, and therefore it will not recognize the repeated command. I've fixed this in my code below.
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.0.0.5-->
<command id="485" name="Adaptive Confidence" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevConfidence</param>
<param>{Var.CurrentConfidence}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>CurrentConfidence</param>
<param>{2}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>PrevCommand</param>
<param>{Var.CurrentCommand}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>File.Read</cmdType>
<params>
<param>options.xml</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>Option\sname="PrefixString"\svalue="(.*)"</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>(?:^{Match.1}\s|^)(.*)</param>
<param>-</param>
<param>{1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>CurrentCommand</param>
<param>{Match.1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{Var.CurrentCommand}&&{Var.PrevCommand}</ifParams>
<then>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param>Option\sname="RequiredConfidence"\svalue="(.*)"</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>PY.ExecString</cmdType>
<params>
<param>result=round(({2}+{Var.PrevConfidence})/2)</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>AvgConfidence</param>
<param>{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>Same command twice with Low Confidence</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.AddText</cmdType>
<params>
<param>Confidence: {Var.PrevConfidence} , {2}, avg {Var.AvgConfidence}, Current Confidence {Match.1} </param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>PY.ExecString</cmdType>
<params>
<param>result=round(({Match.1}+{Var.AvgConfidence})/2)</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>AvgConfidence</param>
<param>{LastResult}</param>
</params>
<cmdRepeat>0</cmdRepeat>
</action>
<action>
<cmdType>VC.SetOption</cmdType>
<params>
<param>RequiredConfidence</param>
<param>0.{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.Pause</cmdType>
<params>
<param>1000</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.TellVox</cmdType>
<params>
<param>{1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.StopMacro</cmdType>
<params />
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>commands did not match ...ignoring</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.AddText</cmdType>
<params>
<param>{Var.CurrentCommand} vs {Var.PrevCommand}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
</else>
</if>
<event>VC.Reco.TooLow</event>
</command>
-
Hi Haddood, nice work. I've tested the first command and it show me in the history window a error in the python maths. I deletet the outer brackets and now it works.
old py action: result=round(({Match.1}+{Var.AvgConfidence})/2)
new py action: result=round({Match.1}+{Var.AvgConfidence})/2
Kalle
Kalle not sure about python but the 2 methods should give 2 different results ...
Round ( (2 + 5) / 2) = 4
Round (2 + 5) / 2= 3.5
-
This is a clever idea. Thanks for sharing.
We count on Haddood to stress test VC!
well, thank you for both :biglaugh
The problems you've been running into with your command have to do with a bug when overriding required confidence using the VC.SetOption action. It turns out that while the description claims it takes an integer between 1-100, it's actually expecting a decimal value between 0 and 1.
This is the culprit behind all of the issues you had -- including causing the subsequent VC.TellVox action to trigger this command over and over, leading to your endless loop. (I don't have the time to explain in detail, sorry.)
it make sense if its a percentage variable, hence you added 0. before the value ..
Anyhow: James will fix the bug in the next 48 hours or so
Maybe James will want to add an event in the case of successful recognition with a payload of the phrase and the confidence (it is already as announcement in the history window) 8) 8) 8)
One other thing: the regular expression that captures the command name even if we say a prefix first only works some of the time. If I have a prefix such as "Jarvis", followed by a command that starts with an "s", then the regex cuts off the "s" of my command name, and therefore it will not recognize the repeated command. I've fixed this in my code below.
another thank you ... you always save the day when it comes to RegEX ... I am still a toddler with this command
-
Kalle not sure about python but the 2 methods should give 2 different results ...
Round ( (2 + 5) / 2) = 4
Round (2 + 5) / 2= 3.5
You are correct, it has nothing to do with the brackets.
I've add a picture below with the error.
-
Kalle -- I think on your German system, the decimal values are showing up as the character , instead of .
Python is expecting . not , which is what is causing your error. It doesn't recognize that kind of punctuation as a decimal point.
You can test this in the Python plugin editor.
-
Thanks, you are right - this is the problem. :bonk
Maybe I can solve this with a result.replace action
-
Kalle, I wonder if you set the interface language in VC options to English, does it still use comma for decimals?
-
I tried switching mine to German, and it continued to format my decimal points "properly", so I wonder if it's a different localization element.
It's ugly, but you can use the following syntax in the PY.ExecString action, if you don't want to do multiple Result.Replace actions etc.
result=round(float(('{2}').replace(',','.'))+float(('{Var.PrevCommand}').replace(',','.'))/2)
... I think that's the correct number of ( ), but it's hard to keep track!
-
Thanks Naomi, I will test it. :hugs
-
James did provide a solution for recognized commands ... I updated the post to include the adjustment on positive recognition ....
Kalle if you are testing, maybe you want to add this too