Plugin Development for FoxVox


Plugin support essentially provides a way to introduce and set variable values inside of FoxVox.  Variables are key/value pairs consisting of the variable Name and its Value.  Both name and value are parsed as strings, although internally numbers and Boolean values (true/false) are automatically converted for comparison purposes (=, >, <, !=, etc).  Variables names are case sensitive so "var1" and "Var1" are recognized as two different variables.   FoxVox variables can be used inside the library in the following ways:

  • Voice key values
    • Variable value specifies a recognized voice key which is loaded into the SR engine grammar set.  These variables are set onto voice keys by entering their name preceded by the # symbol.  The SR engine will refresh the grammar set every time a voice key variable changes.  You should ensure these don't change too frequently as it could bog down the SR engine due to constant refreshing.
  • Parsed input values
    • These are variables whose values follow the FoxVox variable input schema outlined below.  They translate into a keyboard key, mouse button, or HID device button/hat/analog inputs and can be used as dynamic inputs in place directly bound inputs on Input keys or PTT settings, or also as dynamic outputs on output commands (Note: for HID output, only vJoy virtual joystick outputs are supported).
  • Conditional values
    • These are variables which are used for condition statements within FoxVox.  Conditions can be set on both voice and key command groups, commands, and outputs for maximum flexibility.  Variable conditions compare the current value of the variable with a comparison operator to determine whether the condition is valid or not.  The variable values can be set and changed via the plugin or on executed outputs from within FoxVox.

Technical Specifications

Here's the technical basics on what is currently supported by FoxVox:

  • FoxVox runs on the .Net core platform (currently .Net 7) and uses reflection to parse a dynamically loaded assembly file.  This means the assembly must support MSIL parsing in order to run.  If you want to use native code or something else, you'll need to create a wrapper assembly in .Net that allows for translation.
  • Public methods that return either an object or an IDictionary<string variable, string value> will be made available in FoxVox.  Here are some examples of what will and won't work:
public void MethodA()will not be loaded as no object to parse is returned (void).
private ObjB MethodB()will not be loaded as it is marked private.
public ObjC MethodC(bool input)will load successfully.  A parameter must be added with a true/false value.
public ObjD MethodD()will load successfully.
  • FoxVox is designed to poll the method on a standard interval that is set by the user. Using reflection, it parses the returned object and exposes all Fields and Properties that are public in scope and are one of the basic following types: Numeric type (int, bool, long, float, byte, decimal, etc), boolean, string, or enum.  If the return value is an IDictionary<string, string> it will return the variable names and associated values.
  • Fields/Properties which are objects or arrays/lists are not recursively parsed (at least for now...) and are ignored.
  • Bitwise enums on the object should be typed as the actual enumeration and not left in its primitive underlying form (i.e. typed as an int) in order to make use of flag values. If so, FoxVox will parse the enum into its individual elements and return 1 or 0 depending on whether the flag bit is on or off in the current enum value.

Example

Here is a sample c# code file that uses both a returned class method and a returned dictionary<string, string> method to return variables to FoxVox:

using System.Collections.Generic;
namespace TestPlugin
{
    public enum EnumVals
    {
        Val1,
        Val2,
        Val3
    }
    public class PluginObject
    {
        public string ValueA { get; set; }
        public int ValueB { get; set; }
        public bool ValueC { get; set; }
        public EnumVals ValueD { get; set; }
    }
    public static class PluginMethods
    {
        public static PluginObject Method1()
        {
            return new PluginObject
            {
                ValueA = "Test A",
                ValueB = 100,
                ValueC = true,
                ValueD = EnumVals.Val1,
            };
        }
        public static Dictionary<string, string> Method2()
        {
            return new Dictionary<string, string>
            {
                {"ValueA", "Test A" },
                {"ValueB", "100" },
                {"ValueC", "true" },
                {"ValueD", "Val1" },
            };
        }
    }
}


FoxVox variable input schemas

Schemas can be combined with ';' to indicate separate elements or '/' to indicate grouped elements

 Bool values are parsed as follows: '1', 'true', 'yes', or 'ok' to indicate true, otherwise false (usually '0' or 'false')

 Hexadecimal values can be supplied for ints by preceding them with "0x", e.g. "0x41"

Mouse:

InputType | Button | Position

  • InputType [int]: 0 for mouse.
  • Button [int]: A button value from one of the following (From .Net System.Windows.Input.MouseButton):
    • Left = 0,
    • Middle = 1,
    • Right = 2,
    • XButton1 = 3,
    • XButton2 = 4,
    • Wheel Scroll = 5 or greater
  • Position [int] (Optional): 0 means press & release (down then up); Greater than 0 (i.e. 1) means button/wheel down; Less than 0 (i.e. -1) means button/wheel up;
Ex: "0|0|0"
designates mouse left button press & release

Note: Mouse movement and horizontal scroll is currently not supported in variables

Keyboard:

InputType | KeyCode | ScanCode | Modifiers | Position | Extended

  • InputType [int]: 1 for keyboard.
  • KeyCode [int]: A virtual key code value.
  • ScanCode [int]: A scan code value.
    • Note: Either a virtual key code or scan code is required.  If both are specified, the scan code is used and the virtual key code is ignored.
  • Modifiers [int]: A bitwise enum value from the following:
    • None = 0,
    • Shift = 1,
    • Control = 2,
    • Alt = 4,
    • ex: Alt+Shift would be a value of 5, Ctl+Shift would be a value of 3
  • Position [int] (Optional): 0 means press & release (down then up); Greater than 0 (i.e. 1) means key down; Less than 0 (i.e. -1) means key up;
  • Extended [bool] (Optional): indicates if the key is an extended key.
Ex: "1|0|0x1E|1|0|0"
designates Shift + A key press and release

Joystick/HID:

InputType | Device/Report# | ButtonType | Id (Button#/Hat#/Axis#) | Position | Product

  • InputType [int]: 2 for Joystick/HID.
  • Device/Report# [int]: Device number (0 based index).
  • ButtonType [int]: 0 for button, 1 for POV/Hat, 2 for Analog value.
  • Id [int]:
    • ButtonType=0: Button ID (1 to 128)
    • ButtonType=1: Pov/Hat ID (1 to 4)
    • ButtonType=2: Axis Id where X=48, Y=49, Z=50, xR=51, yR=52, zR=53, Slider1=54, Slider2=55, Slider3=56
  • Position [dynamic]:
    • ButtonType=0: negative (<0) = up, 0 full press, positive (>0) down
    • ButtonType=1: POV position in either
      • integer: -1=center, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW
      • degrees: -1=center, 0, 45, 90, 135, 180, 225, 270, 315
    • ButtonType=2: 0 to 100 percent, or csv ranges (ie 0-20,50-80)
  • Product: the HID device product name used to identify it (must include 'vJoy' if specifying a vJoy virtual device output)
    • This can also be the RawInput DeviceId value
  • Mfr (Optional): the HID device manufacturer name used to help identify it
Ex: "2|0|0|1|0|vJoy - Virtual Joystick"
designates button #1 press and release on vJoy device #1

When using variables as inputs, the following OPTIONAL values can be appended to the end of the schema to refine control

  • Press Delay [int]: The allowed time between presses in milliseconds.
  • Press Count [int]: Specify the required press count (e.g. 2 = double click).
  • Delay [int]: The duration the input must be held in milliseconds.
  • Latch [bool]: Enable latching behavior on activation (stays on until next activation).
  • LatchTimeout [int]: How long until the latch expires (default is indefinite).
  • Group ID [int]: The id of the group the key belongs to (input groups are evaluated independently).

NOTES:

To use these, all optional values in the schema must be specified

To leave a value at it's default, don't specify anything between the separators, e.g. ||

E.G. Append "||2||||" to one of the examples above to make it a double-click activation:

Ex: "2|0|0|1|0|vJoy - Virtual Joystick|||2||||"
(note...you can omit the separators after press count 2, or include them as shown)

That's it - now go find or create your own custom plugin for use with FoxVox!

Get FoxVox

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.