diff --git a/KeyboardAudioVisualizer/App.config b/KeyboardAudioVisualizer/App.config
index 731f6de..7381577 100644
--- a/KeyboardAudioVisualizer/App.config
+++ b/KeyboardAudioVisualizer/App.config
@@ -1,6 +1,14 @@
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/ApplicationManager.cs b/KeyboardAudioVisualizer/ApplicationManager.cs
index bd6e9d8..ea612b1 100644
--- a/KeyboardAudioVisualizer/ApplicationManager.cs
+++ b/KeyboardAudioVisualizer/ApplicationManager.cs
@@ -91,12 +91,12 @@ namespace KeyboardAudioVisualizer
//new ListLedGroup(device).Brush = new BeatBrush(AudioProcessor.Instance.PrimaryVisualizationProvider, new Color(255, 255, 255));
//{
- // ILedGroup left = new RectangleLedGroup(new Rectangle(device.Location.X, device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
- // ILedGroup right = new RectangleLedGroup(new Rectangle(device.Location.X + (device.Size.Width / 2.0), device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
+ // ILedGroup left1 = new RectangleLedGroup(new Rectangle(device.Location.X, device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
+ // ILedGroup right1 = new RectangleLedGroup(new Rectangle(device.Location.X + (device.Size.Width / 2.0), device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
// IGradient levelGradient = new LinearGradient(new GradientStop(0, new Color(0, 0, 255)), new GradientStop(1, new Color(255, 0, 0)));
- // left.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Left, 0);
- // right.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Right, 1);
+ // left1.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Left, 0);
+ // right1.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, levelGradient, LevelBarDirection.Right, 1);
//}
break;
@@ -105,8 +105,14 @@ namespace KeyboardAudioVisualizer
ILedGroup right = new RectangleLedGroup(new Rectangle(device.Location.X + (device.Size.Width / 2.0), device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
IGradient mousematLevelGradient = new LinearGradient(new GradientStop(0, new Color(0, 0, 255)), new GradientStop(1, new Color(255, 0, 0)));
- left.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 0);
- right.Brush = new LevelBarBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 1);
+ left.Brush = new LevelBarBrush(AudioProcessor.Instance.TertiaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 0);
+ right.Brush = new LevelBarBrush(AudioProcessor.Instance.TertiaryVisualizationProvider, mousematLevelGradient, LevelBarDirection.Top, 1);
+ break;
+
+ case RGBDeviceType.Mouse:
+ case RGBDeviceType.Headset:
+ ILedGroup deviceGroup = new ListLedGroup(device);
+ deviceGroup.Brush = new BeatBrush(AudioProcessor.Instance.SecondaryVisualizationProvider, new Color(255, 255, 255));
break;
}
diff --git a/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs b/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs
index 2e12345..71661aa 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs
@@ -8,12 +8,6 @@ namespace KeyboardAudioVisualizer.AudioProcessing
{
public class AudioProcessor : IDisposable
{
- #region Constants
-
- private const int MAXIMUM_UPDATE_RATE = 40; // We won't allow to change the FPS beyond this
-
- #endregion
-
#region Properties & Fields
public static AudioProcessor Instance { get; private set; }
@@ -24,6 +18,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing
public IVisualizationProvider PrimaryVisualizationProvider { get; private set; }
public IVisualizationProvider SecondaryVisualizationProvider { get; private set; }
+ public IVisualizationProvider TertiaryVisualizationProvider { get; private set; }
#endregion
@@ -38,8 +33,10 @@ namespace KeyboardAudioVisualizer.AudioProcessing
public void Update()
{
_spectrumProvider.Update();
- PrimaryVisualizationProvider.Update();
- SecondaryVisualizationProvider.Update();
+
+ PrimaryVisualizationProvider?.Update();
+ SecondaryVisualizationProvider?.Update();
+ TertiaryVisualizationProvider?.Update();
}
public static void Initialize()
@@ -67,8 +64,11 @@ namespace KeyboardAudioVisualizer.AudioProcessing
//PrimaryVisualizationProvider = new BeatVisualizationProvider(new BeatVisualizationProviderConfiguration(), _spectrumProvider);
PrimaryVisualizationProvider.Initialize();
- SecondaryVisualizationProvider = new LevelVisualizationProvider(new LevelVisualizationProviderConfiguration(), _audioBuffer);
+ SecondaryVisualizationProvider = new BeatVisualizationProvider(new BeatVisualizationProviderConfiguration(), _spectrumProvider);
SecondaryVisualizationProvider.Initialize();
+
+ TertiaryVisualizationProvider = new LevelVisualizationProvider(new LevelVisualizationProviderConfiguration(), _audioBuffer);
+ TertiaryVisualizationProvider.Initialize();
}
public void Dispose() => _audioInput.Dispose();
diff --git a/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs b/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs
index 5d7f9b3..267eaa9 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs
@@ -12,14 +12,14 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
public class FrequencyBarsVisualizationProviderConfiguration : AbstractConfiguration
{
- private ValueMode _valueMode = ValueMode.Max;
+ private ValueMode _valueMode = ValueMode.Sum;
public ValueMode ValueMode
{
get => _valueMode;
set => SetProperty(ref _valueMode, value);
}
- private SpectrumMode _spectrumMode = SpectrumMode.Gamma;
+ private SpectrumMode _spectrumMode = SpectrumMode.Logarithmic;
public SpectrumMode SpectrumMode
{
get => _spectrumMode;
@@ -40,15 +40,15 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
set => SetProperty(ref _smoothing, value);
}
- private float _minFrequency = 60;
- public float MinFrequency
+ private double _minFrequency = 60;
+ public double MinFrequency
{
get => _minFrequency;
set => SetProperty(ref _minFrequency, value);
}
- private float _maxFrequency = 15000;
- public float MaxFrequency
+ private double _maxFrequency = 15000;
+ public double MaxFrequency
{
get => _maxFrequency;
set => SetProperty(ref _maxFrequency, value);
@@ -61,8 +61,8 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
set => SetProperty(ref _referenceLevel, value);
}
- private float _emphasisePeaks = 0.5f;
- public float EmphasisePeaks
+ private double _emphasisePeaks = 0.5f;
+ public double EmphasisePeaks
{
get => _emphasisePeaks;
set => SetProperty(ref _emphasisePeaks, value);
@@ -147,8 +147,11 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
if (_configuration.EmphasisePeaks > 0.001)
binPower = Math.Pow(binPower, 1 + _configuration.EmphasisePeaks) * _emphasiseFactor;
- VisualizationData[i] = (float)((VisualizationData[i] * _smoothingFactor) + (binPower * (1.0 - _smoothingFactor)));
- if (float.IsNaN(VisualizationData[i])) VisualizationData[i] = 0;
+ if (i < VisualizationData.Length)
+ {
+ VisualizationData[i] = (float)((VisualizationData[i] * _smoothingFactor) + (binPower * (1.0 - _smoothingFactor)));
+ if (float.IsNaN(VisualizationData[i])) VisualizationData[i] = 0;
+ }
}
}
@@ -157,11 +160,11 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
switch (_configuration.SpectrumMode)
{
case SpectrumMode.Gamma:
- return _spectrumProvider.GetGammaSpectrum(_configuration.Bars, _configuration.Gamma, _configuration.MinFrequency, _configuration.MaxFrequency);
+ return _spectrumProvider.GetGammaSpectrum(_configuration.Bars, _configuration.Gamma, (float)_configuration.MinFrequency, (float)_configuration.MaxFrequency);
case SpectrumMode.Logarithmic:
- return _spectrumProvider.GetLogarithmicSpectrum(_configuration.Bars, _configuration.MinFrequency, _configuration.MaxFrequency);
+ return _spectrumProvider.GetLogarithmicSpectrum(_configuration.Bars, (float)_configuration.MinFrequency, (float)_configuration.MaxFrequency);
case SpectrumMode.Linear:
- return _spectrumProvider.GetLinearSpectrum(_configuration.Bars, _configuration.MinFrequency, _configuration.MaxFrequency);
+ return _spectrumProvider.GetLinearSpectrum(_configuration.Bars, (float)_configuration.MinFrequency, (float)_configuration.MaxFrequency);
default:
return null;
}
diff --git a/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs b/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs
index fbb8554..f4d6c18 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs
@@ -2,6 +2,7 @@
using System.Linq;
using KeyboardAudioVisualizer.AudioCapture;
using KeyboardAudioVisualizer.Configuration;
+using KeyboardAudioVisualizer.Helper;
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
{
@@ -89,7 +90,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
private void RecalculateConfigValues(string changedPropertyName)
{
if ((changedPropertyName == null) || (changedPropertyName == nameof(LevelVisualizationProviderConfiguration.Smoothing)))
- _smoothingFactor = Math.Log10(_configuration.Smoothing);
+ _smoothingFactor = Math.Log10(MathHelper.Clamp(_configuration.Smoothing, 0.001, 9.5));
if ((changedPropertyName == null) || (changedPropertyName == nameof(LevelVisualizationProviderConfiguration.Scale))
|| (changedPropertyName == nameof(LevelVisualizationProviderConfiguration.ConversionMode)))
diff --git a/KeyboardAudioVisualizer/Configuration/IConfiguration.cs b/KeyboardAudioVisualizer/Configuration/IConfiguration.cs
index 87e3044..ac4755f 100644
--- a/KeyboardAudioVisualizer/Configuration/IConfiguration.cs
+++ b/KeyboardAudioVisualizer/Configuration/IConfiguration.cs
@@ -1,5 +1,7 @@
-namespace KeyboardAudioVisualizer.Configuration
+using System.ComponentModel;
+
+namespace KeyboardAudioVisualizer.Configuration
{
// DarthAffe 05.08.2017: Marker interface
- public interface IConfiguration { }
+ public interface IConfiguration : INotifyPropertyChanged { }
}
diff --git a/KeyboardAudioVisualizer/Controls/Formular.cs b/KeyboardAudioVisualizer/Controls/Formular.cs
index 5ef7148..ed82f12 100644
--- a/KeyboardAudioVisualizer/Controls/Formular.cs
+++ b/KeyboardAudioVisualizer/Controls/Formular.cs
@@ -77,6 +77,12 @@ namespace KeyboardAudioVisualizer.Controls
public static void SetRowSpan(DependencyObject element, int value) => element.SetValue(RowSpanProperty, value);
public static int GetRowSpan(DependencyObject element) => (int)element.GetValue(RowSpanProperty);
+ public static readonly DependencyProperty FillProperty = DependencyProperty.RegisterAttached("Fill", typeof(bool), typeof(Formular),
+ new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
+
+ public static void SetFill(DependencyObject element, bool value) => element.SetValue(FillProperty, value);
+ public static bool GetFill(DependencyObject element) => (bool)element.GetValue(FillProperty);
+
// ReSharper restore InconsistentNaming
#endregion
@@ -91,7 +97,7 @@ namespace KeyboardAudioVisualizer.Controls
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
- layout.AddElement(child);
+ layout.AddElement(child, 0);
}
return new Size(layout.Width, layout.Height);
@@ -104,9 +110,9 @@ namespace KeyboardAudioVisualizer.Controls
FormularLayout layout = new FormularLayout(RowHeight, LabelWidth, ElementSpacing, RowSpacing);
foreach (UIElement child in InternalChildren)
- child.Arrange(layout.AddElement(child));
+ child.Arrange(layout.AddElement(child, finalSize.Width));
- return new Size(layout.Width, layout.Height);
+ return new Size(finalSize.Width, layout.Height);
}
#endregion
@@ -146,7 +152,7 @@ namespace KeyboardAudioVisualizer.Controls
#region Methods
- public Rect AddElement(UIElement element)
+ public Rect AddElement(UIElement element, double targetWidth)
{
bool isLabel = GetIsLabel(element);
int lineBreaks = GetLineBreaks(element);
@@ -177,9 +183,13 @@ namespace KeyboardAudioVisualizer.Controls
if (element is FrameworkElement fe)
fe.MaxHeight = height;
- Rect rect = new Rect(new Point(_currentRowWidth, (_rows * _rowHeight) + (_rows * _rowSpacing)), new Size(elementWidth, height));
+ double width = elementWidth;
+ if ((targetWidth >= 1) && GetFill(element))
+ width = targetWidth - _currentRowWidth;
- _currentRowWidth += elementWidth + _elementSpacing;
+ Rect rect = new Rect(new Point(_currentRowWidth, (_rows * _rowHeight) + (_rows * _rowSpacing)), new Size(width, height));
+
+ _currentRowWidth += width + _elementSpacing;
return rect;
}
diff --git a/KeyboardAudioVisualizer/Converter/EqualsToBoolConverter.cs b/KeyboardAudioVisualizer/Converter/EqualsToBoolConverter.cs
new file mode 100644
index 0000000..3856734
--- /dev/null
+++ b/KeyboardAudioVisualizer/Converter/EqualsToBoolConverter.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace KeyboardAudioVisualizer.Converter
+{
+ [ValueConversion(typeof(object), typeof(bool))]
+ public class EqualsToBoolConverter : IValueConverter
+ {
+ #region Methods
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => Equals(value, parameter);
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj b/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
index 7270621..df90530 100644
--- a/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
+++ b/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
@@ -73,8 +73,8 @@
-
- ..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll
+
+ ..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll
@@ -129,6 +129,7 @@
+
@@ -140,6 +141,9 @@
ConfigurationWindow.xaml
+
+
+
@@ -191,6 +195,10 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
@@ -219,19 +227,37 @@
Designer
MSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
-
-
-
+
diff --git a/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml b/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
index 7e81dd1..dc8baaf 100644
--- a/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
+++ b/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
@@ -2,7 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:KeyboardAudioVisualizer.UI"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
- xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls">
+ xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
+ xmlns:converter="clr-namespace:KeyboardAudioVisualizer.Converter">
@@ -10,14 +11,18 @@
+
+
+
+
diff --git a/KeyboardAudioVisualizer/Styles/ComboBox.xaml b/KeyboardAudioVisualizer/Styles/ComboBox.xaml
new file mode 100644
index 0000000..ab0b6fb
--- /dev/null
+++ b/KeyboardAudioVisualizer/Styles/ComboBox.xaml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/Styles/Formular.xaml b/KeyboardAudioVisualizer/Styles/Formular.xaml
index cc53cdd..7e58030 100644
--- a/KeyboardAudioVisualizer/Styles/Formular.xaml
+++ b/KeyboardAudioVisualizer/Styles/Formular.xaml
@@ -11,9 +11,10 @@
BasedOn="{StaticResource StyleFrameworkElement}"
TargetType="{x:Type controls:Formular}">
-
-
+
+
+
+
@@ -23,7 +24,7 @@
-
+
diff --git a/KeyboardAudioVisualizer/Styles/Theme.xaml b/KeyboardAudioVisualizer/Styles/Theme.xaml
index 8e69cfe..30dea6f 100644
--- a/KeyboardAudioVisualizer/Styles/Theme.xaml
+++ b/KeyboardAudioVisualizer/Styles/Theme.xaml
@@ -4,6 +4,8 @@
xmlns:presentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options">
#FFDCDCDC
+ #FF2A2A2A
+ #B82A2A2A
#111111
#B8111111
#60111111
@@ -27,6 +29,12 @@
+
+
+
+
+
+
@@ -39,5 +47,5 @@
14
14
- 28
+ 22
diff --git a/KeyboardAudioVisualizer/UI/Configuration/BeatConfiguration.xaml b/KeyboardAudioVisualizer/UI/Configuration/BeatConfiguration.xaml
new file mode 100644
index 0000000..c72c70d
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Configuration/BeatConfiguration.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/UI/Configuration/FrequencyBarsConfiguration.xaml b/KeyboardAudioVisualizer/UI/Configuration/FrequencyBarsConfiguration.xaml
index b5fb27d..26261bc 100644
--- a/KeyboardAudioVisualizer/UI/Configuration/FrequencyBarsConfiguration.xaml
+++ b/KeyboardAudioVisualizer/UI/Configuration/FrequencyBarsConfiguration.xaml
@@ -1,20 +1,33 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
+ xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
+ xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
+ xmlns:system="clr-namespace:System;assembly=mscorlib">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -26,12 +39,48 @@
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml b/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml
new file mode 100644
index 0000000..7cfe412
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml b/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml
index b8b39d9..0928bbc 100644
--- a/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml
+++ b/KeyboardAudioVisualizer/UI/ConfigurationWindow.xaml
@@ -19,6 +19,11 @@
+
+
+
+
+
@@ -28,9 +33,26 @@
-
+
+
+
+
+
+
+
+
+
+
+
+ Frequency Bars
+
+
+
+
+
+
@@ -40,18 +62,64 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ Beat-Detection
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -65,11 +133,11 @@
-
+
-
+
diff --git a/KeyboardAudioVisualizer/UI/Visualization/BeatVisualization.xaml b/KeyboardAudioVisualizer/UI/Visualization/BeatVisualization.xaml
new file mode 100644
index 0000000..4629ffa
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/BeatVisualization.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/UI/Visualization/BeatVisualizer.cs b/KeyboardAudioVisualizer/UI/Visualization/BeatVisualizer.cs
new file mode 100644
index 0000000..c7d9ef7
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/BeatVisualizer.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Threading;
+using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
+using RGB.NET.Core;
+using Color = System.Windows.Media.Color;
+using Point = System.Windows.Point;
+
+namespace KeyboardAudioVisualizer.UI.Visualization
+{
+ public class BeatVisualizer : Control
+ {
+ #region DependencyProperties
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty VisualizationProviderProperty = DependencyProperty.Register(
+ "VisualizationProvider", typeof(IVisualizationProvider), typeof(BeatVisualizer), new PropertyMetadata(default(IVisualizationProvider)));
+
+ public IVisualizationProvider VisualizationProvider
+ {
+ get => (IVisualizationProvider)GetValue(VisualizationProviderProperty);
+ set => SetValue(VisualizationProviderProperty, value);
+ }
+
+ public static readonly DependencyProperty BrushProperty = DependencyProperty.Register(
+ "Brush", typeof(Brush), typeof(BeatVisualizer), new PropertyMetadata(default(Brush)));
+
+ public Brush Brush
+ {
+ get => (Brush)GetValue(BrushProperty);
+ set => SetValue(BrushProperty, value);
+ }
+
+ public static readonly DependencyProperty BeatValueProperty = DependencyProperty.Register(
+ "BeatValue", typeof(float), typeof(BeatVisualizer), new PropertyMetadata(default(float)));
+
+ public float BeatValue
+ {
+ get => (float)GetValue(BeatValueProperty);
+ set => SetValue(BeatValueProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Constructors
+
+ public BeatVisualizer()
+ {
+ RGBSurface.Instance.Updated += args => Dispatcher.BeginInvoke(new Action(Update), DispatcherPriority.Normal);
+
+ //TODO DarthAffe 12.08.2017: Create brush from config
+ Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
+ }
+
+ #endregion
+
+ #region Methods
+
+ private void Update()
+ {
+ IVisualizationProvider visualizationProvider = VisualizationProvider;
+ if ((visualizationProvider == null) || (Visibility != Visibility.Visible)) return;
+
+ if (visualizationProvider.VisualizationData[0] > 0.9)
+ BeatValue = 1f;
+ else if (BeatValue > 0.01f)
+ {
+ float newValue = BeatValue * 0.625f;
+ if (newValue > 0.01f)
+ BeatValue = newValue;
+ else BeatValue = 0;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml b/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml
new file mode 100644
index 0000000..6d7d53f
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualizer.cs b/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualizer.cs
new file mode 100644
index 0000000..62dd797
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualizer.cs
@@ -0,0 +1,142 @@
+using System;
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Threading;
+using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
+using RGB.NET.Brushes.Gradients;
+using RGB.NET.Core;
+using Color = System.Windows.Media.Color;
+using Rectangle = System.Windows.Shapes.Rectangle;
+
+namespace KeyboardAudioVisualizer.UI.Visualization
+{
+ [TemplatePart(Name = "PART_BarsPanel", Type = typeof(Panel))]
+ public class FrequencyBarsVisualizer : Control
+ {
+ #region DependencyProperties
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty VisualizationProviderProperty = DependencyProperty.Register(
+ "VisualizationProvider", typeof(IVisualizationProvider), typeof(FrequencyBarsVisualizer),
+ new PropertyMetadata(default(IVisualizationProvider), VisualizationProviderChanged));
+
+ public IVisualizationProvider VisualizationProvider
+ {
+ get => (IVisualizationProvider)GetValue(VisualizationProviderProperty);
+ set => SetValue(VisualizationProviderProperty, value);
+ }
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Properties & Fields
+
+ private IGradient _gradient;
+ private Panel _panel;
+ private Rectangle[] _bars = new Rectangle[0];
+
+ #endregion
+
+ #region Constructors
+
+ public FrequencyBarsVisualizer()
+ {
+ RGBSurface.Instance.Updated += args => Dispatcher.BeginInvoke(new Action(Update), DispatcherPriority.Normal);
+ SizeChanged += (sender, args) => UpdateSizes();
+
+ //TODO DarthAffe 12.08.2017: Get gradient from config
+ _gradient = new RainbowGradient(300, -14);
+ }
+
+ #endregion
+
+ #region Methods
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ _panel = GetTemplateChild("PART_BarsPanel") as Panel;
+
+ InitializeBars();
+ }
+
+ private static void VisualizationProviderChanged(DependencyObject dependencyObject,
+ DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
+ {
+ FrequencyBarsVisualizer visualizer = dependencyObject as FrequencyBarsVisualizer;
+ if (visualizer == null) return;
+
+ void ConfigurationOnPropertyChanged(object sender, PropertyChangedEventArgs args) => visualizer.ConfigurationChanged(args.PropertyName);
+
+ if (dependencyPropertyChangedEventArgs.OldValue is IVisualizationProvider oldVisualizationProvider)
+ oldVisualizationProvider.Configuration.PropertyChanged -= ConfigurationOnPropertyChanged;
+
+ if (dependencyPropertyChangedEventArgs.NewValue is IVisualizationProvider newVisualizationProvider)
+ newVisualizationProvider.Configuration.PropertyChanged += ConfigurationOnPropertyChanged;
+ }
+
+ private void ConfigurationChanged(string changedPropertyName)
+ {
+ if ((changedPropertyName == null) || (changedPropertyName == nameof(FrequencyBarsVisualizationProviderConfiguration.Bars)))
+ InitializeBars();
+ }
+
+ private void InitializeBars()
+ {
+ if (_panel == null) return;
+
+ _panel.Children.Clear();
+ _bars = new Rectangle[((FrequencyBarsVisualizationProviderConfiguration)VisualizationProvider.Configuration).Bars];
+
+ for (int i = 0; i < _bars.Length; i++)
+ {
+ _bars[i] = new Rectangle { VerticalAlignment = VerticalAlignment.Bottom, Width = 0 };
+ _panel.Children.Add(_bars[i]);
+ }
+
+ UpdateSizes();
+ UpdateColors();
+ }
+
+ private void UpdateSizes()
+ {
+ if (_bars.Length == 0) return;
+
+ double barSpacing = ActualWidth / _bars.Length;
+ double barWidth = (barSpacing * 3.0) / 4.0;
+ double margin = barSpacing - barWidth;
+
+ for (int i = 0; i < _bars.Length; i++)
+ {
+ _bars[i].Width = barWidth;
+ _bars[i].Margin = new Thickness(margin / 2, 0, margin / 2, 0);
+ }
+ }
+
+ private void UpdateColors()
+ {
+ for (int i = 0; i < _bars.Length; i++)
+ {
+ RGB.NET.Core.Color color = _gradient.GetColor((double)i / _bars.Length);
+ _bars[i].Fill = new SolidColorBrush(Color.FromRgb(color.R, color.G, color.B));
+ }
+ }
+
+ private void Update()
+ {
+ IVisualizationProvider visualizationProvider = VisualizationProvider;
+ if ((visualizationProvider == null) || (Visibility != Visibility.Visible)) return;
+
+ int count = Math.Min(_bars.Length, visualizationProvider.VisualizationData.Length);
+ for (int i = 0; i < count; i++)
+ {
+ _bars[i].Height = (float)((_bars[i].Height * 0.5) + ((ActualHeight * visualizationProvider.VisualizationData[i]) * (1.0 - 0.5)));
+ if (double.IsNaN(_bars[i].Height)) _bars[i].Height = 0;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/UI/Visualization/LevelVisualization.xaml b/KeyboardAudioVisualizer/UI/Visualization/LevelVisualization.xaml
new file mode 100644
index 0000000..56e1111
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/LevelVisualization.xaml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/UI/Visualization/LevelVisualizer.cs b/KeyboardAudioVisualizer/UI/Visualization/LevelVisualizer.cs
new file mode 100644
index 0000000..a746688
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/LevelVisualizer.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Threading;
+using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
+using RGB.NET.Core;
+using Color = System.Windows.Media.Color;
+using Point = System.Windows.Point;
+
+namespace KeyboardAudioVisualizer.UI.Visualization
+{
+ public class LevelVisualizer : Control
+ {
+ #region DependencyProperties
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty VisualizationProviderProperty = DependencyProperty.Register(
+ "VisualizationProvider", typeof(IVisualizationProvider), typeof(LevelVisualizer), new PropertyMetadata(default(IVisualizationProvider)));
+
+ public IVisualizationProvider VisualizationProvider
+ {
+ get => (IVisualizationProvider)GetValue(VisualizationProviderProperty);
+ set => SetValue(VisualizationProviderProperty, value);
+ }
+
+ public static readonly DependencyProperty BrushLeftProperty = DependencyProperty.Register(
+ "BrushLeft", typeof(Brush), typeof(LevelVisualizer), new PropertyMetadata(default(Brush)));
+
+ public Brush BrushLeft
+ {
+ get => (Brush)GetValue(BrushLeftProperty);
+ set => SetValue(BrushLeftProperty, value);
+ }
+
+ public static readonly DependencyProperty BrushRightProperty = DependencyProperty.Register(
+ "BrushRight", typeof(Brush), typeof(LevelVisualizer), new PropertyMetadata(default(Brush)));
+
+ public Brush BrushRight
+ {
+ get => (Brush)GetValue(BrushRightProperty);
+ set => SetValue(BrushRightProperty, value);
+ }
+
+ public static readonly DependencyProperty SizeLeftProperty = DependencyProperty.Register(
+ "SizeLeft", typeof(int), typeof(LevelVisualizer), new PropertyMetadata(default(int)));
+
+ public int SizeLeft
+ {
+ get => (int)GetValue(SizeLeftProperty);
+ set => SetValue(SizeLeftProperty, value);
+ }
+
+ public static readonly DependencyProperty SizeRightProperty = DependencyProperty.Register(
+ "SizeRight", typeof(int), typeof(LevelVisualizer), new PropertyMetadata(default(int)));
+
+ public int SizeRight
+ {
+ get => (int)GetValue(SizeRightProperty);
+ set => SetValue(SizeRightProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Constructors
+
+ public LevelVisualizer()
+ {
+ RGBSurface.Instance.Updated += args => Dispatcher.BeginInvoke(new Action(Update), DispatcherPriority.Normal);
+
+ //TODO DarthAffe 12.08.2017: Create brush from config
+ BrushLeft = new LinearGradientBrush(Color.FromRgb(255, 0, 0), Color.FromRgb(0, 0, 255), new Point(0, 0.5), new Point(1, 0.5));
+ BrushRight = new LinearGradientBrush(Color.FromRgb(0, 0, 255), Color.FromRgb(255, 0, 0), new Point(0, 0.5), new Point(1, 0.5));
+ }
+
+ #endregion
+
+ #region Methods
+
+ private void Update()
+ {
+ IVisualizationProvider visualizationProvider = VisualizationProvider;
+ if ((visualizationProvider == null) || (Visibility != Visibility.Visible)) return;
+
+ int horizontalSizeLeft = (int)(visualizationProvider.VisualizationData[0] * (ActualWidth / 2));
+ if (Math.Abs(SizeLeft - horizontalSizeLeft) > 1)
+ SizeLeft = horizontalSizeLeft;
+
+ int horizontalSizeRight = (int)(visualizationProvider.VisualizationData[1] * (ActualWidth / 2));
+ if (Math.Abs(SizeRight - horizontalSizeRight) > 1)
+ SizeRight = horizontalSizeRight;
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/packages.config b/KeyboardAudioVisualizer/packages.config
index 06f2799..e2069eb 100644
--- a/KeyboardAudioVisualizer/packages.config
+++ b/KeyboardAudioVisualizer/packages.config
@@ -9,5 +9,5 @@
-
+
\ No newline at end of file