diff --git a/Directory.Packages.props b/Directory.Packages.props
index 5dac804..857504e 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -20,5 +20,8 @@
+
+
+
diff --git a/OpenShock.VoiceRecognizer.Common/Enums/BrowserProxyType.cs b/OpenShock.VoiceRecognizer.Common/Enums/BrowserProxyType.cs
new file mode 100644
index 0000000..68b4bef
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Common/Enums/BrowserProxyType.cs
@@ -0,0 +1,13 @@
+using OpenShock.VoiceRecognizer.Common.Utility;
+using System.Text.Json.Serialization;
+
+namespace OpenShock.VoiceRecognizer.Common.Enums;
+
+[JsonConverter(typeof(TypedStringEnumConverter))]
+public enum BrowserProxyType
+{
+ Chrome,
+ Edge,
+ Opera,
+ Firefox,
+};
diff --git a/OpenShock.VoiceRecognizer.Configuration/AudioConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/AudioConfigurationState.cs
index ef32f6b..17b0eec 100644
--- a/OpenShock.VoiceRecognizer.Configuration/AudioConfigurationState.cs
+++ b/OpenShock.VoiceRecognizer.Configuration/AudioConfigurationState.cs
@@ -16,5 +16,5 @@ public void LoadFileConfiguration(ConfigurationFileFormat configurationFileForma
InputDeviceID.Value = configurationFileFormat.InputDeviceID;
public void LoadDefaultConfiguration() =>
- InputDeviceID = new(AudioDevices.GetInputAudioDevices().First().ID);
+ InputDeviceID.Value = AudioDevices.GetInputAudioDevices().First().ID;
}
diff --git a/OpenShock.VoiceRecognizer.Configuration/BrowserProxyConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/BrowserProxyConfigurationState.cs
new file mode 100644
index 0000000..0cfb11a
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Configuration/BrowserProxyConfigurationState.cs
@@ -0,0 +1,29 @@
+using OpenShock.VoiceRecognizer.Common;
+using OpenShock.VoiceRecognizer.Common.Audio;
+using OpenShock.VoiceRecognizer.Common.Enums;
+
+namespace OpenShock.VoiceRecognizer.Configuration;
+
+public class BrowserProxyConfigurationState
+{
+ public ReactiveObject Proxy { get; set; }
+ public ReactiveObject ProxyPort { get; set; }
+
+ public BrowserProxyConfigurationState()
+ {
+ Proxy = new(BrowserProxyType.Chrome);
+ ProxyPort = new(0);
+ }
+
+ public void LoadFileConfiguration(ConfigurationFileFormat configurationFileFormat)
+ {
+ Proxy.Value = configurationFileFormat.BrowserProxyType;
+ ProxyPort.Value = configurationFileFormat.BrowserProxyPort;
+ }
+
+ public void LoadDefaultConfiguration()
+ {
+ Proxy.Value = BrowserProxyType.Chrome;
+ ProxyPort.Value = 0;
+ }
+}
diff --git a/OpenShock.VoiceRecognizer.Configuration/ConfigurationFileFormat.cs b/OpenShock.VoiceRecognizer.Configuration/ConfigurationFileFormat.cs
index 75c60ed..af570ae 100644
--- a/OpenShock.VoiceRecognizer.Configuration/ConfigurationFileFormat.cs
+++ b/OpenShock.VoiceRecognizer.Configuration/ConfigurationFileFormat.cs
@@ -9,8 +9,17 @@ public class ConfigurationFileFormat
public string InputDeviceID { get; set; } = string.Empty;
public string VoskModelDirectory { get; set; } = string.Empty;
public int OscListenPort { get; set; } = 0;
- public ShockCollarType CollarType { get; }
+ public ShockCollarType CollarType { get; set; } = ShockCollarType.OpenShock;
public ObservableCollection Words { get; set; } = [];
+ /*public string OpenShockAPIKey { get; set; } = string.Empty;
+ public string OpenShockGroupName { get; set; } = string.Empty;*/
+ public string OpenShockSendHost { get; set; } = string.Empty;
+ public int OpenShockSendPort { get; set; } = 0;
+ public string OpenShockOscListenIntensityEndpoint { get; set; } = string.Empty;
+ public string OpenShockOscSendShockEndpoint { get; set; } = string.Empty;
+ public string OpenShockOscSendVibrateEndpoint { get; set; } = string.Empty;
+ public BrowserProxyType BrowserProxyType { get; set; } = BrowserProxyType.Chrome;
+ public int BrowserProxyPort { get; set; } = 0;
public ConfigurationFileFormat() { }
@@ -21,6 +30,15 @@ public ConfigurationFileFormat(ConfigurationState state)
OscListenPort = state.OSC.ListenPort.Value;
CollarType = state.Shock.CollarType.Value;
Words = state.Shock.Words.Value;
+ /*OpenShockAPIKey = state.OpenShock.APIKey.Value;
+ OpenShockGroupName = state.OpenShock.GroupName.Value;*/
+ OpenShockSendHost = state.OpenShock.SendHost.Value;
+ OpenShockSendPort = state.OpenShock.SendPort.Value;
+ OpenShockOscListenIntensityEndpoint = state.OpenShock.ExternalListenSetIntensityEndpoint;
+ OpenShockOscSendShockEndpoint = state.OpenShock.ExternalSendStartShockEndpoint;
+ OpenShockOscSendVibrateEndpoint = state.OpenShock.ExternalSendStartShockEndpoint;
+ BrowserProxyType = state.BrowserProxy.Proxy.Value;
+ BrowserProxyPort = state.BrowserProxy.ProxyPort.Value;
}
public static bool TryLoad(string filepath, out ConfigurationFileFormat? configurationFileFormat)
diff --git a/OpenShock.VoiceRecognizer.Configuration/ConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/ConfigurationState.cs
index 74ff1ef..1ba43ce 100644
--- a/OpenShock.VoiceRecognizer.Configuration/ConfigurationState.cs
+++ b/OpenShock.VoiceRecognizer.Configuration/ConfigurationState.cs
@@ -1,6 +1,4 @@
-using OpenShock.VoiceRecognizer.Common.Enums;
-
-namespace OpenShock.VoiceRecognizer.Configuration;
+namespace OpenShock.VoiceRecognizer.Configuration;
public class ConfigurationState
{
@@ -10,6 +8,8 @@ public class ConfigurationState
public VoskConfigurationState Vosk { get; }
public OSCConfigurationState OSC { get; }
public ShockConfigurationState Shock { get; }
+ public OpenShockConfigurationState OpenShock { get; }
+ public BrowserProxyConfigurationState BrowserProxy { get; }
public static ConfigurationState? Instance { get; private set; } = null;
@@ -19,6 +19,8 @@ private ConfigurationState()
Vosk = new();
OSC = new();
Shock = new();
+ OpenShock = new();
+ BrowserProxy = new();
}
public void LoadConfiguration()
@@ -41,6 +43,8 @@ private void LoadConfigurationStateFromFile()
Vosk.LoadFileConfiguration(configurationFileFormat!);
OSC.LoadFileConfiguration(configurationFileFormat!);
Shock.LoadFileConfiguration(configurationFileFormat!);
+ OpenShock.LoadFileConfiguration(configurationFileFormat!);
+ BrowserProxy.LoadFileConfiguration(configurationFileFormat!);
}
}
@@ -50,6 +54,8 @@ private void LoadDefaultConfigurationState()
Vosk.LoadDefaultConfiguration();
OSC.LoadDefaultConfiguration();
Shock.LoadDefaultConfiguration();
+ OpenShock.LoadDefaultConfiguration();
+ BrowserProxy.LoadDefaultConfiguration();
}
public void SaveConfigurationStateToFile() =>
diff --git a/OpenShock.VoiceRecognizer.Configuration/OSCConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/OSCConfigurationState.cs
index c7e2f5c..5fb0ba3 100644
--- a/OpenShock.VoiceRecognizer.Configuration/OSCConfigurationState.cs
+++ b/OpenShock.VoiceRecognizer.Configuration/OSCConfigurationState.cs
@@ -15,5 +15,5 @@ public void LoadFileConfiguration(ConfigurationFileFormat configurationFileForma
ListenPort.Value = configurationFileFormat.OscListenPort;
public void LoadDefaultConfiguration() =>
- ListenPort = new(9005);
+ ListenPort.Value = 9005;
}
diff --git a/OpenShock.VoiceRecognizer.Configuration/OpenShockConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/OpenShockConfigurationState.cs
new file mode 100644
index 0000000..18b1c53
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Configuration/OpenShockConfigurationState.cs
@@ -0,0 +1,48 @@
+using OpenShock.VoiceRecognizer.Common;
+
+namespace OpenShock.VoiceRecognizer.Configuration;
+
+public class OpenShockConfigurationState
+{
+ /*public ReactiveObject APIKey { get; private set; }
+ public ReactiveObject GroupName { get; private set; }*/
+ public ReactiveObject SendHost { get; private set; }
+ public ReactiveObject SendPort { get; private set; }
+
+ public ReactiveObject ExternalListenSetIntensityEndpoint { get; set; }
+ public ReactiveObject ExternalSendStartShockEndpoint { get; set; }
+ public ReactiveObject ExternalSendStartVibrationEndpoint { get; set; }
+
+ public OpenShockConfigurationState()
+ {
+ /*APIKey = new(string.Empty);
+ GroupName = new(string.Empty);*/
+ SendHost = new(string.Empty);
+ SendPort = new(9006);
+ ExternalListenSetIntensityEndpoint = new(string.Empty);
+ ExternalSendStartShockEndpoint = new(string.Empty);
+ ExternalSendStartVibrationEndpoint = new(string.Empty);
+ }
+
+ public void LoadFileConfiguration(ConfigurationFileFormat configurationFileFormat)
+ {
+ /*APIKey.Value = configurationFileFormat.OpenShockAPIKey;
+ GroupName.Value = configurationFileFormat.OpenShockGroupName;*/
+ SendHost.Value = configurationFileFormat.OpenShockSendHost;
+ SendPort.Value = configurationFileFormat.OpenShockSendPort;
+ ExternalListenSetIntensityEndpoint.Value = configurationFileFormat.OpenShockOscListenIntensityEndpoint;
+ ExternalSendStartShockEndpoint.Value = configurationFileFormat.OpenShockOscSendShockEndpoint;
+ ExternalSendStartVibrationEndpoint.Value = configurationFileFormat.OpenShockOscSendVibrateEndpoint;
+ }
+
+ public void LoadDefaultConfiguration()
+ {
+ /*APIKey.Value = string.Empty;
+ GroupName.Value = string.Empty;*/
+ SendHost.Value = "127.0.0.1";
+ SendPort.Value = 0;
+ ExternalListenSetIntensityEndpoint.Value = string.Empty;
+ ExternalSendStartShockEndpoint.Value = string.Empty;
+ ExternalSendStartVibrationEndpoint.Value = string.Empty;
+ }
+}
diff --git a/OpenShock.VoiceRecognizer.Configuration/ShockConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/ShockConfigurationState.cs
index b8e65d1..3eaf314 100644
--- a/OpenShock.VoiceRecognizer.Configuration/ShockConfigurationState.cs
+++ b/OpenShock.VoiceRecognizer.Configuration/ShockConfigurationState.cs
@@ -24,8 +24,8 @@ public void LoadFileConfiguration(ConfigurationFileFormat configurationFileForma
public void LoadDefaultConfiguration()
{
- CollarType = new(ShockCollarType.OpenShock);
- Words = new([]);
+ CollarType.Value = ShockCollarType.OpenShock;
+ Words.Value = [];
}
}
@@ -33,5 +33,6 @@ public class WordRecognition
{
public string Word { get; set; } = string.Empty;
public ShockType Type { get; set; }
- public float Delay { get; set; }
+ public float MinDelay { get; set; }
+ public float MaxDelay { get; set; }
}
diff --git a/OpenShock.VoiceRecognizer.Configuration/VoskConfigurationState.cs b/OpenShock.VoiceRecognizer.Configuration/VoskConfigurationState.cs
index 0e8488b..61ec930 100644
--- a/OpenShock.VoiceRecognizer.Configuration/VoskConfigurationState.cs
+++ b/OpenShock.VoiceRecognizer.Configuration/VoskConfigurationState.cs
@@ -15,5 +15,5 @@ public void LoadFileConfiguration(ConfigurationFileFormat configurationFileForma
ModelDirectory.Value = configurationFileFormat.VoskModelDirectory;
public void LoadDefaultConfiguration() =>
- ModelDirectory = new(AppDomain.CurrentDomain.BaseDirectory);
+ ModelDirectory.Value = AppDomain.CurrentDomain.BaseDirectory;
}
diff --git a/OpenShock.VoiceRecognizer.Integrations/BrowserProxy/BaseBrowserProxy.cs b/OpenShock.VoiceRecognizer.Integrations/BrowserProxy/BaseBrowserProxy.cs
new file mode 100644
index 0000000..5542de9
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Integrations/BrowserProxy/BaseBrowserProxy.cs
@@ -0,0 +1,28 @@
+using System.Net;
+
+namespace OpenShock.VoiceRecognizer.Integrations.BrowserProxy;
+
+public abstract class BaseBrowserProxy
+{
+ protected HttpListener? _listener = null;
+ protected Thread? _thread = null;
+ protected bool _shouldExit = false;
+ protected int _port = 0;
+ protected List _speechDetectionResults = [];
+ protected List _speechDetectionOnEnd = [];
+ protected List _pendingJavascript = [];
+
+ public BaseBrowserProxy() { }
+
+ public abstract void StartProxy(int port);
+
+ public abstract void StopProxy();
+
+ public abstract void DetectBrowser();
+
+ public abstract void CloseBrowser();
+
+ public void AddJavascriptCommand(string command) => _pendingJavascript.Add(command);
+
+ protected abstract void WorkerThread();
+}
diff --git a/OpenShock.VoiceRecognizer.Integrations/BrowserProxy/ChromeBrowserProxy.cs b/OpenShock.VoiceRecognizer.Integrations/BrowserProxy/ChromeBrowserProxy.cs
new file mode 100644
index 0000000..a0c7296
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Integrations/BrowserProxy/ChromeBrowserProxy.cs
@@ -0,0 +1,161 @@
+using System.Net;
+using System.Text;
+using System.Web;
+using NAudio.CoreAudioApi;
+
+namespace OpenShock.VoiceRecognizer.Integrations.BrowserProxy;
+
+public class ChromeBrowserProxy : BaseBrowserProxy
+{
+ public override void StartProxy(int port)
+ {
+ _port = port;
+ _listener = new();
+ _listener.Prefixes.Add($"http://*:{port}/");
+ _listener.Start();
+ _thread = new(new ThreadStart(WorkerThread));
+ _thread.Start();
+ }
+
+ public override void StopProxy()
+ {
+ try
+ {
+ _listener!.Abort();
+ }
+ catch (Exception) { }
+
+ try
+ {
+ _listener!.Stop();
+ }
+ catch(Exception) { }
+ }
+
+ public override void CloseBrowser()
+ {
+
+ }
+
+ public override void DetectBrowser()
+ {
+
+ }
+
+ protected override void WorkerThread()
+ {
+ while (!_shouldExit)
+ {
+ if (_listener is null)
+ {
+ Thread.Sleep(1000);
+ continue;
+ }
+
+ HttpListenerContext? context = null;
+ try
+ {
+ context = _listener!.GetContext();
+ string text = string.Empty;
+ string? contextUrlLocalPath = context!.Request?.Url?.LocalPath;
+ if (!string.IsNullOrEmpty(contextUrlLocalPath))
+ {
+ if (contextUrlLocalPath.EndsWith('/'))
+ {
+ _speechDetectionResults.Clear();
+ _speechDetectionOnEnd.Clear();
+ DetectBrowser();
+ byte[] bytes = [];
+ try
+ {
+ using FileStream stream = File.OpenRead("proxy.html");
+ using StreamReader reader = new(stream, Encoding.UTF8);
+ text = reader.ReadToEnd();
+ bytes = Encoding.UTF8.GetBytes(text);
+ text = Encoding.UTF8.GetString(bytes).Replace("__PROXY_PORT__", _port.ToString());
+ }
+ catch (Exception) { }
+ }
+ else if (contextUrlLocalPath.EndsWith("/crossdomain.xml"))
+ {
+ text = $"{Environment.NewLine}";
+ text += $"{Environment.NewLine}";
+ text += $"{Environment.NewLine}";
+ }
+ else if (contextUrlLocalPath.EndsWith("/ProxyData"))
+ {
+ DetectBrowser();
+ var message = HttpUtility.ParseQueryString(context!.Request?.Url?.Query ?? string.Empty)["message"];
+ if (!string.IsNullOrEmpty(message))
+ {
+ byte[] messageBytes = Convert.FromBase64String(message);
+ string @string = Encoding.UTF8.GetString(messageBytes);
+ //HandleProxyData(@string);
+ }
+ }
+ else if (contextUrlLocalPath.EndsWith("/CloseBrowserTab"))
+ {
+ CloseBrowser();
+ }
+ else if (contextUrlLocalPath.EndsWith("/CloseProxy"))
+ {
+ _shouldExit = true;
+ }
+ else if (contextUrlLocalPath.EndsWith("/OpenBrowserTab"))
+ {
+ // pending javascript
+ CloseBrowser();
+ }
+ else if (contextUrlLocalPath.EndsWith("/SetProxyPort"))
+ {
+ // do stuff
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionGetResult"))
+ {
+ if (_speechDetectionResults.Count > 0)
+ {
+ text = _speechDetectionResults.First();
+ _speechDetectionResults.RemoveAt(0);
+ }
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionInit"))
+ {
+ _speechDetectionResults.Clear();
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionStartRecognition"))
+ {
+ AddJavascriptCommand("WebGLSpeechDetectionPlugin.Start()");
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionStopRecognition"))
+ {
+ AddJavascriptCommand("WebGLSpeechDetectionPlugin.Stop()");
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionAbort"))
+ {
+ AddJavascriptCommand("WebGLSpeechDetectionPlugin.Abort()");
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionGetLanguages"))
+ {
+ AddJavascriptCommand("WebGLSpeechDetectionPlugin.GetLanguages()");
+ }
+ else if (contextUrlLocalPath.EndsWith("/SpeechDetectionSetLanguage"))
+ {
+ _speechDetectionResults.Clear();
+ string languageCode = HttpUtility.ParseQueryString(context.Request!.Url!.Query)["lang"]!;
+ if (languageCode is not null)
+ {
+ AddJavascriptCommand($"WebGLSpeechDetectionPlugin.SetLanguage(\"{languageCode}\")");
+ }
+ }
+ }
+
+ byte[] textBytes = Encoding.UTF8.GetBytes(text);
+ context.Response.ContentEncoding = Encoding.UTF8;
+ context.Response.AddHeader("ContentType", "utf8");
+ context.Response.OutputStream.Write(textBytes, 0, textBytes.Length);
+ context.Response.OutputStream.Flush();
+ }
+ catch (Exception) { }
+ }
+ }
+}
diff --git a/OpenShock.VoiceRecognizer.Integrations/OSC/OSCClient.cs b/OpenShock.VoiceRecognizer.Integrations/OSC/OSCClient.cs
new file mode 100644
index 0000000..75a548d
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Integrations/OSC/OSCClient.cs
@@ -0,0 +1,34 @@
+using BuildSoft.OscCore;
+using OpenShock.VoiceRecognizer.Common;
+using OpenShock.VoiceRecognizer.Configuration;
+
+namespace OpenShock.VoiceRecognizer.Integrations.OSC;
+
+public class OSCClient
+{
+ public OscClient? Client = null;
+
+ public OSCClient()
+ {
+ GenerateNewClient();
+ AttachHandlers();
+ }
+
+ private void AttachHandlers()
+ {
+ ConfigurationState.Instance!.OpenShock.SendHost.ValueChanged += OnSendHostChange;
+ ConfigurationState.Instance!.OpenShock.SendPort.ValueChanged += OnSendPortChanged;
+ }
+
+ private void OnSendHostChange(object? sender, ValueChangedEventArgs e) =>
+ GenerateNewClient();
+
+ private void OnSendPortChanged(object? _, ValueChangedEventArgs e) =>
+ GenerateNewClient();
+
+ private void GenerateNewClient() =>
+ Client = new(
+ ConfigurationState.Instance!.OpenShock.SendHost.Value,
+ ConfigurationState.Instance!.OpenShock.SendPort.Value
+ );
+}
diff --git a/OpenShock.VoiceRecognizer.Integrations/OSC/OSCServer.cs b/OpenShock.VoiceRecognizer.Integrations/OSC/OSCServer.cs
index c257664..b17e5bb 100644
--- a/OpenShock.VoiceRecognizer.Integrations/OSC/OSCServer.cs
+++ b/OpenShock.VoiceRecognizer.Integrations/OSC/OSCServer.cs
@@ -10,6 +10,7 @@ public class OSCServer
private OscServer? _server = null;
public event EventHandler? ToggleRecognizer;
public event EventHandler? SetRecognizer;
+ public event EventHandler? OscMessage;
public OSCServer()
{
@@ -29,6 +30,9 @@ private void AddServerMethods()
{
_server!.TryAddMethod("/recognizer/toggle", OnChangeRecognizerState);
_server!.TryAddMethod("/recognizer/set", OnSetRecognizerState);
+ _server!.AddMonitorCallback((BlobString endpoint, OscMessageValues values) =>
+ OscMessage?.Invoke(this, new OscMessageEventArgs(endpoint.ToString(), values))
+ );
}
private void OnListenPortChanged(object? sender, ValueChangedEventArgs e) =>
@@ -53,3 +57,9 @@ public class RecognizerSetEventArgs(bool state) : EventArgs
{
public bool State { get; private set; } = state;
}
+
+public class OscMessageEventArgs(string endpoint, OscMessageValues values) : EventArgs
+{
+ public string Endpoint { get; private set; } = endpoint;
+ public OscMessageValues Values { get; private set; } = values;
+}
diff --git a/OpenShock.VoiceRecognizer.Integrations/OpenShock.VoiceRecognizer.Integrations.csproj b/OpenShock.VoiceRecognizer.Integrations/OpenShock.VoiceRecognizer.Integrations.csproj
index 502f80f..5e50ba1 100644
--- a/OpenShock.VoiceRecognizer.Integrations/OpenShock.VoiceRecognizer.Integrations.csproj
+++ b/OpenShock.VoiceRecognizer.Integrations/OpenShock.VoiceRecognizer.Integrations.csproj
@@ -8,6 +8,8 @@
+
+
diff --git a/OpenShock.VoiceRecognizer.Integrations/OpenShock/OpenShockAPI.cs b/OpenShock.VoiceRecognizer.Integrations/OpenShock/OpenShockAPI.cs
new file mode 100644
index 0000000..8135432
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Integrations/OpenShock/OpenShockAPI.cs
@@ -0,0 +1,52 @@
+using OpenShock.SDK.CSharp;
+using OpenShock.SDK.CSharp.Models;
+using OpenShock.VoiceRecognizer.Common;
+using OpenShock.VoiceRecognizer.Configuration;
+
+namespace OpenShock.VoiceRecognizer.Integrations.OpenShock;
+
+public class OpenShockAPI
+{
+ public OpenShockApiClient? Client { get; private set; } = null;
+
+ public OpenShockAPI()
+ {
+ GenerateNewClient();
+ AttachHandlers();
+ }
+
+ public async Task> GetShockers()
+ {
+ var shockerList = new List();
+ var shockers = await Client.GetOwnShockers();
+ if (shockers.IsT0)
+ {
+ foreach (var shockerCollection in shockers.AsT0.Value)
+ {
+ shockerList.AddRange(shockerCollection.Shockers);
+ }
+ }
+
+ return shockerList;
+ }
+
+ public async Task GetDeviceGateway()
+ {
+
+ }
+
+ private void AttachHandlers() { }
+ //ConfigurationState.Instance!.OpenShock.APIKey.ValueChanged += OnAPIKeyChanged;
+
+ //private void OnAPIKeyChanged(object? sender, ValueChangedEventArgs e) =>
+ // GenerateNewClient();
+
+ private void GenerateNewClient()
+ {
+ /*var apiKey = ConfigurationState.Instance!.OpenShock.APIKey.Value;
+ if (!string.IsNullOrEmpty(apiKey))
+ {
+ Client = new(new ApiClientOptions { Token = apiKey });
+ }*/
+ }
+}
diff --git a/OpenShock.VoiceRecognizer.NGramRecognizer/NGramRecognizer.cs b/OpenShock.VoiceRecognizer.NGramRecognizer/NGramRecognizer.cs
index 07255f1..0610f07 100644
--- a/OpenShock.VoiceRecognizer.NGramRecognizer/NGramRecognizer.cs
+++ b/OpenShock.VoiceRecognizer.NGramRecognizer/NGramRecognizer.cs
@@ -1,5 +1,4 @@
using System.Collections.ObjectModel;
-using OpenShock.VoiceRecognizer.Common.Enums;
using OpenShock.VoiceRecognizer.Configuration;
namespace OpenShock.VoiceRecognizer.NGramRecognizer;
@@ -12,7 +11,7 @@ public static class NGramRecognizer
foreach (var word in words)
{
- if (recognizedSpeech.Contains(word.Word) && (int?)result?.Type < (int)word.Type)
+ if (recognizedSpeech.Contains(word.Word) && (result?.Type is null || (int?)result?.Type < (int)word.Type))
{
result = word;
}
diff --git a/OpenShock.VoiceRecognizer.STT/BaseRecognizer.cs b/OpenShock.VoiceRecognizer.STT/BaseRecognizer.cs
index 81fb239..53291f4 100644
--- a/OpenShock.VoiceRecognizer.STT/BaseRecognizer.cs
+++ b/OpenShock.VoiceRecognizer.STT/BaseRecognizer.cs
@@ -1,6 +1,7 @@
using OpenShock.VoiceRecognizer.Configuration;
using OpenShock.VoiceRecognizer.Common;
-using OpenShock.VoiceRecognizer.NGramRecognizer;
+using OpenShock.VoiceRecognizer.Integrations.OSC;
+using OpenShock.VoiceRecognizer.Shockers;
namespace OpenShock.VoiceRecognizer.STT;
@@ -10,6 +11,9 @@ public abstract class BaseRecognizer : IDisposable
public event EventHandler? StateChanged;
public event EventHandler? RecognizedSpeech;
+ protected OSCServer _server;
+ protected OpenShockShocker _shocker;
+
///
/// Specifies if the Recognizer is currently listening
/// to the Input device.
@@ -22,8 +26,10 @@ public abstract class BaseRecognizer : IDisposable
///
public bool Stopped { get; protected set; }
- public BaseRecognizer()
+ public BaseRecognizer(OSCServer server)
{
+ _shocker = new OpenShockShocker(server);
+ _server = server;
Paused = false;
Stopped = true;
ConfigurationState.Instance!.Audio.InputDeviceID.ValueChanged += DeviceChanged;
@@ -64,7 +70,8 @@ protected void OnRecognizedSpeech(string text)
if (recognized is not null)
{
- switch (recognized.Type)
+ _shocker.HandleRecognizedWord(recognized);
+ /*switch (recognized.Type)
{
case Utility.Common.ShockType.Vibrate:
break;
@@ -72,8 +79,7 @@ protected void OnRecognizedSpeech(string text)
break;
case Utility.Common.ShockType.VibrateThenShock:
break;
-
- }
+ }*/
}
}
@@ -98,12 +104,7 @@ protected void DeviceChanged(object? _, ValueChangedEventArgs e) =>
public abstract void Dispose();
}
-public class RecognizedSpeechEventArgs
+public class RecognizedSpeechEventArgs(string text)
{
- public string Text { get; }
-
- public RecognizedSpeechEventArgs(string text)
- {
- Text = text;
- }
+ public string Text { get; } = text;
}
diff --git a/OpenShock.VoiceRecognizer.STT/OpenShock.VoiceRecognizer.STT.csproj b/OpenShock.VoiceRecognizer.STT/OpenShock.VoiceRecognizer.STT.csproj
index 2d1dbb8..67dd340 100644
--- a/OpenShock.VoiceRecognizer.STT/OpenShock.VoiceRecognizer.STT.csproj
+++ b/OpenShock.VoiceRecognizer.STT/OpenShock.VoiceRecognizer.STT.csproj
@@ -9,7 +9,9 @@
+
+
diff --git a/OpenShock.VoiceRecognizer.STT/VoskRecognizer.cs b/OpenShock.VoiceRecognizer.STT/VoskRecognizer.cs
index 0385e3e..adb1137 100644
--- a/OpenShock.VoiceRecognizer.STT/VoskRecognizer.cs
+++ b/OpenShock.VoiceRecognizer.STT/VoskRecognizer.cs
@@ -5,6 +5,7 @@
using OpenShock.VoiceRecognizer.Configuration;
using OpenShock.VoiceRecognizer.Common.Audio;
using Vosk;
+using OpenShock.VoiceRecognizer.Integrations.OSC;
namespace OpenShock.VoiceRecognizer.STT;
@@ -14,7 +15,7 @@ public class VoskSpeechRecognizer : BaseRecognizer
private VoskRecognizer? _recognizer;
private WasapiCapture? _capture;
- public VoskSpeechRecognizer() : base()
+ public VoskSpeechRecognizer(OSCServer server) : base(server)
{
AttachEventHandlers();
}
diff --git a/OpenShock.VoiceRecognizer.Shockers/BaseShocker.cs b/OpenShock.VoiceRecognizer.Shockers/BaseShocker.cs
new file mode 100644
index 0000000..98bc2db
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Shockers/BaseShocker.cs
@@ -0,0 +1,24 @@
+using OpenShock.VoiceRecognizer.Configuration;
+using OpenShock.VoiceRecognizer.Integrations.OSC;
+
+namespace OpenShock.VoiceRecognizer.Shockers;
+
+public abstract class BaseShocker : IDisposable
+{
+ protected readonly OSCServer _server;
+
+ public BaseShocker(OSCServer server)
+ {
+ _server = server;
+ }
+
+ protected abstract void OnOscMessageReceived(object? sender, OscMessageEventArgs e);
+
+ public abstract void HandleRecognizedWord(WordRecognition recognized);
+
+ protected abstract void HandleVibrate();
+
+ protected abstract void HandleShock();
+
+ public abstract void Dispose();
+}
diff --git a/OpenShock.VoiceRecognizer.Shockers/OpenShock.VoiceRecognizer.Shockers.csproj b/OpenShock.VoiceRecognizer.Shockers/OpenShock.VoiceRecognizer.Shockers.csproj
new file mode 100644
index 0000000..e05ba41
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Shockers/OpenShock.VoiceRecognizer.Shockers.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/OpenShock.VoiceRecognizer.Shockers/OpenShockShocker.cs b/OpenShock.VoiceRecognizer.Shockers/OpenShockShocker.cs
new file mode 100644
index 0000000..6a2b71c
--- /dev/null
+++ b/OpenShock.VoiceRecognizer.Shockers/OpenShockShocker.cs
@@ -0,0 +1,79 @@
+using OpenShock.VoiceRecognizer.Configuration;
+using OpenShock.VoiceRecognizer.Integrations.OSC;
+using OpenShock.VoiceRecognizer.Utility.Common;
+
+namespace OpenShock.VoiceRecognizer.Shockers;
+
+public class OpenShockShocker : BaseShocker
+{
+ // goes 1 to 10 - anna
+ private float _externalSetIntensity = 0.0f;
+ private readonly OSCClient _client;
+
+ public OpenShockShocker(OSCServer server) : base(server)
+ {
+ _client = new();
+ AttachHandlers();
+ }
+
+ private void AttachHandlers() =>
+ _server.OscMessage += OnOscMessageReceived;
+
+ protected override void OnOscMessageReceived(object? sender, OscMessageEventArgs e)
+ {
+ if (e.Endpoint.Equals(ConfigurationState.Instance!.OpenShock.ExternalListenSetIntensityEndpoint.Value))
+ {
+ try
+ {
+ _externalSetIntensity = e.Values.ReadFloatElement(0);
+ }
+ catch (Exception) { }
+ }
+ }
+
+ public override async void HandleRecognizedWord(WordRecognition recognized)
+ {
+ switch (recognized.Type)
+ {
+ case ShockType.Vibrate:
+ HandleVibrate();
+ break;
+ case ShockType.Shock:
+ HandleShock();
+ break;
+ case ShockType.VibrateThenShock:
+ HandleVibrate();
+ var delay = (new Random().NextSingle() * (recognized.MaxDelay - recognized.MinDelay)) + recognized.MinDelay;
+ await TaskDelay(delay).ConfigureAwait(false);
+ HandleShock();
+ break;
+ }
+ }
+
+ private static async Task TaskDelay(float seconds)
+ {
+ var ms = Convert.ToInt32(Math.Truncate(seconds * 1000));
+ await Task.Delay(ms).ConfigureAwait(false);
+ }
+
+ protected override void HandleShock()
+ {
+ _client.Client?.Send(
+ $"{ConfigurationState.Instance!.OpenShock.ExternalSendStartShockEndpoint.Value}",
+ true
+ );
+ }
+
+ protected override void HandleVibrate()
+ {
+ _client.Client?.Send(
+ $"{ConfigurationState.Instance!.OpenShock.ExternalSendStartVibrationEndpoint.Value}",
+ true
+ );
+ }
+
+ public override void Dispose()
+ {
+
+ }
+}
diff --git a/OpenShock.VoiceRecognizer.sln b/OpenShock.VoiceRecognizer.sln
index a6238ef..8e2c95c 100644
--- a/OpenShock.VoiceRecognizer.sln
+++ b/OpenShock.VoiceRecognizer.sln
@@ -26,6 +26,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenShock.VoiceRecognizer.S
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenShock.VoiceRecognizer.NGramRecognizer", "OpenShock.VoiceRecognizer.NGramRecognizer\OpenShock.VoiceRecognizer.NGramRecognizer.csproj", "{4DC9F43A-2783-4829-AC1F-27904F60E6A5}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenShock.VoiceRecognizer.Shockers", "OpenShock.VoiceRecognizer.Shockers\OpenShock.VoiceRecognizer.Shockers.csproj", "{A1EF76BD-C3CF-4883-B158-296B02AAF8D5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -60,6 +62,10 @@ Global
{4DC9F43A-2783-4829-AC1F-27904F60E6A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DC9F43A-2783-4829-AC1F-27904F60E6A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DC9F43A-2783-4829-AC1F-27904F60E6A5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A1EF76BD-C3CF-4883-B158-296B02AAF8D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A1EF76BD-C3CF-4883-B158-296B02AAF8D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A1EF76BD-C3CF-4883-B158-296B02AAF8D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A1EF76BD-C3CF-4883-B158-296B02AAF8D5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/OpenShock.VoiceRecognizer/Assets/Proxies/browserproxy.html b/OpenShock.VoiceRecognizer/Assets/Proxies/browserproxy.html
new file mode 100644
index 0000000..2418e82
--- /dev/null
+++ b/OpenShock.VoiceRecognizer/Assets/Proxies/browserproxy.html
@@ -0,0 +1,877 @@
+
+
+ Speech Proxy
+
+
+ Please do not close this tab whilst OVR Toolkit is open! This is used for speech recognition.
+
+
+
+
+
+
diff --git a/OpenShock.VoiceRecognizer/UI/ViewModels/MainModelViewModel.cs b/OpenShock.VoiceRecognizer/UI/ViewModels/MainModelViewModel.cs
index e78ba75..5493cc3 100644
--- a/OpenShock.VoiceRecognizer/UI/ViewModels/MainModelViewModel.cs
+++ b/OpenShock.VoiceRecognizer/UI/ViewModels/MainModelViewModel.cs
@@ -32,7 +32,7 @@ public MainModelViewModel()
private void SelectRecognizer()
{
- BaseSpeechRecognizer = new VoskSpeechRecognizer();
+ BaseSpeechRecognizer = new VoskSpeechRecognizer(_oscServer);
BaseSpeechRecognizer.RecognizedSpeech += OnRecognizedSpeech;
BaseSpeechRecognizer.StateChanged += OnRecognizerStateChanged;
}
diff --git a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsGeneralViewModel.cs b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsGeneralViewModel.cs
index 57fb069..9dcf95e 100644
--- a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsGeneralViewModel.cs
+++ b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsGeneralViewModel.cs
@@ -1,6 +1,7 @@
using OpenShock.VoiceRecognizer.Common.Audio;
using OpenShock.VoiceRecognizer.Common.Enums;
using OpenShock.VoiceRecognizer.Configuration;
+using OpenShock.VoiceRecognizer.UI.ViewModels.Enums;
namespace OpenShock.VoiceRecognizer.UI.ViewModels.Settings;
@@ -8,6 +9,7 @@ public class SettingsGeneralViewModel : BaseViewModel
{
public AudioDeviceSelectorViewModel InputDeviceSelectorVM { get; }
public NumberInputViewModel ListenPortSelectorVM { get; }
+ public ShockCollarTypeSelectorViewModel ShockCollarTypeSelectorVM { get; }
public SettingsGeneralViewModel()
{
@@ -22,6 +24,11 @@ public SettingsGeneralViewModel()
ConfigurationState.Instance!.OSC.ListenPort.Value
);
+ ShockCollarTypeSelectorVM = new(
+ "Shock Collar Type",
+ ConfigurationState.Instance!.Shock.CollarType.Value
+ );
+
AttachEventHandlers();
}
@@ -29,6 +36,7 @@ private void AttachEventHandlers()
{
InputDeviceSelectorVM.DeviceChanged += AudioDeviceChanged;
ListenPortSelectorVM.NumberValueChanged += ListenPortChanged;
+ ShockCollarTypeSelectorVM.EnumChanged += ShockCollarTypeChanged;
}
private void AudioDeviceChanged(object? sender, AudioDeviceChangedEventArgs e)
@@ -43,4 +51,7 @@ private void AudioDeviceChanged(object? sender, AudioDeviceChangedEventArgs e)
private void ListenPortChanged(object? sender, NumberValueChangedEventArgs e) =>
ConfigurationState.Instance!.OSC.ListenPort.Value = e.Value;
+
+ private void ShockCollarTypeChanged(object? sender, EnumChangedEventArgs e) =>
+ ConfigurationState.Instance!.Shock.CollarType.Value = e.Value;
}
diff --git a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsOpenShockViewModel.cs b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsOpenShockViewModel.cs
new file mode 100644
index 0000000..39c6d37
--- /dev/null
+++ b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsOpenShockViewModel.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OpenShock.VoiceRecognizer.Configuration;
+
+namespace OpenShock.VoiceRecognizer.UI.ViewModels.Settings;
+
+public class SettingsOpenShockViewModel : BaseViewModel
+{
+ public StringInputViewModel SendHostSelectorVM { get; set; }
+ public NumberInputViewModel SendPortSelectorVM { get; set; }
+ public StringInputViewModel ListenIntensityEndpointSelectorVM { get; set; }
+ public StringInputViewModel SendShockEndpointSelectorVM { get; set; }
+ public StringInputViewModel SendVibrateEndpointSelectorVM { get; set; }
+
+ public SettingsOpenShockViewModel()
+ {
+ SendHostSelectorVM = new(
+ "Host",
+ ConfigurationState.Instance!.OpenShock.SendHost.Value
+ );
+ SendPortSelectorVM = new(
+ "Port",
+ ConfigurationState.Instance!.OpenShock.SendPort.Value
+ );
+ ListenIntensityEndpointSelectorVM = new(
+ "Intensity Listen Endpoint",
+ ConfigurationState.Instance!.OpenShock.ExternalListenSetIntensityEndpoint.Value
+ );
+ SendShockEndpointSelectorVM = new(
+ "Send Shock Endpoint",
+ ConfigurationState.Instance!.OpenShock.ExternalSendStartShockEndpoint.Value
+ );
+ SendVibrateEndpointSelectorVM = new(
+ "Send Vibrate Endpoint",
+ ConfigurationState.Instance!.OpenShock.ExternalSendStartVibrationEndpoint.Value
+ );
+
+ AttachEventHandlers();
+ }
+
+ private void AttachEventHandlers()
+ {
+ SendHostSelectorVM.PropertyChanged += OnSendHostChanged;
+ SendPortSelectorVM.PropertyChanged += OnSendPortChanged;
+ ListenIntensityEndpointSelectorVM.PropertyChanged += OnListenIntensityEndpointChanged;
+ SendShockEndpointSelectorVM.PropertyChanged += OnSendShockEndpointChanged;
+ SendVibrateEndpointSelectorVM.PropertyChanged += OnSendVibrateEndpointChanged;
+ }
+
+ private void OnSendHostChanged(object? sender, PropertyChangedEventArgs e)
+ => ConfigurationState.Instance!.OpenShock.SendHost.Value = SendHostSelectorVM.Text!;
+
+ private void OnSendPortChanged(object? sender, PropertyChangedEventArgs e)
+ => ConfigurationState.Instance!.OpenShock.SendPort.Value = SendPortSelectorVM.Value!;
+
+ private void OnListenIntensityEndpointChanged(object? sender, PropertyChangedEventArgs e)
+ => ConfigurationState.Instance!.OpenShock.ExternalListenSetIntensityEndpoint.Value = ListenIntensityEndpointSelectorVM.Text!;
+
+ private void OnSendShockEndpointChanged(object? sender, PropertyChangedEventArgs e)
+ => ConfigurationState.Instance!.OpenShock.ExternalSendStartShockEndpoint.Value = SendShockEndpointSelectorVM.Text!;
+
+ private void OnSendVibrateEndpointChanged(object? sender, PropertyChangedEventArgs e)
+ => ConfigurationState.Instance!.OpenShock.ExternalSendStartVibrationEndpoint.Value = SendVibrateEndpointSelectorVM.Text!;
+}
diff --git a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsWindowViewModel.cs b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsWindowViewModel.cs
index 66ee10b..f8f8bb5 100644
--- a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsWindowViewModel.cs
+++ b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsWindowViewModel.cs
@@ -10,12 +10,14 @@ public class SettingsWindowViewModel
public SettingsGeneralViewModel GeneralVM { get; }
public SettingsVoskModelViewModel VoskVM { get; }
public SettingsZapViewModel ZapVM { get; }
+ public SettingsOpenShockViewModel OpenShockVM { get; }
public SettingsWindowViewModel()
{
GeneralVM = new();
VoskVM = new();
ZapVM = new();
+ OpenShockVM = new();
}
public void SaveSettings()
diff --git a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsZapViewModel.cs b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsZapViewModel.cs
index 815bd98..70fcd29 100644
--- a/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsZapViewModel.cs
+++ b/OpenShock.VoiceRecognizer/UI/ViewModels/Settings/SettingsZapViewModel.cs
@@ -13,7 +13,8 @@ public class SettingsZapViewModel : BaseViewModel
public StringInputViewModel TextInputVM { get; set; }
public ShockTypeSelectorViewModel ShockTypeSelectorVM { get; set; }
- public NumberInputViewModel DelayInputVM { get; set; }
+ public NumberInputViewModel MinDelayInputVM { get; set; }
+ public NumberInputViewModel MaxDelayInputVM { get; set; }
public SettingsZapViewModel()
{
@@ -21,11 +22,13 @@ public SettingsZapViewModel()
Words = ConfigurationState.Instance!.Shock.Words.Value;
InputText = string.Empty;
ShockType = ShockType.VibrateThenShock;
- Delay = 0.0f;
+ MinDelay = 0.0f;
+ MaxDelay = 0.0f;
TextInputVM = new("Text", string.Empty);
ShockTypeSelectorVM = new("Shock Type", ShockType);
- DelayInputVM = new("Delay", 0);
+ MinDelayInputVM = new("Minimum Delay (seconds)", 0);
+ MaxDelayInputVM = new("Maximum Delay (seconds)", 0);
AttachHandlers();
}
@@ -34,15 +37,18 @@ private void AttachHandlers()
{
TextInputVM.PropertyChanged += OnTextInputChanged;
ShockTypeSelectorVM.EnumChanged += OnShockTypeSelected;
- DelayInputVM.PropertyChanged += OnDelayInputChanged;
+ MinDelayInputVM.PropertyChanged += OnMinDelayInputChanged;
+ MaxDelayInputVM.PropertyChanged += OnMaxDelayInputChanged;
}
private void OnTextInputChanged(object? sender, EventArgs e) =>
InputText = TextInputVM.Text ?? string.Empty;
private void OnShockTypeSelected(object? sender, EnumChangedEventArgs e) =>
ShockType = e.Value;
- private void OnDelayInputChanged(object? sender, EventArgs e) =>
- Delay = DelayInputVM.Value;
+ private void OnMinDelayInputChanged(object? sender, EventArgs e) =>
+ MinDelay = MinDelayInputVM.Value;
+ private void OnMaxDelayInputChanged(object? sender, EventArgs e) =>
+ MaxDelay = MaxDelayInputVM.Value;
public int SelectedWordIndex
{
@@ -57,7 +63,8 @@ public int SelectedWordIndex
public string InputText { get; set; }
public ShockType ShockType { get; set; }
- public float Delay { get; set; }
+ public float MinDelay { get; set; }
+ public float MaxDelay { get; set; }
public bool HasSelectedWord => SelectedWordIndex <= Words.Count && SelectedWordIndex > -1;
}
diff --git a/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsGeneralView.axaml b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsGeneralView.axaml
index 46bf24b..4c631b0 100644
--- a/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsGeneralView.axaml
+++ b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsGeneralView.axaml
@@ -6,6 +6,7 @@
mc:Ignorable="d"
xmlns:vm="using:OpenShock.VoiceRecognizer.UI.ViewModels.Settings"
xmlns:views="using:OpenShock.VoiceRecognizer.UI.Views"
+ xmlns:enumViews="using:OpenShock.VoiceRecognizer.UI.Views.Enums"
x:DataType="vm:SettingsGeneralViewModel">
+
diff --git a/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsOpenShockView.axaml b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsOpenShockView.axaml
new file mode 100644
index 0000000..b56cc63
--- /dev/null
+++ b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsOpenShockView.axaml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsOpenShockView.axaml.cs b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsOpenShockView.axaml.cs
new file mode 100644
index 0000000..0324397
--- /dev/null
+++ b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsOpenShockView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace OpenShock.VoiceRecognizer.UI.Views.Settings;
+
+public partial class SettingsOpenShockView : UserControl
+{
+ public SettingsOpenShockView()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsZapView.axaml b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsZapView.axaml
index ef83c70..7b5da7c 100644
--- a/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsZapView.axaml
+++ b/OpenShock.VoiceRecognizer/UI/Views/Settings/SettingsZapView.axaml
@@ -54,7 +54,10 @@
-
+
+
+
+
w.Word.Contains(word)))
{
@@ -27,7 +28,8 @@ private void WordAddClicked(object? sender, RoutedEventArgs e)
{
Word = word,
Type = shockType,
- Delay = delay,
+ MinDelay = minDelay,
+ MaxDelay = maxDelay,
});
ConfigurationState.Instance!.Shock.Words.Value = words;
}
diff --git a/OpenShock.VoiceRecognizer/UI/Windows/SettingsWindow.axaml b/OpenShock.VoiceRecognizer/UI/Windows/SettingsWindow.axaml
index e19484a..04a3982 100644
--- a/OpenShock.VoiceRecognizer/UI/Windows/SettingsWindow.axaml
+++ b/OpenShock.VoiceRecognizer/UI/Windows/SettingsWindow.axaml
@@ -33,6 +33,7 @@
+
+
GeneralPage,
"VoskPage" => VoskPage,
"ZapPage" => ZapPage,
+ "OpenShockPage" => OpenShockPage,
_ => throw new NotImplementedException(),
};
}