I made some modifications; Ended up with this:
VOICE_ACTIVATED_TOGGLE [true;false]
Begin Text Compare : [{CMDACTION}] Equals 'Plugin'
Do nothing (ignore command)
Begin Text Compare : [{CMD}] Ends With 'on'
Press down Left Alt key
Else
Release Left Alt key
End Condition
Else
Set integer [~PTTHoldTime] value to 300
Inline C# Function: Voice Toggle
End Condition
Where "Voice Toggle" contains:
using System;
using System.Threading;
using System.Diagnostics;
public class VAInline
{
bool buttonPressed = false;
public void main()
{
//Check if the required command exists, otherwise exit
if(!VA.CommandExists("VOICE_ACTIVATED_TOGGLE true") || !VA.CommandExists("VOICE_ACTIVATED_TOGGLE false"))
{
VA.WriteToLog("Voice Toggle Error: Command 'VOICE_ACTIVATED_TOGGLE [true;false]' does not exist, startup aborted","red");
return;
}
try // avoid any weird exceptions causing problems.
{
float timeToKeepRecording = VA.GetInt("~PTTHoldTime") ?? 300; // time in seconds after our last recognised speech, that we keep the 'push to talk' key pressed. Default is 300ms if not set in the VoiceAttack command.
Stopwatch sw = new Stopwatch();
bool speechDetected = false;
VA.WriteToLog("Beginning Voice Toggle","green");
while(true)
{
if(VA.Stopped) // if VA wants us to stop, abandon our task.
{
break;
}
if(VA.ParseTokens("{STATE_SPEECHACTIVE}") == "1") // we currently hear speech:
{
speechDetected = true;
if (!buttonPressed)
{
pushToTalk(true);
}
}
else // we currently do NOT hear speech:
{
if (speechDetected && !sw.IsRunning)
{
sw.Start();
speechDetected = false;
}
else if (buttonPressed && sw.ElapsedMilliseconds > timeToKeepRecording)
{
pushToTalk(false);
sw.Reset();
}
}
// don't do anything for a little while... no need to waste cpu cycles.
Thread.Sleep(10);
}
}
catch(Exception e)
{
VA.WriteToLog("Voice Toggle Exception: " + e,"red");
}
finally
{
pushToTalk(false);
VA.WriteToLog("Voice Toggle Exiting","purple");
}
}
void pushToTalk(bool targetState)
{
VA.ExecuteCommand("VOICE_ACTIVATED_TOGGLE " + targetState);
VA.WriteToLog("Voice Toggle " + (targetState ? "Enabled" : "Disabled"),"green");
buttonPressed = targetState;
}
}
I noticed you're using a toggle command, which means that state the push-to-talk key ends up in cannot be guaranteed, so this instead explicitly sets that state.