diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/KeyboardAudioVisualizer.sln b/KeyboardAudioVisualizer.sln
new file mode 100644
index 0000000..d69b599
--- /dev/null
+++ b/KeyboardAudioVisualizer.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.15
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyboardAudioVisualizer", "KeyboardAudioVisualizer\KeyboardAudioVisualizer.csproj", "{0AC4E8B1-4D4D-447F-B9FD-38A74ED1F243}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0AC4E8B1-4D4D-447F-B9FD-38A74ED1F243}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AC4E8B1-4D4D-447F-B9FD-38A74ED1F243}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AC4E8B1-4D4D-447F-B9FD-38A74ED1F243}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0AC4E8B1-4D4D-447F-B9FD-38A74ED1F243}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/KeyboardAudioVisualizer/App.config b/KeyboardAudioVisualizer/App.config
new file mode 100644
index 0000000..731f6de
--- /dev/null
+++ b/KeyboardAudioVisualizer/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/App.xaml b/KeyboardAudioVisualizer/App.xaml
new file mode 100644
index 0000000..083b6f0
--- /dev/null
+++ b/KeyboardAudioVisualizer/App.xaml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeyboardAudioVisualizer/App.xaml.cs b/KeyboardAudioVisualizer/App.xaml.cs
new file mode 100644
index 0000000..b154184
--- /dev/null
+++ b/KeyboardAudioVisualizer/App.xaml.cs
@@ -0,0 +1,62 @@
+using System;
+using System.IO;
+using System.Windows;
+using Hardcodet.Wpf.TaskbarNotification;
+using KeyboardAudioVisualizer.Helper;
+
+namespace KeyboardAudioVisualizer
+{
+ public partial class App : Application
+ {
+ #region Constants
+
+ private const string PATH_SETTINGS = "Settings.xaml";
+
+ #endregion
+
+ #region Properties & Fields
+
+ private TaskbarIcon _taskbarIcon;
+
+ #endregion
+
+ #region Constructors
+
+ #endregion
+
+ #region Methods
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ base.OnStartup(e);
+
+ try
+ {
+ _taskbarIcon = (TaskbarIcon)FindResource("TaskbarIcon");
+
+ Settings settings = SerializationHelper.LoadObjectFromFile(PATH_SETTINGS);
+ if (settings == null)
+ {
+ settings = new Settings();
+ _taskbarIcon.ShowBalloonTip("Keyboard Audio-Visualizer is starting in the tray!", "Click on the icon to open the configuration.", BalloonIcon.Info);
+ }
+ ApplicationManager.Instance.Settings = settings;
+ }
+ catch (Exception ex)
+ {
+ File.WriteAllText("error.log", $"[{DateTime.Now:G}] Exception!\r\n\r\nMessage:\r\n{ex.GetFullMessage()}\r\n\r\nStackTrace:\r\n{ex.StackTrace}\r\n\r\n");
+ MessageBox.Show("An error occured while starting the Keyboard Audio-Visualizer.\r\nPlease double check if SDK-support for your devices is enabled.\r\nMore information can be found in the error.log file in the application directory.", "Can't start Keyboard Audio-Visualizer.");
+ Shutdown();
+ }
+ }
+
+ protected override void OnExit(ExitEventArgs e)
+ {
+ base.OnExit(e);
+
+ SerializationHelper.SaveObjectToFile(ApplicationManager.Instance.Settings, PATH_SETTINGS);
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/ApplicationManager.cs b/KeyboardAudioVisualizer/ApplicationManager.cs
new file mode 100644
index 0000000..ee7a083
--- /dev/null
+++ b/KeyboardAudioVisualizer/ApplicationManager.cs
@@ -0,0 +1,48 @@
+using System.Windows;
+using KeyboardAudioVisualizer.Helper;
+using KeyboardAudioVisualizer.UI;
+
+namespace KeyboardAudioVisualizer
+{
+ public class ApplicationManager
+ {
+ #region Properties & Fields
+
+ public static ApplicationManager Instance { get; } = new ApplicationManager();
+
+ private ConfigurationWindow _configurationWindow;
+
+ public Settings Settings { get; set; }
+
+ #endregion
+
+ #region Commands
+
+ private ActionCommand _openConfiguration;
+ public ActionCommand OpenConfigurationCommand => _openConfiguration ?? (_openConfiguration = new ActionCommand(OpenConfiguration));
+
+ private ActionCommand _exitCommand;
+ public ActionCommand ExitCommand => _exitCommand ?? (_exitCommand = new ActionCommand(Exit));
+
+ #endregion
+
+ #region Constructors
+
+ private ApplicationManager()
+ { }
+
+ #endregion
+
+ #region Methods
+
+ private void OpenConfiguration()
+ {
+ if (_configurationWindow == null) _configurationWindow = new ConfigurationWindow();
+ _configurationWindow.Show();
+ }
+
+ private void Exit() => Application.Current.Shutdown();
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Controls/BlurredDecorationWindow.cs b/KeyboardAudioVisualizer/Controls/BlurredDecorationWindow.cs
new file mode 100644
index 0000000..649ccac
--- /dev/null
+++ b/KeyboardAudioVisualizer/Controls/BlurredDecorationWindow.cs
@@ -0,0 +1,91 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace KeyboardAudioVisualizer.Controls
+{
+ [TemplatePart(Name = "PART_Decoration", Type = typeof(FrameworkElement))]
+ [TemplatePart(Name = "PART_Content", Type = typeof(FrameworkElement))]
+ [TemplatePart(Name = "PART_CloseButton", Type = typeof(Button))]
+ [TemplatePart(Name = "PART_MinimizeButton", Type = typeof(Button))]
+ [TemplatePart(Name = "PART_IconButton", Type = typeof(Button))]
+ public class BlurredDecorationWindow : System.Windows.Window
+ {
+ #region DependencyProperties
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty BackgroundImageProperty = DependencyProperty.Register(
+ "BackgroundImage", typeof(ImageSource), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource BackgroundImage
+ {
+ get => (ImageSource)GetValue(BackgroundImageProperty);
+ set => SetValue(BackgroundImageProperty, value);
+ }
+
+ public static readonly DependencyProperty DecorationHeightProperty = DependencyProperty.Register(
+ "DecorationHeight", typeof(double), typeof(BlurredDecorationWindow), new PropertyMetadata(20.0));
+
+ public double DecorationHeight
+ {
+ get => (double)GetValue(DecorationHeightProperty);
+ set => SetValue(DecorationHeightProperty, value);
+ }
+
+ public static readonly DependencyProperty IconToolTipProperty = DependencyProperty.Register(
+ "IconToolTip", typeof(string), typeof(BlurredDecorationWindow), new PropertyMetadata(default(string)));
+
+ public string IconToolTip
+ {
+ get => (string)GetValue(IconToolTipProperty);
+ set => SetValue(IconToolTipProperty, value);
+ }
+
+ public static readonly DependencyProperty IconCommandProperty = DependencyProperty.Register(
+ "IconCommand", typeof(ICommand), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ICommand)));
+
+ public ICommand IconCommand
+ {
+ get => (ICommand)GetValue(IconCommandProperty);
+ set => SetValue(IconCommandProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Constructors
+
+ static BlurredDecorationWindow()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(BlurredDecorationWindow), new FrameworkPropertyMetadata(typeof(BlurredDecorationWindow)));
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ FrameworkElement decoration = GetTemplateChild("PART_Decoration") as FrameworkElement;
+ if (decoration != null)
+ decoration.MouseLeftButtonDown += (sender, args) => DragMove();
+
+ Button closeButton = GetTemplateChild("PART_CloseButton") as Button;
+ if (closeButton != null)
+ closeButton.Click += (sender, args) => Application.Current.Shutdown();
+
+ Button minimizeButton = GetTemplateChild("PART_MinimizeButton") as Button;
+ if (minimizeButton != null)
+ minimizeButton.Click += (sender, args) => Application.Current.MainWindow.WindowState = WindowState.Minimized;
+
+ Button iconButton = GetTemplateChild("PART_IconButton") as Button;
+ if (iconButton != null)
+ iconButton.Click += (sender, args) => IconCommand?.Execute(null);
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Controls/ImageButton.cs b/KeyboardAudioVisualizer/Controls/ImageButton.cs
new file mode 100644
index 0000000..184536a
--- /dev/null
+++ b/KeyboardAudioVisualizer/Controls/ImageButton.cs
@@ -0,0 +1,51 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace KeyboardAudioVisualizer.Controls
+{
+ public class ImageButton : Button
+ {
+ #region Properties & Fields
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
+ "Image", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource Image
+ {
+ get => (ImageSource)GetValue(ImageProperty);
+ set => SetValue(ImageProperty, value);
+ }
+
+ public static readonly DependencyProperty HoverImageProperty = DependencyProperty.Register(
+ "HoverImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource HoverImage
+ {
+ get => (ImageSource)GetValue(HoverImageProperty);
+ set => SetValue(HoverImageProperty, value);
+ }
+
+ public static readonly DependencyProperty PressedImageProperty = DependencyProperty.Register(
+ "PressedImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
+
+ public ImageSource PressedImage
+ {
+ get => (ImageSource)GetValue(PressedImageProperty);
+ set => SetValue(PressedImageProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Constructors
+
+ static ImageButton()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Helper/ActionCommand.cs b/KeyboardAudioVisualizer/Helper/ActionCommand.cs
new file mode 100644
index 0000000..1b6ee2a
--- /dev/null
+++ b/KeyboardAudioVisualizer/Helper/ActionCommand.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Windows.Input;
+
+namespace KeyboardAudioVisualizer.Helper
+{
+ public class ActionCommand : ICommand
+ {
+ #region Properties & Fields
+
+ private readonly Func _canExecute;
+ private readonly Action _command;
+
+ #endregion
+
+ #region Events
+
+ public event EventHandler CanExecuteChanged;
+
+ #endregion
+
+ #region Constructors
+
+ public ActionCommand(Action command, Func canExecute = null)
+ {
+ this._command = command;
+ this._canExecute = canExecute;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public bool CanExecute(object parameter)
+ {
+ return _canExecute?.Invoke() ?? true;
+ }
+
+ public void Execute(object parameter)
+ {
+ _command?.Invoke();
+ }
+
+ public void RaiseCanExecuteChanged()
+ {
+ CanExecuteChanged?.Invoke(this, new EventArgs());
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Helper/ExceptionExtension.cs b/KeyboardAudioVisualizer/Helper/ExceptionExtension.cs
new file mode 100644
index 0000000..1931e57
--- /dev/null
+++ b/KeyboardAudioVisualizer/Helper/ExceptionExtension.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace KeyboardAudioVisualizer.Helper
+{
+ public static class ExceptionExtension
+ {
+ #region Methods
+
+ public static string GetFullMessage(this Exception ex, string message = "")
+ {
+ if (ex == null) return string.Empty;
+
+ if (ex.InnerException != null)
+ message += "\r\nInnerException: " + GetFullMessage(ex.InnerException);
+
+ return message;
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Helper/SerializationHelper.cs b/KeyboardAudioVisualizer/Helper/SerializationHelper.cs
new file mode 100644
index 0000000..4b64b0c
--- /dev/null
+++ b/KeyboardAudioVisualizer/Helper/SerializationHelper.cs
@@ -0,0 +1,54 @@
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace KeyboardAudioVisualizer.Helper
+{
+ public static class SerializationHelper
+ {
+ #region Methods
+
+ public static void SaveObjectToFile(T serializableObject, string path)
+ {
+ if (serializableObject == null) return;
+
+ try
+ {
+ XmlDocument xmlDocument = new XmlDocument();
+ XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
+ using (MemoryStream stream = new MemoryStream())
+ {
+ serializer.Serialize(stream, serializableObject);
+ stream.Seek(0, SeekOrigin.Begin);
+ xmlDocument.Load(stream);
+ xmlDocument.Save(path);
+ }
+ }
+ catch {/* Catch'em all */}
+ }
+
+ public static T LoadObjectFromFile(string fileName)
+ {
+ if (string.IsNullOrEmpty(fileName)) return default(T);
+
+ try
+ {
+ XmlDocument xmlDocument = new XmlDocument();
+ xmlDocument.Load(fileName);
+ string xmlString = xmlDocument.OuterXml;
+
+ using (StringReader sr = new StringReader(xmlString))
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof(T));
+ using (XmlReader reader = new XmlTextReader(sr))
+ return (T)serializer.Deserialize(reader);
+ }
+ }
+ catch {/* Catch'em all */}
+
+ return default(T);
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj b/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
new file mode 100644
index 0000000..326dc9d
--- /dev/null
+++ b/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
@@ -0,0 +1,177 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {0AC4E8B1-4D4D-447F-B9FD-38A74ED1F243}
+ WinExe
+ KeyboardAudioVisualizer
+ KeyboardAudioVisualizer
+ v4.6.1
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ Resources\Icon.ico
+
+
+
+ ..\packages\CSCore.1.2.1.1\lib\net35-client\CSCore.dll
+
+
+ ..\packages\Hardcodet.NotifyIcon.Wpf.1.0.8\lib\net451\Hardcodet.Wpf.TaskbarNotification.dll
+
+
+ ..\packages\MathNet.Numerics.3.20.0\lib\net40\MathNet.Numerics.dll
+
+
+ ..\packages\RGB.NET.Brushes.1.0.0\lib\net45\RGB.NET.Brushes.dll
+
+
+ ..\packages\RGB.NET.Core.1.0.0\lib\net45\RGB.NET.Core.dll
+
+
+ ..\packages\RGB.NET.Devices.Corsair.1.0.0\lib\net45\RGB.NET.Devices.Corsair.dll
+
+
+ ..\packages\RGB.NET.Groups.1.0.0\lib\net45\RGB.NET.Groups.dll
+
+
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+
+
+
+
+
+
+
+ ConfigurationWindow.xaml
+
+
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/Properties/AssemblyInfo.cs b/KeyboardAudioVisualizer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..48fc08f
--- /dev/null
+++ b/KeyboardAudioVisualizer/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("KeyboardAudioVisualizer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("KeyboardAudioVisualizer")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/KeyboardAudioVisualizer/Properties/Resources.Designer.cs b/KeyboardAudioVisualizer/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..e690458
--- /dev/null
+++ b/KeyboardAudioVisualizer/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace KeyboardAudioVisualizer.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("KeyboardAudioVisualizer.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/KeyboardAudioVisualizer/Properties/Resources.resx b/KeyboardAudioVisualizer/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/KeyboardAudioVisualizer/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/Properties/Settings.Designer.cs b/KeyboardAudioVisualizer/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..bd09016
--- /dev/null
+++ b/KeyboardAudioVisualizer/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace KeyboardAudioVisualizer.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/KeyboardAudioVisualizer/Properties/Settings.settings b/KeyboardAudioVisualizer/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/KeyboardAudioVisualizer/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/Resources/Icon.ico b/KeyboardAudioVisualizer/Resources/Icon.ico
new file mode 100644
index 0000000..0f5afd2
Binary files /dev/null and b/KeyboardAudioVisualizer/Resources/Icon.ico differ
diff --git a/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml b/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
new file mode 100644
index 0000000..6342872
--- /dev/null
+++ b/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeyboardAudioVisualizer/Resources/background.png b/KeyboardAudioVisualizer/Resources/background.png
new file mode 100644
index 0000000..3ab6966
Binary files /dev/null and b/KeyboardAudioVisualizer/Resources/background.png differ
diff --git a/KeyboardAudioVisualizer/Resources/close.png b/KeyboardAudioVisualizer/Resources/close.png
new file mode 100644
index 0000000..e166bd7
Binary files /dev/null and b/KeyboardAudioVisualizer/Resources/close.png differ
diff --git a/KeyboardAudioVisualizer/Resources/font.ttf b/KeyboardAudioVisualizer/Resources/font.ttf
new file mode 100644
index 0000000..65d7240
Binary files /dev/null and b/KeyboardAudioVisualizer/Resources/font.ttf differ
diff --git a/KeyboardAudioVisualizer/Resources/minimize.png b/KeyboardAudioVisualizer/Resources/minimize.png
new file mode 100644
index 0000000..78910ae
Binary files /dev/null and b/KeyboardAudioVisualizer/Resources/minimize.png differ
diff --git a/KeyboardAudioVisualizer/Settings.cs b/KeyboardAudioVisualizer/Settings.cs
new file mode 100644
index 0000000..ed082f0
--- /dev/null
+++ b/KeyboardAudioVisualizer/Settings.cs
@@ -0,0 +1,6 @@
+namespace KeyboardAudioVisualizer
+{
+ public class Settings
+ {
+ }
+}
diff --git a/KeyboardAudioVisualizer/Styles/BlurredDecorationWindow.xaml b/KeyboardAudioVisualizer/Styles/BlurredDecorationWindow.xaml
new file mode 100644
index 0000000..1289637
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/BlurredDecorationWindow.xaml
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/Styles/CachedResourceDictionary.cs b/KeyboardAudioVisualizer/Styles/CachedResourceDictionary.cs
new file mode 100644
index 0000000..f476a96
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/CachedResourceDictionary.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Windows;
+
+namespace KeyboardAudioVisualizer.Styles
+{
+ public class CachedResourceDictionary : ResourceDictionary
+ {
+ #region Properties & Fields
+
+ // ReSharper disable InconsistentNaming
+ private static readonly List _cachedDictionaries = new List();
+ private static readonly ResourceDictionary _innerDictionary = new ResourceDictionary();
+ // ReSharper restore
+
+ public new Uri Source
+ {
+ get => null;
+ set
+ {
+ lock (_innerDictionary)
+ {
+ UpdateCache(value);
+
+ MergedDictionaries.Clear();
+ MergedDictionaries.Add(_innerDictionary);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ private static void UpdateCache(Uri source)
+ {
+ string uriPath = source.OriginalString;
+ if (_cachedDictionaries.Contains(uriPath)) return;
+
+ _cachedDictionaries.Add(uriPath);
+
+ ResourceDictionary newDictionary = new ResourceDictionary { Source = new Uri(uriPath, source.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative) };
+ CopyDictionaryEntries(newDictionary, _innerDictionary);
+ }
+
+ private static void CopyDictionaryEntries(IDictionary source, IDictionary target)
+ {
+ foreach (object key in source.Keys)
+ if (!target.Contains(key))
+ target.Add(key, source[key]);
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Styles/FrameworkElement.xaml b/KeyboardAudioVisualizer/Styles/FrameworkElement.xaml
new file mode 100644
index 0000000..557eeca
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/FrameworkElement.xaml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/KeyboardAudioVisualizer/Styles/ImageButton.xaml b/KeyboardAudioVisualizer/Styles/ImageButton.xaml
new file mode 100644
index 0000000..08f0250
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/ImageButton.xaml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/Styles/Theme.xaml b/KeyboardAudioVisualizer/Styles/Theme.xaml
new file mode 100644
index 0000000..d774c2b
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/Theme.xaml
@@ -0,0 +1,28 @@
+
+
+
+ #FFD0D0D0
+ #111111
+ #A0111111
+ #50000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 13
+ 14
+
diff --git a/KeyboardAudioVisualizer/Styles/ToolTip.xaml b/KeyboardAudioVisualizer/Styles/ToolTip.xaml
new file mode 100644
index 0000000..83f228d
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/ToolTip.xaml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs b/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs
new file mode 100644
index 0000000..437e377
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs
@@ -0,0 +1,29 @@
+using System.Diagnostics;
+using KeyboardAudioVisualizer.Helper;
+
+namespace KeyboardAudioVisualizer.UI
+{
+ public class ConfigurationViewModel
+ {
+ #region Properties & Fields
+
+ #endregion
+
+ #region Commands
+
+ private ActionCommand _openHomepageCommand;
+ public ActionCommand OpenHomepageCommand => _openHomepageCommand ?? (_openHomepageCommand = new ActionCommand(OpenHomepage));
+
+ #endregion
+
+ #region Constructors
+
+ #endregion
+
+ #region Methods
+
+ private void OpenHomepage() => Process.Start("https://github.com/DarthAffe/KeyboardAudioVisualizer");
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml b/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml
new file mode 100644
index 0000000..78a4f2c
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml.cs b/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml.cs
new file mode 100644
index 0000000..3fa71ce
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml.cs
@@ -0,0 +1,9 @@
+using KeyboardAudioVisualizer.Controls;
+
+namespace KeyboardAudioVisualizer.UI
+{
+ public partial class ConfigurationWindow : BlurredDecorationWindow
+ {
+ public ConfigurationWindow() => InitializeComponent();
+ }
+}
diff --git a/KeyboardAudioVisualizer/packages.config b/KeyboardAudioVisualizer/packages.config
new file mode 100644
index 0000000..4850754
--- /dev/null
+++ b/KeyboardAudioVisualizer/packages.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 0000000..c58398e
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+