diff --git a/KeyboardAudioVisualizer.sln.DotSettings b/KeyboardAudioVisualizer.sln.DotSettings
new file mode 100644
index 0000000..3157d76
--- /dev/null
+++ b/KeyboardAudioVisualizer.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs b/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs
index 71661aa..d1e51f1 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/AudioProcessor.cs
@@ -59,7 +59,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing
_spectrumProvider.Initialize();
//TODO DarthAffe 03.08.2017: Initialize correctly; Settings
- MultiBandEqualizer equalizer = new MultiBandEqualizer { [0] = -3, [1] = -1, [2] = 1, [3] = 2, [4] = 3 };
+ MultiBandEqualizer equalizer = new MultiBandEqualizer();
PrimaryVisualizationProvider = new FrequencyBarsVisualizationProvider(new FrequencyBarsVisualizationProviderConfiguration(), _spectrumProvider) { Equalizer = equalizer };
//PrimaryVisualizationProvider = new BeatVisualizationProvider(new BeatVisualizationProviderConfiguration(), _spectrumProvider);
PrimaryVisualizationProvider.Initialize();
diff --git a/KeyboardAudioVisualizer/AudioProcessing/Equalizer/EqualizerBand.cs b/KeyboardAudioVisualizer/AudioProcessing/Equalizer/EqualizerBand.cs
new file mode 100644
index 0000000..6d27b76
--- /dev/null
+++ b/KeyboardAudioVisualizer/AudioProcessing/Equalizer/EqualizerBand.cs
@@ -0,0 +1,42 @@
+using RGB.NET.Core;
+
+namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
+{
+ public class EqualizerBand : AbstractBindable
+ {
+ #region Properties & Fields
+
+ private float _offset;
+ public float Offset
+ {
+ get => _offset;
+ set
+ {
+ if (!IsFixedOffset)
+ SetProperty(ref _offset, value);
+ }
+ }
+
+ private float _value;
+ public float Value
+ {
+ get => _value;
+ set => SetProperty(ref _value, value);
+ }
+
+ public bool IsFixedOffset { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public EqualizerBand(float offset, float value = 0, bool fixedOffset = false)
+ {
+ this.Offset = offset;
+ this.Value = value;
+ this.IsFixedOffset = fixedOffset;
+ }
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/AudioProcessing/Equalizer/IEqualizer.cs b/KeyboardAudioVisualizer/AudioProcessing/Equalizer/IEqualizer.cs
index 03427e8..dca2d9c 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/Equalizer/IEqualizer.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/Equalizer/IEqualizer.cs
@@ -1,8 +1,13 @@
-namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
+using System.Collections.ObjectModel;
+
+namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
{
public interface IEqualizer
{
bool IsEnabled { get; set; }
- float[] CalculateValues(int values);
+
+ ObservableCollection Bands { get; }
+
+ float[] CalculateValues(int count);
}
}
diff --git a/KeyboardAudioVisualizer/AudioProcessing/Equalizer/MultiBandEqualizer.cs b/KeyboardAudioVisualizer/AudioProcessing/Equalizer/MultiBandEqualizer.cs
index 6c77654..4cbb630 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/Equalizer/MultiBandEqualizer.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/Equalizer/MultiBandEqualizer.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
@@ -8,46 +7,35 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
{
#region Properties & Fields
+ public ObservableCollection Bands { get; } = new ObservableCollection();
+
private float[] _values;
- private readonly List _bands = new List();
-
- public int Bands => _bands.Count;
- public float this[int band]
- {
- get => _bands[band].Value;
- set
- {
- _bands[band].Value = value;
- RecalculateValues();
- }
- }
-
public bool IsEnabled { get; set; } = true;
#endregion
#region Constructors
- public MultiBandEqualizer(int bands = 5)
+ public MultiBandEqualizer()
{
- if (bands < 2) throw new ArgumentOutOfRangeException(nameof(bands), "There must be at least two bands for an working equalizer!");
-
- float reference = (float)Math.Log(bands);
-
- for (int i = bands - 1; i >= 0; i--)
- {
- Band band = new Band((reference - (float)Math.Log(i + 1)) / reference);
- _bands.Add(band);
- }
-
- CalculateValues(1);
+ AddBand(0, 0, true);
+ AddBand(1, 0, true);
}
#endregion
#region Methods
+ public void AddBand(float frequency, float modification, bool isFixedFrequency = false)
+ {
+ EqualizerBand band = new EqualizerBand(frequency, modification, isFixedFrequency);
+ band.PropertyChanged += (sender, args) => InvalidateCache();
+ Bands.Add(band);
+
+ InvalidateCache();
+ }
+
public float[] CalculateValues(int values)
{
if ((_values == null) || (_values.Length != values))
@@ -55,7 +43,6 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
_values = new float[values];
RecalculateValues();
}
-
return _values;
}
@@ -65,40 +52,15 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Equalizer
for (int i = 0; i < _values.Length; i++)
{
float offset = (i / width);
-
- Band bandBefore = _bands.Last(n => n.Offset <= offset);
- Band bandAfter = _bands.First(n => n.Offset >= offset);
-
+ EqualizerBand bandBefore = Bands.Last(n => n.Offset <= offset);
+ EqualizerBand bandAfter = Bands.First(n => n.Offset >= offset);
offset = bandAfter.Offset <= 0 ? 0 : (offset - bandBefore.Offset) / (bandAfter.Offset - bandBefore.Offset);
-
float value = (float)((3.0 * (offset * offset)) - (2.0 * (offset * offset * offset)));
_values[i] = bandBefore.Value + (value * (bandAfter.Value - bandBefore.Value));
}
}
- #endregion
-
- #region Data
-
- private class Band
- {
- #region Properties & Fields
-
- public float Offset { get; set; }
- public float Value { get; set; }
-
- #endregion
-
- #region Constructors
-
- public Band(float offset, float value = 0)
- {
- this.Offset = offset;
- this.Value = value;
- }
-
- #endregion
- }
+ private void InvalidateCache() => _values = null;
#endregion
}
diff --git a/KeyboardAudioVisualizer/AudioProcessing/Spectrum/Band.cs b/KeyboardAudioVisualizer/AudioProcessing/Spectrum/Band.cs
index 38505ac..cefcb0e 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/Spectrum/Band.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/Spectrum/Band.cs
@@ -11,6 +11,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Spectrum
public float LowerFrequency { get; }
public float UpperFrequency { get; }
+ public float CenterFrequency { get; }
private float? _average = null;
public float Average => _average ?? (_average = _data.Average()).Value;
@@ -35,6 +36,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Spectrum
{
this.LowerFrequency = lowerFrequency;
this.UpperFrequency = upperFrequency;
+ this.CenterFrequency = (LowerFrequency + UpperFrequency) / 2f; //TODO DarthAffe 12.08.2017: Is this valid for logarithmic scaling?
this._data = data;
_resolution = (UpperFrequency - LowerFrequency) / data.Length;
diff --git a/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs b/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs
index 267eaa9..6007b9b 100644
--- a/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs
+++ b/KeyboardAudioVisualizer/AudioProcessing/VisualizationPRovider/FrequencyBarsVisualizationProvider.cs
@@ -127,22 +127,16 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
ISpectrum spectrum = GetSpectrum();
if (spectrum == null) return;
+ float[] equalizerValues = Equalizer?.IsEnabled == true ? Equalizer.CalculateValues(spectrum.BandCount) : null;
+
for (int i = 0; i < spectrum.BandCount; i++)
{
double binPower = Math.Max(0, 20 * Math.Log10(GetBandValue(spectrum[i])));
- //TODO DarthAffe 10.08.2017: Rewrite Equalizer
- //if (Equalizer?.IsEnabled == true)
- //{
- // float value = Equalizer.CalculateValues(VisualizationData.Length)[i];
- // if (Math.Abs(value) > 0.000001)
- // {
- // bool lower = value < 0;
- // value = 1 + (value * value);
- // binPower *= lower ? 1f / value : value;
- // }
- //}
+ if (equalizerValues != null)
+ binPower += equalizerValues[i];
+ binPower = Math.Max(0, binPower);
binPower /= _configuration.ReferenceLevel;
if (_configuration.EmphasisePeaks > 0.001)
binPower = Math.Pow(binPower, 1 + _configuration.EmphasisePeaks) * _emphasiseFactor;
diff --git a/KeyboardAudioVisualizer/Configuration/AbstractConfiguration.cs b/KeyboardAudioVisualizer/Configuration/AbstractConfiguration.cs
index fed82f4..e918473 100644
--- a/KeyboardAudioVisualizer/Configuration/AbstractConfiguration.cs
+++ b/KeyboardAudioVisualizer/Configuration/AbstractConfiguration.cs
@@ -1,20 +1,15 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
+using RGB.NET.Core;
namespace KeyboardAudioVisualizer.Configuration
{
- public class AbstractConfiguration : IConfiguration, INotifyPropertyChanged
+ public class AbstractConfiguration : AbstractBindable, IConfiguration, INotifyPropertyChanged
{
- #region Events
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- #endregion
-
#region Methods
- protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null)
+ protected override bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if ((typeof(T) == typeof(double)) || (typeof(T) == typeof(float)))
{
@@ -31,8 +26,6 @@ namespace KeyboardAudioVisualizer.Configuration
return true;
}
- protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-
#endregion
}
}
diff --git a/KeyboardAudioVisualizer/Converter/BoolToVisibilityConverter.cs b/KeyboardAudioVisualizer/Converter/BoolToVisibilityConverter.cs
new file mode 100644
index 0000000..50958ca
--- /dev/null
+++ b/KeyboardAudioVisualizer/Converter/BoolToVisibilityConverter.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace KeyboardAudioVisualizer.Converter
+{
+ [ValueConversion(typeof(bool), typeof(Visibility))]
+ public class BoolToVisibilityConverter : IValueConverter
+ {
+ #region Methods
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => (value as bool?) == true ? Visibility.Visible : Visibility.Collapsed;
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value as Visibility? == Visibility.Visible;
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Converter/OffsetToPosXConverter.cs b/KeyboardAudioVisualizer/Converter/OffsetToPosXConverter.cs
new file mode 100644
index 0000000..8aa97a8
--- /dev/null
+++ b/KeyboardAudioVisualizer/Converter/OffsetToPosXConverter.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace KeyboardAudioVisualizer.Converter
+{
+ public class ValueToPosYConverter : IMultiValueConverter
+ {
+ #region Methods
+
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if ((values.Length != 3) || (values[0] == null) || (values[0] == DependencyProperty.UnsetValue)
+ || (values[1] == null) || (values[1] == DependencyProperty.UnsetValue)
+ || (values[2] == null) || (values[2] == DependencyProperty.UnsetValue))
+ return 0;
+
+ float val = (float)values[0];
+ double height = (double)values[1];
+ double reference = (double)values[2];
+
+ double halfHeight = height / 2.0;
+
+ double offset = val / reference;
+ if (offset < 0)
+ return halfHeight + (-offset * halfHeight);
+
+ if (offset > 0)
+ return halfHeight - (offset * halfHeight);
+
+ return halfHeight;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/Converter/ValueToPosYConverter.cs b/KeyboardAudioVisualizer/Converter/ValueToPosYConverter.cs
new file mode 100644
index 0000000..19a975c
--- /dev/null
+++ b/KeyboardAudioVisualizer/Converter/ValueToPosYConverter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace KeyboardAudioVisualizer.Converter
+{
+ public class OffsetToPosXConverter : IMultiValueConverter
+ {
+ #region Methods
+
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ if ((values.Length != 2) || (values[0] == null) || (values[0] == DependencyProperty.UnsetValue)
+ || (values[1] == null) || (values[1] == DependencyProperty.UnsetValue))
+ return 0;
+
+ float offset = (float)values[0];
+ double width = (double)values[1];
+
+ return offset * width;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj b/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
index df90530..b252c77 100644
--- a/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
+++ b/KeyboardAudioVisualizer/KeyboardAudioVisualizer.csproj
@@ -106,6 +106,7 @@
+
@@ -129,7 +130,10 @@
+
+
+
@@ -142,6 +146,7 @@
+
diff --git a/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml b/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
index dc8baaf..e67945c 100644
--- a/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
+++ b/KeyboardAudioVisualizer/Resources/KeyboardAudioVisualizer.xaml
@@ -15,6 +15,7 @@
+
diff --git a/KeyboardAudioVisualizer/Styles/Theme.xaml b/KeyboardAudioVisualizer/Styles/Theme.xaml
index 30dea6f..f70bf72 100644
--- a/KeyboardAudioVisualizer/Styles/Theme.xaml
+++ b/KeyboardAudioVisualizer/Styles/Theme.xaml
@@ -23,7 +23,7 @@
-
+
@@ -34,11 +34,16 @@
-
+
+
+
+
+
+
40
diff --git a/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml b/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml
index 7cfe412..2a69216 100644
--- a/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml
+++ b/KeyboardAudioVisualizer/UI/Configuration/LevelConfiguration.xaml
@@ -41,7 +41,7 @@
-
diff --git a/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs b/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs
index 01e0d6c..fe1849d 100644
--- a/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs
+++ b/KeyboardAudioVisualizer/UI/ConfigurationViewModel.cs
@@ -2,10 +2,11 @@
using System.Diagnostics;
using System.Reflection;
using KeyboardAudioVisualizer.Helper;
+using RGB.NET.Core;
namespace KeyboardAudioVisualizer.UI
{
- public class ConfigurationViewModel
+ public class ConfigurationViewModel : AbstractBindable
{
#region Properties & Fields
diff --git a/KeyboardAudioVisualizer/UI/Visualization/EqualizerVisualizer.cs b/KeyboardAudioVisualizer/UI/Visualization/EqualizerVisualizer.cs
new file mode 100644
index 0000000..0b59aaa
--- /dev/null
+++ b/KeyboardAudioVisualizer/UI/Visualization/EqualizerVisualizer.cs
@@ -0,0 +1,101 @@
+using System.Windows;
+using System.Windows.Controls;
+using KeyboardAudioVisualizer.AudioProcessing.Equalizer;
+
+namespace KeyboardAudioVisualizer.UI.Visualization
+{
+ //[TemplatePart(Name = "PART_Grips", Type = typeof(Canvas))]
+ public class EqualizerVisualizer : Control
+ {
+ #region DependencyProperties
+ // ReSharper disable InconsistentNaming
+
+ public static readonly DependencyProperty EqualizerProperty = DependencyProperty.Register(
+ "Equalizer", typeof(IEqualizer), typeof(EqualizerVisualizer), new PropertyMetadata(default(IEqualizer)));
+
+ public IEqualizer Equalizer
+ {
+ get => (IEqualizer)GetValue(EqualizerProperty);
+ set => SetValue(EqualizerProperty, value);
+ }
+
+ public static readonly DependencyProperty ReferenceLevelProperty = DependencyProperty.Register(
+ "ReferenceLevel", typeof(double), typeof(EqualizerVisualizer), new PropertyMetadata(default(double)));
+
+ public double ReferenceLevel
+ {
+ get => (double)GetValue(ReferenceLevelProperty);
+ set => SetValue(ReferenceLevelProperty, value);
+ }
+
+ // ReSharper restore InconsistentNaming
+ #endregion
+
+ #region Properties & Fields
+
+ //private Canvas _canvas;
+
+ #endregion
+
+ #region Constructors
+
+ //public EqualizerVisualizer()
+ //{
+ // SizeChanged += (sender, args) => Update();
+ // Update();
+ //}
+
+ #endregion
+
+ #region Methods
+
+ //public override void OnApplyTemplate()
+ //{
+ // base.OnApplyTemplate();
+
+ // _canvas = GetTemplateChild("PART_Grips") as Canvas;
+ //}
+
+ //private static void EqualizerChanged(DependencyObject dependencyObject,
+ // DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
+ //{
+ // EqualizerVisualizer visualizer = dependencyObject as EqualizerVisualizer;
+ // if (visualizer == null) return;
+
+ // void BandsChanged(object sender, NotifyCollectionChangedEventArgs args) => visualizer.Update();
+
+ // if (dependencyPropertyChangedEventArgs.OldValue is IEqualizer oldEqualizer)
+ // oldEqualizer.Bands.CollectionChanged -= BandsChanged;
+
+ // if (dependencyPropertyChangedEventArgs.NewValue is IEqualizer newEqualizer)
+ // newEqualizer.Bands.CollectionChanged += BandsChanged;
+ //}
+
+ //private void Update()
+ //{
+ // if (_canvas == null) return;
+
+ // void OnBandChanged(object sender, PropertyChangedEventArgs args) => Update();
+
+ // foreach (object child in _canvas.Children)
+ // {
+ // EqualizerBand band = (child as ContentControl)?.Content as EqualizerBand;
+ // if (band == null) continue;
+ // band.PropertyChanged -= OnBandChanged;
+ // }
+
+ // _canvas.Children.Clear();
+
+ // foreach (EqualizerBand band in Equalizer.Bands)
+ // {
+ // ContentControl ctrl = new ContentControl();
+
+ // ctrl.Content = band;
+
+ // _canvas.Children.Add(ctrl);
+ // }
+ //}
+
+ #endregion
+ }
+}
diff --git a/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml b/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml
index 6d7d53f..e887486 100644
--- a/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml
+++ b/KeyboardAudioVisualizer/UI/Visualization/FrequencyBarsVisualization.xaml
@@ -2,19 +2,24 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
- xmlns:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization">
+ xmlns:visualization="clr-namespace:KeyboardAudioVisualizer.UI.Visualization"
+ xmlns:equalizer="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.Equalizer"
+ xmlns:converter="clr-namespace:KeyboardAudioVisualizer.Converter">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+