diff --git a/README.md b/README.md
index 2c506bb..dd6cfa7 100644
--- a/README.md
+++ b/README.md
@@ -3,23 +3,17 @@ VoiceMeeter integration and live feedback for the Elgato Stream Deck device.
**Author's website and contact information:** [https://barraider.com](https://barraider.com)
-## What's new in v1.8
-- `AND/OR` support on the Mode1 Check in the `Advanced Toggle`! You can now do things like `Strip[0].Mute AND Strip[1].B2` or `Strip[0].Solo OR Strip[0].B2 OR Strip[1].B1`
-- Customizable `Long Press` length on the Press/Long-Press action
-- **Hotkey Support** :star_struck: - All advanced actions now support sending hotkeys to integrate with the :voicemeeter: Macros
-- **Midi Support** :star_struck: :star_struck: - All advanced actions now support the :voicemeeter: `SendMidi` commands
-- Support for `\n` (new line) in the Enabled/Disabled Texts
-
-## What's new in 1.7
-- VM Advanced actions now support renaming values that show 1 / 0 to a user-defined text (On/Off or Enabled/Disabled, etc.)
-- Bugfix in which the second image was not stored correctly in the VM Advanced Toggle action
-- Moved actions to a "VoiceMeeter" category in the Stream Deck app
+## New in v1.9
+- :new: **MacroButton support!** Toggle VoiceMeeter Macro Buttons from the Stream Deck
+ - Supports both "Toggle" mode and "PTT" mode.
+- `Mute/Unmute` action now supports sending hotkeys
+- Core improvements and bug fixes
### Download:
https://github.com/BarRaider/streamdeck-voicemeeter/releases/
## Current functionality
-### 5 Plugins built into one:
+### 6 Plugins built into one:
#### VoiceMeeter Mute/Unmute
- Allows you to easily connect to one of VoiceMeeter's Strips or Buses
- 3 different modes: Toggle/Push-To-Talk/Single Setting (on/off)
@@ -62,6 +56,9 @@ https://github.com/BarRaider/streamdeck-voicemeeter/releases/
#### VoiceMeeter Advanced PTT
The `Advanced PTT` action allows you to set a bunch of settings until you release the key.
+#### MacroButton Toggle
+Allows running VoiceMeeter macros from the Stream Deck. Supports both Toggle and Push modes. The `Logical ID` number is shown at the top-center of every VoiceMeeter macro.
+
### Fields explained:
- Mode1 Key Press - The configuration to set when we're toggling into Mode1 -> Use this to turn ON the setting e.g. `Strip[0].Mute=1`
- Mode1 Check - True/False value to determine if we're in Mode1. Example: If you input: `Strip[0].Mute` the plugin will determine you're in Mode1 every time Strip0 is muted.
@@ -73,6 +70,24 @@ The `Advanced PTT` action allows you to set a bunch of settings until you releas
- Title Value - Value to display in the title. Example: If you input: `Strip[0].Mono` it will display `1` when Mono is enabled on Strip0 and `0` otherwise.
+### Midi Usage
+You can trigger Midi functions using the SendMidi command from the Advanced Actions.
+Syntax: `SendMidi(DEVICE_NAME, COMMAND, CHANNEL, KEY_ID, VALUE);`
+
+**DEVICE_NAME:** Name of your device. Start of the name is good too (i.e. nano instead of nanoKORG).
+Name can be found in VoiceMeeter Macro under `MIDI OUT1 device:
+
+
+**COMMAND:** One of 3 options:
+ - note-on
+ - note-of
+ - ctrl-change
+
+**CHANNEL:** Integer value between 1 to 16
+
+**KEY_ID:** The id of the Midi key to turn on/off. This can be found using the LEARN feature inside VoiceMeeter Macro:
+
+
### FAQ
Q: Can I use this plugin to Restart VoiceMeeter?
A: Yes! Choose one of the "VoiceMeeter Advanced" plugins and use the following command: `Command.Restart = 1;`
@@ -86,6 +101,11 @@ A: Valid values can be found starting on page 9 of VoiceMeeter API PDF: https://
Q: Can I make the title multi-line?
A: Yes, write `\n` in the `Title Prefix` parameter to add lines
+Q: Is there AND/OR support for Mode1 Check?
+A: Yes, there is now `AND/OR` support on the Mode1 Check in the `Advanced Toggle`! You can now do things like `Strip[0].Mute AND Strip[1].B2` or `Strip[0].Solo OR Strip[0].B2 OR Strip[1].B1`
+
+Q: Where can I find the Macro `Logical ID`?
+A: The `Logical ID` number is shown at the top-center of every VoiceMeeter macro.
### Download
* [Download plugin](https://github.com/BarRaider/streamdeck-voicemeeter/releases/)
@@ -98,4 +118,18 @@ Please contact the developer. Contact information is available at https://barrai
## Dependencies
* Uses StreamDeck-Tools by BarRaider: [](https://www.nuget.org/packages/streamdeck-tools)
-* Uses [Easy-PI](https://github.com/BarRaider/streamdeck-easypi) by BarRaider - Provides seamless integration with the Stream Deck PI (Property Inspector)
\ No newline at end of file
+* Uses [Easy-PI](https://github.com/BarRaider/streamdeck-easypi) by BarRaider - Provides seamless integration with the Stream Deck PI (Property Inspector)
+
+## Change Log
+
+## What's new in v1.8
+- `AND/OR` support on the Mode1 Check in the `Advanced Toggle`! You can now do things like `Strip[0].Mute AND Strip[1].B2` or `Strip[0].Solo OR Strip[0].B2 OR Strip[1].B1`
+- Customizable `Long Press` length on the Press/Long-Press action
+- **Hotkey Support** :new: - All advanced actions now support sending hotkeys to integrate with the :voicemeeter: Macros
+- **Midi Support** :new: - All advanced actions now support the :voicemeeter: `SendMidi` commands
+- Support for `\n` (new line) in the Enabled/Disabled Texts
+
+## What's new in 1.7
+- VM Advanced actions now support renaming values that show 1 / 0 to a user-defined text (On/Off or Enabled/Disabled, etc.)
+- Bugfix in which the second image was not stored correctly in the VM Advanced Toggle action
+- Moved actions to a "VoiceMeeter" category in the Stream Deck app
diff --git a/VoiceMeeter/Actions/VMAdvancedPTTAction.cs b/VoiceMeeter/Actions/VMAdvancedPTTAction.cs
index d25da72..beb5869 100644
--- a/VoiceMeeter/Actions/VMAdvancedPTTAction.cs
+++ b/VoiceMeeter/Actions/VMAdvancedPTTAction.cs
@@ -69,6 +69,7 @@ public static PluginSettings CreateDefaultSettings()
#region Private members
private readonly PluginSettings settings;
+ private bool didSetNotConnected = false;
#endregion
@@ -90,8 +91,10 @@ public VMAdvancedPTTAction(SDConnection connection, InitialPayload payload) : ba
public async override void KeyPressed(KeyPayload payload)
{
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} KeyPressed");
if (!VMManager.Instance.IsConnected)
{
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but VM is not connected!");
await Connection.ShowAlert();
return;
}
@@ -126,9 +129,15 @@ public async override void OnTick()
{
if (!VMManager.Instance.IsConnected)
{
+ didSetNotConnected = true;
await Connection.SetImageAsync(Properties.Plugin.Default.VMNotRunning);
return;
}
+ else if (didSetNotConnected)
+ {
+ didSetNotConnected = false;
+ await Connection.SetImageAsync((String)null);
+ }
if (settings.TitleType == TitleTypeEnum.VMLive && !String.IsNullOrEmpty(settings.TitleParam))
{
@@ -156,7 +165,6 @@ public override void ReceivedSettings(ReceivedSettingsPayload payload)
{
Tools.AutoPopulateSettings(settings, payload.Settings);
InitializeSettings();
- Logger.Instance.LogMessage(TracingLevel.INFO, $"Settings loaded: {payload.Settings}");
}
public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) { }
diff --git a/VoiceMeeter/Actions/VMAdvancedPressAction.cs b/VoiceMeeter/Actions/VMAdvancedPressAction.cs
index 5258e7c..2e46e71 100644
--- a/VoiceMeeter/Actions/VMAdvancedPressAction.cs
+++ b/VoiceMeeter/Actions/VMAdvancedPressAction.cs
@@ -79,11 +79,10 @@ public static PluginSettings CreateDefaultSettings()
private const int LONG_KEYPRESS_LENGTH_MS = 600;
private readonly PluginSettings settings;
- private bool keyPressed = false;
private bool longKeyPressed = false;
- private DateTime keyPressStart;
private int longKeypressTime = LONG_KEYPRESS_LENGTH_MS;
private readonly System.Timers.Timer tmrRunLongPress = new System.Timers.Timer();
+ private bool didSetNotConnected = false;
#endregion
@@ -113,6 +112,7 @@ private void TmrRunLongPress_Elapsed(object sender, System.Timers.ElapsedEventAr
public void LongKeyPressed()
{
longKeyPressed = true;
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"Long keypress");
if (!String.IsNullOrEmpty(settings.LongPressValue))
{
VMManager.Instance.SetParameters(settings.LongPressValue);
@@ -133,18 +133,18 @@ public override void ReceivedSettings(ReceivedSettingsPayload payload)
{
Tools.AutoPopulateSettings(settings, payload.Settings);
InitializeSettings();
- Logger.Instance.LogMessage(TracingLevel.INFO, $"Settings loaded: {payload.Settings}");
}
public async override void KeyPressed(KeyPayload payload)
{
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} KeyPressed");
+
// Used for long press
- keyPressed = true;
longKeyPressed = false;
- keyPressStart = DateTime.Now;
if (!VMManager.Instance.IsConnected)
{
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but VM is not connected!");
await Connection.ShowAlert();
return;
}
@@ -155,11 +155,11 @@ public async override void KeyPressed(KeyPayload payload)
public override void KeyReleased(KeyPayload payload)
{
- keyPressed = false;
tmrRunLongPress.Stop();
if (!longKeyPressed && !String.IsNullOrEmpty(settings.SetValue))
{
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"Short keypress");
VMManager.Instance.SetParameters(settings.SetValue);
MidiCommandHandler.HandleMidiParameters(settings.KeypressMidi);
if (!String.IsNullOrEmpty(settings.KeypressHotkey))
@@ -173,9 +173,15 @@ public async override void OnTick()
{
if (!VMManager.Instance.IsConnected)
{
+ didSetNotConnected = true;
await Connection.SetImageAsync(Properties.Plugin.Default.VMNotRunning);
return;
}
+ else if (didSetNotConnected)
+ {
+ didSetNotConnected = false;
+ await Connection.SetImageAsync((String)null);
+ }
if (settings.TitleType == TitleTypeEnum.VMLive && !String.IsNullOrEmpty(settings.TitleParam))
{
@@ -202,6 +208,8 @@ public async override void OnTick()
public override void Dispose()
{
Logger.Instance.LogMessage(TracingLevel.INFO, "Destructor called");
+ tmrRunLongPress.Stop();
+ tmrRunLongPress.Elapsed -= TmrRunLongPress_Elapsed;
}
public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) { }
diff --git a/VoiceMeeter/Actions/VMAdvancedToggle.cs b/VoiceMeeter/Actions/VMAdvancedToggle.cs
index fcdb20e..0fbff08 100644
--- a/VoiceMeeter/Actions/VMAdvancedToggle.cs
+++ b/VoiceMeeter/Actions/VMAdvancedToggle.cs
@@ -102,6 +102,7 @@ public static PluginSettings CreateDefaultSettings()
private const string LOGICAL_OR = " OR ";
private readonly PluginSettings settings;
+ private bool didSetNotConnected = false;
#endregion
@@ -127,8 +128,10 @@ public VMAdvancedToggleAction(SDConnection connection, InitialPayload payload) :
public async override void KeyPressed(KeyPayload payload)
{
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} KeyPressed");
if (!VMManager.Instance.IsConnected)
{
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but VM is not connected!");
await Connection.ShowAlert();
return;
}
@@ -168,9 +171,15 @@ public async override void OnTick()
{
if (!VMManager.Instance.IsConnected)
{
+ didSetNotConnected = true;
await Connection.SetImageAsync(Properties.Plugin.Default.VMNotRunning);
return;
}
+ else if (didSetNotConnected)
+ {
+ didSetNotConnected = false;
+ await Connection.SetImageAsync((String)null);
+ }
// Set the image
if (!String.IsNullOrEmpty(settings.UserImage1) && IsMode1(false))
@@ -213,8 +222,6 @@ public override void Dispose()
public async override void ReceivedSettings(ReceivedSettingsPayload payload)
{
Tools.AutoPopulateSettings(settings, payload.Settings);
- Logger.Instance.LogMessage(TracingLevel.INFO, $"Settings loaded: {payload.Settings}");
-
InitializeSettings();
// Used to return the correct filename back to the Property Inspector
await SaveSettings();
diff --git a/VoiceMeeter/Actions/VMMacroToggle.cs b/VoiceMeeter/Actions/VMMacroToggle.cs
new file mode 100644
index 0000000..8479917
--- /dev/null
+++ b/VoiceMeeter/Actions/VMMacroToggle.cs
@@ -0,0 +1,296 @@
+using BarRaider.SdTools;
+using HotkeyCommands;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Printing;
+using System.Drawing.Text;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using VoiceMeeter.Midi;
+using WindowsInput.Native;
+
+namespace VoiceMeeter
+{
+ //---------------------------------------------------
+ // BarRaider's Hall Of Fame
+ // Subscriber: JustVoxPop
+ // Subscriber: iMackx
+ // Subscriber: CyberlightGames
+ // Craigs_Cave - 5 Gifted Subs
+ // 100 Bits: iMackx
+ // JustVoxPop - 1 Gifted Subs
+ // iMackx - 1 Gifted Subs
+ // nubby_ninja - 5 Gifted Subs
+ // 500 Bits: MagicGuitarist
+ // Subscriber: SaintG85
+ // Subscriber: MagicGuitarist
+ // 17 Bits: TwilightLinkable
+ //---------------------------------------------------
+ [PluginActionId("com.barraider.vmmacrotoggle")]
+ class VMMacroToggle : PluginBase
+ {
+ private enum MacroToggleMode
+ {
+ Toggle = 0,
+ PTT = 1
+ }
+ private class PluginSettings
+ {
+ public static PluginSettings CreateDefaultSettings()
+ {
+ PluginSettings instance = new PluginSettings
+ {
+ EnabledImage = String.Empty,
+ DisabledImage = String.Empty,
+ TitlePrefix = String.Empty,
+ EnabledText = String.Empty,
+ DisabledText = String.Empty,
+ ButtonId = DEFAULT_BUTTON_ID.ToString(),
+ ToggleMode = MacroToggleMode.Toggle
+ };
+
+ return instance;
+ }
+
+ [JsonProperty(PropertyName = "buttonId")]
+ public string ButtonId { get; set; }
+
+ [JsonProperty(PropertyName = "toggleMode")]
+ public MacroToggleMode ToggleMode { get; set; }
+
+ [FilenameProperty]
+ [JsonProperty(PropertyName = "enabledImage")]
+ public string EnabledImage { get; set; }
+
+ [FilenameProperty]
+ [JsonProperty(PropertyName = "disabledImage")]
+ public string DisabledImage { get; set; }
+
+ [JsonProperty(PropertyName = "titlePrefix")]
+ public string TitlePrefix { get; set; }
+
+ [JsonProperty(PropertyName = "enabledText")]
+ public string EnabledText { get; set; }
+
+ [JsonProperty(PropertyName = "disabledText")]
+ public string DisabledText { get; set; }
+ }
+
+ #region Private members
+ private const int DEFAULT_BUTTON_ID = 0;
+ private static readonly string[] DEFAULT_BUTTON_IMAGES = { @"images\buttonDisabled.png", @"images\buttonEnabled.png" };
+
+ private readonly PluginSettings settings;
+ private int buttonId = DEFAULT_BUTTON_ID;
+ private bool isButtonEnabled = false;
+ private bool startingToggleMode = false;
+ private Image enabledImage = null;
+ private Image disabledImage = null;
+ private bool didSetNotConnected = false;
+
+ #endregion
+
+ #region Public Methods
+
+ public VMMacroToggle(SDConnection connection, InitialPayload payload) : base(connection, payload)
+ {
+ if (payload.Settings == null || payload.Settings.Count == 0)
+ {
+ this.settings = PluginSettings.CreateDefaultSettings();
+ Connection.SetSettingsAsync(JObject.FromObject(settings));
+ }
+ else
+ {
+ this.settings = payload.Settings.ToObject();
+ }
+ InitializeSettings();
+ }
+
+ #endregion
+
+ #region IPluginable
+
+ public async override void KeyPressed(KeyPayload payload)
+ {
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} KeyPressed");
+ if (!VMManager.Instance.IsConnected)
+ {
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but VM is not connected!");
+ await Connection.ShowAlert();
+ return;
+ }
+
+ if (String.IsNullOrEmpty(settings.ButtonId))
+ {
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but ButtonID is null!");
+ await Connection.ShowAlert();
+ return;
+ }
+
+ // Store the initial value so we can revert back to it
+ if (settings.ToggleMode == MacroToggleMode.PTT)
+ {
+ startingToggleMode = isButtonEnabled;
+ }
+
+ VMManager.Instance.SetMacroStatus(buttonId, !isButtonEnabled);
+
+ if (settings.ToggleMode == MacroToggleMode.Toggle)
+ {
+ await Connection.ShowOk();
+ }
+ }
+
+ public override void KeyReleased(KeyPayload payload)
+ {
+ if (settings.ToggleMode == MacroToggleMode.PTT)
+ {
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} Key Released");
+ if (!VMManager.Instance.IsConnected)
+ {
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key released but VM is not connected!");
+ return;
+ }
+
+ if (String.IsNullOrEmpty(settings.ButtonId))
+ {
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key released but ButtonID is null!");
+ return;
+ }
+ VMManager.Instance.SetMacroStatus(buttonId, startingToggleMode);
+ }
+ }
+
+ public async override void OnTick()
+ {
+ if (!VMManager.Instance.IsConnected)
+ {
+ didSetNotConnected = true;
+ await Connection.SetImageAsync(Properties.Plugin.Default.VMNotRunning);
+ return;
+ }
+ else if (didSetNotConnected)
+ {
+ didSetNotConnected = false;
+ await Connection.SetImageAsync((String)null);
+ }
+
+ isButtonEnabled = VMManager.Instance.GetMacroStatus(buttonId);
+
+ // Set the image
+ if (isButtonEnabled)
+ {
+ await Connection.SetImageAsync(enabledImage);
+ }
+ else
+ {
+ await Connection.SetImageAsync(disabledImage);
+ }
+
+ // Set the title
+ string prefix = String.Empty;
+ if (!String.IsNullOrEmpty(settings.TitlePrefix))
+ {
+ prefix = settings.TitlePrefix.Replace(@"\n", "\n");
+ }
+
+ string value = isButtonEnabled ? "1" : "0";
+ if (!String.IsNullOrEmpty(settings.EnabledText) && !String.IsNullOrEmpty(value) && value == Constants.ENABLED_VALUE)
+ {
+ value = settings.EnabledText.Replace(@"\n", "\n"); ;
+ }
+ else if (!String.IsNullOrEmpty(settings.DisabledText) && !String.IsNullOrEmpty(value) && value == Constants.DISABLED_VALUE)
+ {
+ value = settings.DisabledText.Replace(@"\n", "\n"); ;
+ }
+
+ await Connection.SetTitleAsync($"{prefix}{value}");
+
+ }
+
+ public override void Dispose()
+ {
+ Logger.Instance.LogMessage(TracingLevel.INFO, "Destructor called");
+ }
+
+ public async override void ReceivedSettings(ReceivedSettingsPayload payload)
+ {
+ Tools.AutoPopulateSettings(settings, payload.Settings);
+ InitializeSettings();
+ // Used to return the correct filename back to the Property Inspector
+ await SaveSettings();
+ }
+
+ public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) { }
+
+ #endregion
+
+ #region Private Methods
+
+ private Task SaveSettings()
+ {
+ return Connection.SetSettingsAsync(JObject.FromObject(settings));
+ }
+
+ private void InitializeSettings()
+ {
+ if (!Int32.TryParse(settings.ButtonId, out buttonId))
+ {
+ settings.ButtonId = DEFAULT_BUTTON_ID.ToString();
+ buttonId = DEFAULT_BUTTON_ID;
+ SaveSettings();
+ }
+
+ PrefetchImages();
+ }
+
+ private void PrefetchImages()
+ {
+ try
+ {
+ if (enabledImage != null)
+ {
+ enabledImage.Dispose();
+ enabledImage = null;
+ }
+
+ if (disabledImage != null)
+ {
+ disabledImage.Dispose();
+ disabledImage = null;
+ }
+
+ enabledImage = Image.FromFile(TryGetCustomFile(settings.EnabledImage, DEFAULT_BUTTON_IMAGES[1]));
+ disabledImage = Image.FromFile(TryGetCustomFile(settings.DisabledImage, DEFAULT_BUTTON_IMAGES[0]));
+ }
+ catch (Exception ex)
+ {
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"PrefetchImages Exception {ex}");
+ }
+ }
+ private string TryGetCustomFile(string fileName, string fallbackFilename)
+ {
+ string value = fallbackFilename;
+ if (!String.IsNullOrEmpty(fileName))
+ {
+ if (!File.Exists(fileName))
+ {
+ Logger.Instance.LogMessage(TracingLevel.WARN, $"TryGetCustomFile: File not found {fileName}");
+ }
+ else
+ {
+ value = fileName;
+ }
+ }
+
+ return value;
+ }
+
+ #endregion
+ }
+}
diff --git a/VoiceMeeter/Actions/VMMicrophoneAction.cs b/VoiceMeeter/Actions/VMMicrophoneAction.cs
index 4339345..9ffc01f 100644
--- a/VoiceMeeter/Actions/VMMicrophoneAction.cs
+++ b/VoiceMeeter/Actions/VMMicrophoneAction.cs
@@ -1,4 +1,5 @@
using BarRaider.SdTools;
+using HotkeyCommands;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@@ -36,7 +37,9 @@ public static PluginSettings CreateDefaultSettings()
SingleValue = String.Empty,
ImageType = ImageTypeEnum.Microphone,
UserImage1 = String.Empty,
- UserImage2 = String.Empty
+ UserImage2 = String.Empty,
+ MuteHotkey = String.Empty,
+ UnmuteHotkey = String.Empty
};
return instance;
@@ -64,11 +67,19 @@ public static PluginSettings CreateDefaultSettings()
[FilenameProperty]
[JsonProperty(PropertyName = "userImage2")]
public string UserImage2 { get; set; }
+
+ [JsonProperty(PropertyName = "muteHotkey")]
+ public string MuteHotkey { get; set; }
+
+ [JsonProperty(PropertyName = "unmuteHotkey")]
+ public string UnmuteHotkey { get; set; }
+
}
#region Private members
private readonly PluginSettings settings;
+ private bool didSetNotConnected = false;
#endregion
@@ -93,12 +104,15 @@ public VMMicrophoneAction(SDConnection connection, InitialPayload payload) : bas
public async override void KeyPressed(KeyPayload payload)
{
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} KeyPressed");
if (!VMManager.Instance.IsConnected)
{
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but VM is not connected!");
await Connection.ShowAlert();
return;
}
+ bool triggeredMute = false;
switch (settings.MicType)
{
case MicTypeEnum.SingleMode:
@@ -106,6 +120,7 @@ public async override void KeyPressed(KeyPayload payload)
if (Int32.TryParse(settings.SingleValue, out value))
{
VMManager.Instance.SetParam(BuildDeviceName(), value);
+ triggeredMute = value != 0;
}
else
{
@@ -115,11 +130,23 @@ public async override void KeyPressed(KeyPayload payload)
case MicTypeEnum.Toggle:
bool isMuted = VMManager.Instance.GetParamBool(BuildDeviceName());
VMManager.Instance.SetParam(BuildDeviceName(), isMuted ? 0 : 1);
+ triggeredMute = !isMuted;
break;
case MicTypeEnum.PTT:
VMManager.Instance.SetParam(BuildDeviceName(), 0);
+ triggeredMute = false;
break;
}
+
+ if (triggeredMute && !String.IsNullOrEmpty(settings.MuteHotkey))
+ {
+ HotkeyHandler.RunHotkey(settings.MuteHotkey);
+ }
+ else if (!triggeredMute && !String.IsNullOrEmpty(settings.UnmuteHotkey))
+ {
+ HotkeyHandler.RunHotkey(settings.UnmuteHotkey);
+ }
+
}
public override void KeyReleased(KeyPayload payload)
@@ -127,6 +154,11 @@ public override void KeyReleased(KeyPayload payload)
if (settings.MicType == MicTypeEnum.PTT)
{
VMManager.Instance.SetParam(BuildDeviceName(), 1);
+
+ if (!String.IsNullOrEmpty(settings.MuteHotkey))
+ {
+ HotkeyHandler.RunHotkey(settings.MuteHotkey);
+ }
}
}
@@ -134,9 +166,15 @@ public async override void OnTick()
{
if (!VMManager.Instance.IsConnected)
{
+ didSetNotConnected = true;
await Connection.SetImageAsync(Properties.Plugin.Default.VMNotRunning);
return;
}
+ else if (didSetNotConnected)
+ {
+ didSetNotConnected = false;
+ await Connection.SetImageAsync((String)null);
+ }
await Connection.SetImageAsync(GetBase64ImageStatus());
}
@@ -150,7 +188,6 @@ public async override void ReceivedSettings(ReceivedSettingsPayload payload)
{
// New in StreamDeck-Tools v2.0:
Tools.AutoPopulateSettings(settings, payload.Settings);
- Logger.Instance.LogMessage(TracingLevel.INFO, $"Settings loaded: {payload.Settings}");
// Used to return the correct filename back to the Property Inspector
await Connection.SetSettingsAsync(JObject.FromObject(settings));
diff --git a/VoiceMeeter/Actions/VMModifyAction.cs b/VoiceMeeter/Actions/VMModifyAction.cs
index 03dff33..34763fd 100644
--- a/VoiceMeeter/Actions/VMModifyAction.cs
+++ b/VoiceMeeter/Actions/VMModifyAction.cs
@@ -80,6 +80,7 @@ public static PluginSettings CreateDefaultSettings()
private bool keyPressed = false;
private bool longKeyPressed = false;
private DateTime keyPressStart;
+ private bool didSetNotConnected = false;
#endregion
@@ -113,8 +114,10 @@ public void LongKeyPressed()
public async override void KeyPressed(KeyPayload payload)
{
+ Logger.Instance.LogMessage(TracingLevel.INFO, $"{this.GetType()} KeyPressed");
if (!VMManager.Instance.IsConnected)
{
+ Logger.Instance.LogMessage(TracingLevel.ERROR, $"Key pressed but VM is not connected!");
await Connection.ShowAlert();
return;
}
@@ -142,10 +145,16 @@ public async override void OnTick()
{
if (!VMManager.Instance.IsConnected)
{
+ didSetNotConnected = true;
await Connection.SetImageAsync(Properties.Plugin.Default.VMNotRunning);
return;
}
-
+ else if (didSetNotConnected)
+ {
+ didSetNotConnected = false;
+ await Connection.SetImageAsync((String)null);
+ }
+
// Stream Deck calls this function every second,
// so this is the best place to determine if we need to call the long keypress
if (!String.IsNullOrEmpty(settings.LongPressValue) && keyPressed && (DateTime.Now - keyPressStart).TotalSeconds > LONG_KEYPRESS_LENGTH)
@@ -174,7 +183,6 @@ public override void ReceivedSettings(ReceivedSettingsPayload payload)
{
// New in StreamDeck-Tools v2.0:
Tools.AutoPopulateSettings(settings, payload.Settings);
- Logger.Instance.LogMessage(TracingLevel.INFO, $"Settings loaded: {payload.Settings}");
}
public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payload) { }
@@ -185,7 +193,7 @@ public override void ReceivedGlobalSettings(ReceivedGlobalSettingsPayload payloa
private string BuildDeviceName()
{
- return $"{settings.Strip}[{settings.StripNum}].{settings.ParamType.ToString()}";
+ return $"{settings.Strip}[{settings.StripNum}].{settings.ParamType}";
}
#endregion
diff --git a/VoiceMeeter/Images/buttonDisabled.png b/VoiceMeeter/Images/buttonDisabled.png
new file mode 100644
index 0000000..2a0fdbe
Binary files /dev/null and b/VoiceMeeter/Images/buttonDisabled.png differ
diff --git a/VoiceMeeter/Images/buttonDisabled@2x.png b/VoiceMeeter/Images/buttonDisabled@2x.png
new file mode 100644
index 0000000..d73b81b
Binary files /dev/null and b/VoiceMeeter/Images/buttonDisabled@2x.png differ
diff --git a/VoiceMeeter/Images/buttonEnabled.png b/VoiceMeeter/Images/buttonEnabled.png
new file mode 100644
index 0000000..0b907f7
Binary files /dev/null and b/VoiceMeeter/Images/buttonEnabled.png differ
diff --git a/VoiceMeeter/Images/buttonEnabled@2x.png b/VoiceMeeter/Images/buttonEnabled@2x.png
new file mode 100644
index 0000000..9bd4326
Binary files /dev/null and b/VoiceMeeter/Images/buttonEnabled@2x.png differ
diff --git a/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedKeypress.html b/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedKeypress.html
index 18466bf..61ea719 100644
--- a/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedKeypress.html
+++ b/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedKeypress.html
@@ -6,15 +6,18 @@
BarRaider's VoiceMeeter Plugin
-
+
+
-
+
+ For feedback/suggestions contact me at https://BarRaider.com
+ This plugins allows you to send a list of commands directly to VoiceMeeter (click this text for more info...)
@@ -103,10 +106,6 @@
"Disabled" text
-
- For feedback/suggestions contact me at https://BarRaider.com
-
-
diff --git a/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedPTT.html b/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedPTT.html
index d68a358..ff6dfe5 100644
--- a/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedPTT.html
+++ b/VoiceMeeter/PropertyInspector/VoiceMeeter/AdvancedPTT.html
@@ -6,14 +6,17 @@
BarRaider's VoiceMeeter Plugin
-
+
+
-
+
+ For feedback/suggestions contact me at https://BarRaider.com
+ This plugins allows you to send a list of commands directly to VoiceMeeter (click this text for more info...)
- Toggle between Mode1 and Mode2 by pressing the button (click this text for more info...)
+ Click Here for usage instructions
Mode1 is used to turn things ON. Mode 2 is used to turn things OFF.
Example: Lets use Mode1 to turn Mono on (and do aditional things): "Strip[0].mono=1;Bus[2].Gain=-20;"
diff --git a/VoiceMeeter/PropertyInspector/VoiceMeeter/MacroToggle.html b/VoiceMeeter/PropertyInspector/VoiceMeeter/MacroToggle.html
new file mode 100644
index 0000000..a121b6e
--- /dev/null
+++ b/VoiceMeeter/PropertyInspector/VoiceMeeter/MacroToggle.html
@@ -0,0 +1,61 @@
+
+
+