' Quick Command Creator Inline-Function for VoiceAttack v3 - Monitor for PTT Button(s) press ' by SemlerPDX Jan2021/Oct2021 ' VETERANS-GAMING.COM Imports Microsoft.VisualBasic Imports System Imports System.Threading Imports System.Threading.Tasks Public Class VAInline dim checkKeyDown as string = "" dim checkPovDir() as string dim checkPOV as string = "" dim masterMode as boolean = false dim listenAwake as boolean = false dim listeningCanWake as boolean = false dim listeningAltered as boolean = false dim keyDown as boolean = false dim keyAlwaysDown as boolean = false dim keyMonitoring as boolean = true dim keyMonitorActive as boolean = true dim keyMonitorType as integer = 0 dim listeningInterval as integer = 5500 dim keyPollingInterval as integer = 100 dim activeProfile as string = "CORE" dim debugCheck as boolean dim debugCount as integer = 0 Private Function CheckPTTkeyDownState(ByRef keyDown as boolean) for keyIndex as integer = 1 to 6 keyAlwaysDown = false 'Check only if this PTT button has been set if ((VA.GetText("AVCS_" + activeProfile + "_PTTBUTTON_" + keyIndex.ToString())) isNot nothing) checkKeyDown = VA.GetText("AVCS_" + activeProfile + "_PTTBUTTON_" + keyIndex.ToString()) 'Check if this is a reverse-PTT (push-to-mute) if ((VA.GetText("AVCS_" + activeProfile + "_PTTREVERSE_" + keyIndex.ToString())) isNot nothing) if ((VA.GetText("AVCS_" + activeProfile + "_PTTREVERSE_" + keyIndex.ToString())) = "reverse") keyAlwaysDown = true end if end if 'Attempt to check 'Trigger' type button state if (checkKeyDown.EndsWith("TRIGGER")) if (IsNumeric(VA.Utility.ParseTokens("{" + checkKeyDown + "}"))) if ((keyAlwaysDown) and (Convert.ToInt32(VA.Utility.ParseTokens("{" + checkKeyDown + "}")) < 20)) keyDown = true end if if ((not(keyAlwaysDown)) and (Convert.ToInt32(VA.Utility.ParseTokens("{" + checkKeyDown + "}")) > 20)) keyDown = true end if end if elseif (checkKeyDown.Contains("POV")) 'Check PTT POV Directional state checkPovDir = checkKeyDown.Split(":") if ((keyAlwaysDown) and ((VA.Utility.ParseTokens("{" + checkPovDir(0) + "}")) = "CENTER")) keyDown = true end if if ((not(keyAlwaysDown)) and (VA.Utility.ParseTokens("{" + checkPovDir(0) + "}") <> "CENTER")) if (VA.Utility.ParseTokens("{" + checkPovDir(0) + "}") = checkPovDir(1)) keyDown = true end if end if else 'Check PTT key/button state if ((keyAlwaysDown) and ((VA.Utility.ParseTokens("{" + checkKeyDown + "}")) = "0")) keyDown = true end if if ((not(keyAlwaysDown)) and ((VA.Utility.ParseTokens("{" + checkKeyDown + "}")) = "1")) keyDown = true end if end if end if 'Stop checking if a button/key down state has been set for return if (keyDown) Exit For end if next end function Private Function PTTStartListening(ByVal keyMonitorType as integer) 'Start Listening check with delay to eliminate false positives/negatives if (keyMonitorType > 0) Thread.CurrentThread.Sleep(150) if (not(VA.State.GetListeningEnabled)) VA.State.SetListeningEnabled(true) end if end if end function Private Function PTTStopListening(ByVal keyMonitorType as integer) 'Stop Listening check with delay to eliminate false positives/negatives if (keyMonitorType > 0) Thread.CurrentThread.Sleep(500) if (VA.State.GetListeningEnabled) VA.State.SetListeningEnabled(false) end if end if end function Private Function SendDebugMessage(ByVal debugText as string, ByVal debugColor as integer) if ((VA.GetText("AVCS_Debug_QMSG")) isNot nothing) debugCount = VA.GetInt("AVCS_Debug_QMSG") end if debugCount += 1 VA.SetText("AVCS_Debug_TMSG_" + debugCount.ToString(), debugText) VA.SetInt("AVCS_Debug_WCLR_" + debugCount.ToString(), debugColor) VA.SetInt("AVCS_Debug_QMSG", debugCount) try VA.Command.Execute("f_core_debug -log", true) catch VA.WriteToLog("AVCS ERROR: PTTMON01 - f_core_debug null - restart VoiceAttack or create bug report", "red") end try debugCount = 0 end function Public Sub Main() if ((VA.GetText("AVCS_ACTIVE_PROFILE")) isNot nothing) activeProfile = VA.GetText("AVCS_ACTIVE_PROFILE") end if 'Listening Wake - "Wait for spoken response" works when listening disabled; if that ever changes, set this bool to TRUE to enable hotfix below if ((VA.GetInt("AVCS_" + activeProfile + "_PTT_CANWAKE")) isNot nothing) listeningCanWake = VA.GetInt("AVCS_" + activeProfile + "_PTT_CANWAKE") end if if ((VA.GetInt("AVCS_" + activeProfile + "_PTT_MODE")) isNot nothing) keyMonitorType = VA.GetInt("AVCS_" + activeProfile + "_PTT_MODE") end if if ((VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening")) isNot nothing) listeningInterval = VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening") end if if ((VA.GetInt("AVCS_" + activeProfile + "_DevicePollingPTT")) isNot nothing) keyPollingInterval = VA.GetInt("AVCS_" + activeProfile + "_KeyPollingIntervalPTT") end if 'Main Mode Check - call this command from any init, if running it will exit before re-entering, or not at all (if unset) if ((VA.GetBoolean("AVCS_" + activeProfile + "_RadioButtons_ON")) isNot nothing) masterMode = VA.GetBoolean("AVCS_" + activeProfile + "_RadioButtons_ON") if (masterMode) 'Prepare Messages for AVCS Debug system to choose where to send them (event log/file/both) if ((VA.ParseTokens("{BOOL:AVCS_Debug_ON:false}")) = true) debugCheck = true SendDebugMessage("AVCS QCC PTT KeyMonitor Loop Entered",2) end if 'Stagger Delay for any existing loop to exit before new loop instance starts Thread.CurrentThread.Sleep(600) VA.SetBoolean("AVCS_RadioButtons_ON", true) VA.SetBoolean("AVCS_PTT_MODE_ON", true) Thread.CurrentThread.Sleep(keyPollingInterval) PTTStopListening(keyMonitorType) 'MAIN Monitor Loop while (keyMonitorActive) 'Exit Check - allows staggered exit and 'only one instance' of this loop if ((VA.ParseTokens("{BOOL:AVCS_RadioButtons_ON:false}")) = false) keyMonitorType = 1 keyMonitorActive = false PTTStartListening(keyMonitorType) Exit While end if 'Pausing Check - allows pausing the functionality of the main loop without exiting if ((VA.ParseTokens("{BOOL:AVCS_PTT_MODE_ON:false}")) = true) keyMonitoring = true else keyMonitoring = false end if Thread.CurrentThread.Sleep(keyPollingInterval) if (keyMonitoring) 'Keydown Check once per interval keyDown = false CheckPTTkeyDownState(keyDown) 'Listening Wake function - if "Wait for spoken response" ever respects global listening, this this will be needed if (not(keyDown)) if (listeningCanWake) if ((VA.ParseTokens("{BOOL:AVCS_QCC_LISTENING:false}")) = true) keyDown = true VA.SetBoolean("AVCS_QCC_LISTENING", nothing) end if end if end if 'Wake by Name Check once per interval if (not(keyDown)) if ((VA.ParseTokens("{BOOL:AVCS_QCC_AWAKE:false}")) = true) keyDown = true listenAwake = true VA.SetBoolean("AVCS_QCC_AWAKE", nothing) end if end if if (keyDown) VA.SetBoolean("AVCS_PTT_KeyDown", true) VA.SetBoolean("AVCS_" + activeProfile + "_PTT_KeyDown", true) PTTStartListening(keyMonitorType) if (debugCheck) SendDebugMessage("AVCS PTT KEY PRESS / WAKE DETECTED",2) end if 'If Listen Wake Hotfix enabled, allow VAS Loop to increase default wait for response here if (listeningCanWake) if ((VA.GetDecimal("AVCS_VAS_TIMEOUT")) isNot nothing) listeningInterval = 8500 listeningAltered = true end if end if 'Secondary Loop - Wait until done / stop listening for i as integer = 0 to listeningInterval step 500 Thread.CurrentThread.Sleep(500) if (i >= listeningInterval) Exit For end if 'Secondary Exit Check - get out if told to exit instance if ((VA.ParseTokens("{BOOL:AVCS_RadioButtons_ON:false}")) = false) keyMonitorType = 1 keyMonitorActive = false PTTStartListening(keyMonitorType) Exit While end if 'Increase waiting time by resetting counter upon unrecognized speech or repeated Wake Name use if ((VA.ParseTokens("{BOOL:AVCS_QCC_AWAKE:false}")) = true) i = 0 listenAwake = true VA.SetBoolean("AVCS_QCC_AWAKE", nothing) end if 'If wait loop entered via keyDown state detection, allow immediate on/off of Global Listening based on key state if (not(listenAwake)) keyDown = false CheckPTTkeyDownState(keyDown) if (keyDown) i = 0 PTTStartListening(keyMonitorType) else PTTStopListening(keyMonitorType) end if end if next 'Reset all function variables to begin loop again VA.SetBoolean("AVCS_PTT_KeyDown", false) VA.SetBoolean("AVCS_" + activeProfile + "_PTT_KeyDown", false) PTTStopListening(keyMonitorType) keyDown = false listenAwake = false if ((listeningCanWake) and (listeningAltered)) listeningAltered = false listeningInterval = 5500 if ((VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening")) isNot nothing) listeningInterval = VA.GetInt("AVCS_" + activeProfile + "_TimeUntilStopListening") end if end if if (debugCheck) SendDebugMessage("AVCS PTT LISTENING INTERVAL COMPLETE",4) end if end if end if end while VA.SetBoolean("AVCS_PTT_KeyDown", false) VA.SetBoolean("AVCS_" + activeProfile + "_PTT_KeyDown", false) if (debugCheck) SendDebugMessage("AVCS QCC PTT KeyMonitor Loop ended",2) end if else 'Cancel - when lauched but PTT mode is not enabled for this profile keyMonitorType = 1 PTTStartListening(keyMonitorType) end if end if End Sub End Class