mirror of
https://github.com/DarthAffe/KeyboardAudioVisualizer.git
synced 2025-12-12 15:18:30 +00:00
Updated everything to work with RGB.NETs new decorators; Added dropdowns to change the visualization on devices; Changed configuration to be saved as json (converter for the old format is still needed)
This commit is contained in:
parent
44c0cc59fa
commit
9d4aa2728c
@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using Hardcodet.Wpf.TaskbarNotification;
|
||||
using KeyboardAudioVisualizer.AudioProcessing;
|
||||
using KeyboardAudioVisualizer.Configuration;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace KeyboardAudioVisualizer
|
||||
{
|
||||
@ -12,7 +14,7 @@ namespace KeyboardAudioVisualizer
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const string PATH_SETTINGS = "Settings.xml";
|
||||
private const string PATH_SETTINGS = "Settings.json";
|
||||
|
||||
#endregion
|
||||
|
||||
@ -22,10 +24,6 @@ namespace KeyboardAudioVisualizer
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
@ -37,7 +35,14 @@ namespace KeyboardAudioVisualizer
|
||||
_taskbarIcon = (TaskbarIcon)FindResource("TaskbarIcon");
|
||||
_taskbarIcon.DoubleClickCommand = ApplicationManager.Instance.OpenConfigurationCommand;
|
||||
|
||||
Settings settings = SerializationHelper.LoadObjectFromFile<Settings>(PATH_SETTINGS);
|
||||
//Settings settings = SerializationHelper.LoadObjectFromFile<Settings>(PATH_SETTINGS);
|
||||
Settings settings = null;
|
||||
try { settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(PATH_SETTINGS)); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
/* File doesn't exist or is corrupt - just create a new one. */
|
||||
}
|
||||
if (settings == null)
|
||||
{
|
||||
settings = new Settings();
|
||||
@ -45,7 +50,7 @@ namespace KeyboardAudioVisualizer
|
||||
}
|
||||
ApplicationManager.Instance.Settings = settings;
|
||||
|
||||
AudioProcessor.Initialize();
|
||||
AudioVisualizationFactory.Initialize();
|
||||
ApplicationManager.Instance.InitializeDevices();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -62,7 +67,7 @@ namespace KeyboardAudioVisualizer
|
||||
{
|
||||
base.OnExit(e);
|
||||
|
||||
SerializationHelper.SaveObjectToFile(ApplicationManager.Instance.Settings, PATH_SETTINGS);
|
||||
File.WriteAllText(PATH_SETTINGS, JsonConvert.SerializeObject(ApplicationManager.Instance.Settings));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
using System.Windows;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using KeyboardAudioVisualizer.AudioProcessing;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using KeyboardAudioVisualizer.Configuration;
|
||||
using KeyboardAudioVisualizer.Decorators;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
@ -13,11 +17,15 @@ using RGB.NET.Devices.Corsair.SpecialParts;
|
||||
using RGB.NET.Devices.Logitech;
|
||||
using RGB.NET.Groups;
|
||||
using Point = RGB.NET.Core.Point;
|
||||
using GetDecoratorFunc = System.Func<KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider.VisualizationType, KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider.IVisualizationProvider, RGB.NET.Core.IBrushDecorator>;
|
||||
|
||||
namespace KeyboardAudioVisualizer
|
||||
{
|
||||
public class ApplicationManager
|
||||
{
|
||||
#region Constants
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
public static ApplicationManager Instance { get; } = new ApplicationManager();
|
||||
@ -26,6 +34,10 @@ namespace KeyboardAudioVisualizer
|
||||
|
||||
public Settings Settings { get; set; }
|
||||
|
||||
public ObservableDictionary<VisualizationIndex, IVisualizationProvider> Visualizations { get; } = new ObservableDictionary<VisualizationIndex, IVisualizationProvider>();
|
||||
|
||||
private readonly Dictionary<VisualizationIndex, IEnumerable<(ILedGroup group, GetDecoratorFunc getDecoratorFunc)>> _groups = new Dictionary<VisualizationIndex, IEnumerable<(ILedGroup group, GetDecoratorFunc getDecoratorFunc)>>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
@ -50,7 +62,7 @@ namespace KeyboardAudioVisualizer
|
||||
{
|
||||
RGBSurface surface = RGBSurface.Instance;
|
||||
|
||||
surface.UpdateFrequency = 1 / MathHelper.Clamp(Settings.UpdateRate, 1, 40);
|
||||
surface.UpdateFrequency = 1.0 / MathHelper.Clamp(Settings.UpdateRate, 1, 40);
|
||||
surface.UpdateMode = UpdateMode.Continuous;
|
||||
|
||||
surface.LoadDevices(CorsairDeviceProvider.Instance);
|
||||
@ -60,8 +72,10 @@ namespace KeyboardAudioVisualizer
|
||||
ILedGroup background = new ListLedGroup(surface.Leds);
|
||||
background.Brush = new SolidColorBrush(new Color(64, 0, 0, 0)); //TODO DarthAffe 06.08.2017: A-Channel gives some kind of blur - settings!
|
||||
|
||||
//TODO DarthAffe 03.08.2017: Changeable, Settings etc.
|
||||
foreach (IRGBDevice device in surface.Devices)
|
||||
List<(ILedGroup, GetDecoratorFunc)> primaryGroups = new List<(ILedGroup, GetDecoratorFunc)>();
|
||||
List<(ILedGroup, GetDecoratorFunc)> secondaryGroups = new List<(ILedGroup, GetDecoratorFunc)>();
|
||||
List<(ILedGroup, GetDecoratorFunc)> tertiaryGroups = new List<(ILedGroup, GetDecoratorFunc)>();
|
||||
foreach (IRGBDevice device in RGBSurface.Instance.Devices)
|
||||
switch (device.DeviceInfo.DeviceType)
|
||||
{
|
||||
case RGBDeviceType.Keyboard:
|
||||
@ -77,44 +91,84 @@ namespace KeyboardAudioVisualizer
|
||||
|
||||
ILedGroup lightbarLeft = new ListLedGroup(lightbar.Left);
|
||||
lightbarLeft.Brush = new LinearGradientBrush(keyboardLevelGradient);
|
||||
lightbarLeft.Brush.AddDecorator(new LevelBarDecorator(AudioProcessor.Instance.TertiaryVisualizationProvider, LevelBarDirection.Left, 0));
|
||||
tertiaryGroups.Add((lightbarLeft, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer, LevelBarDirection.Left, 0)));
|
||||
|
||||
ILedGroup lightbarRight = new ListLedGroup(lightbar.Right);
|
||||
lightbarRight.Brush = new LinearGradientBrush(keyboardLevelGradient);
|
||||
lightbarRight.Brush.AddDecorator(new LevelBarDecorator(AudioProcessor.Instance.TertiaryVisualizationProvider, LevelBarDirection.Right, 1));
|
||||
tertiaryGroups.Add((lightbarRight, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer, LevelBarDirection.Right, 1)));
|
||||
|
||||
ILedGroup lightbarCenter = new ListLedGroup(lightbar.Center);
|
||||
lightbarCenter.Brush = new SolidColorBrush(new Color(255, 255, 255));
|
||||
lightbarCenter.Brush.AddDecorator(new BeatDecorator(AudioProcessor.Instance.SecondaryVisualizationProvider));
|
||||
secondaryGroups.Add((lightbarCenter, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer)));
|
||||
}
|
||||
|
||||
primary.Brush = new LinearGradientBrush(new RainbowGradient(300, -14));
|
||||
primary.Brush.AddDecorator(new FrequencyBarsDecorator(AudioProcessor.Instance.PrimaryVisualizationProvider));
|
||||
primaryGroups.Add((primary, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer, LevelBarDirection.Horizontal)));
|
||||
break;
|
||||
|
||||
case RGBDeviceType.Mousepad:
|
||||
case RGBDeviceType.LedStripe:
|
||||
|
||||
IGradient mousepadLevelGradient = new LinearGradient(new GradientStop(0, new Color(0, 0, 255)), new GradientStop(1, new Color(255, 0, 0)));
|
||||
|
||||
ILedGroup left = new RectangleLedGroup(new Rectangle(device.Location.X, device.Location.Y, device.Size.Width / 2.0, device.Size.Height));
|
||||
left.Brush = new LinearGradientBrush(new Point(0.5, 1), new Point(0.5, 0), mousepadLevelGradient);
|
||||
left.Brush.AddDecorator(new LevelBarDecorator(AudioProcessor.Instance.TertiaryVisualizationProvider, LevelBarDirection.Top, 0));
|
||||
tertiaryGroups.Add((left, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer, LevelBarDirection.Top, 0)));
|
||||
|
||||
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));
|
||||
right.Brush = new LinearGradientBrush(new Point(0.5, 1), new Point(0.5, 0), mousepadLevelGradient);
|
||||
right.Brush.AddDecorator(new LevelBarDecorator(AudioProcessor.Instance.TertiaryVisualizationProvider, LevelBarDirection.Top, 1));
|
||||
tertiaryGroups.Add((right, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer, LevelBarDirection.Top, 1)));
|
||||
break;
|
||||
|
||||
case RGBDeviceType.Mouse:
|
||||
case RGBDeviceType.Headset:
|
||||
ILedGroup deviceGroup = new ListLedGroup(device);
|
||||
deviceGroup.Brush = new SolidColorBrush(new Color(255, 255, 255));
|
||||
deviceGroup.Brush.AddDecorator(new BeatDecorator(AudioProcessor.Instance.SecondaryVisualizationProvider));
|
||||
secondaryGroups.Add((deviceGroup, (visualizationType, visualizer) => CreateDecorator(visualizationType, visualizer)));
|
||||
break;
|
||||
}
|
||||
|
||||
surface.Updating += args => AudioProcessor.Instance.Update();
|
||||
_groups[VisualizationIndex.Primary] = primaryGroups;
|
||||
_groups[VisualizationIndex.Secondary] = secondaryGroups;
|
||||
_groups[VisualizationIndex.Tertiary] = tertiaryGroups;
|
||||
|
||||
ApplyVisualization(VisualizationIndex.Primary, Settings[VisualizationIndex.Primary].SelectedVisualization);
|
||||
ApplyVisualization(VisualizationIndex.Secondary, Settings[VisualizationIndex.Secondary].SelectedVisualization);
|
||||
ApplyVisualization(VisualizationIndex.Tertiary, Settings[VisualizationIndex.Tertiary].SelectedVisualization);
|
||||
|
||||
surface.Updating += args => AudioVisualizationFactory.Instance.Update();
|
||||
}
|
||||
|
||||
//TODO DarthAffe 12.09.2017: This is just a big mess - is this worth to rework before arge?
|
||||
public void ApplyVisualization(VisualizationIndex visualizationIndex, VisualizationType visualizationType)
|
||||
{
|
||||
IVisualizationProvider visualizer = AudioVisualizationFactory.Instance.CreateVisualizationProvider(visualizationIndex, visualizationType);
|
||||
Visualizations[visualizationIndex] = visualizer;
|
||||
|
||||
foreach ((ILedGroup group, GetDecoratorFunc getDecoratorFunc) in _groups[visualizationIndex])
|
||||
{
|
||||
group.Brush.RemoveAllDecorators();
|
||||
|
||||
if (visualizer != null)
|
||||
{
|
||||
IBrushDecorator decorator = getDecoratorFunc(visualizationType, visualizer);
|
||||
if (decorator != null)
|
||||
group.Brush.AddDecorator(decorator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IBrushDecorator CreateDecorator(VisualizationType visualizationType, IVisualizationProvider visualizationProvider, LevelBarDirection direction = LevelBarDirection.Top, int dataIndex = 0)
|
||||
{
|
||||
if (visualizationType == VisualizationType.FrequencyBars)
|
||||
return new FrequencyBarsDecorator(visualizationProvider);
|
||||
|
||||
if (visualizationType == VisualizationType.Level)
|
||||
return new LevelBarDecorator(visualizationProvider, direction, dataIndex);
|
||||
|
||||
if (visualizationType == VisualizationType.Beat)
|
||||
return new BeatDecorator(visualizationProvider);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OpenConfiguration()
|
||||
@ -125,8 +179,8 @@ namespace KeyboardAudioVisualizer
|
||||
|
||||
private void Exit()
|
||||
{
|
||||
RGBSurface.Instance.Dispose();
|
||||
AudioProcessor.Instance.Dispose();
|
||||
RGBSurface.Instance?.Dispose();
|
||||
AudioVisualizationFactory.Instance?.Dispose();
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
22
KeyboardAudioVisualizer/Attributes/DisplayNameAttribute.cs
Normal file
22
KeyboardAudioVisualizer/Attributes/DisplayNameAttribute.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Attributes
|
||||
{
|
||||
public class DisplayNameAttribute : Attribute
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public DisplayNameAttribute(string displayName)
|
||||
{
|
||||
this.DisplayName = displayName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
23
KeyboardAudioVisualizer/Attributes/VisualizerForAttribute.cs
Normal file
23
KeyboardAudioVisualizer/Attributes/VisualizerForAttribute.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Attributes
|
||||
{
|
||||
public class VisualizerForAttribute : Attribute
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public RGBDeviceType VisualizerFor { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public VisualizerForAttribute(RGBDeviceType visualizerFor)
|
||||
{
|
||||
this.VisualizerFor = visualizerFor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing
|
||||
{
|
||||
public abstract class AbstractAudioProcessor : IAudioProcessor
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public abstract void Initialize();
|
||||
|
||||
public abstract void Update();
|
||||
|
||||
public virtual void Dispose() { }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using KeyboardAudioVisualizer.AudioCapture;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Equalizer;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Spectrum;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing
|
||||
{
|
||||
public class AudioProcessor : IDisposable
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public static AudioProcessor Instance { get; private set; }
|
||||
|
||||
private AudioBuffer _audioBuffer;
|
||||
private IAudioInput _audioInput;
|
||||
private ISpectrumProvider _spectrumProvider;
|
||||
|
||||
public IVisualizationProvider PrimaryVisualizationProvider { get; private set; }
|
||||
public IVisualizationProvider SecondaryVisualizationProvider { get; private set; }
|
||||
public IVisualizationProvider TertiaryVisualizationProvider { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
private AudioProcessor() { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Update()
|
||||
{
|
||||
_spectrumProvider.Update();
|
||||
|
||||
PrimaryVisualizationProvider?.Update();
|
||||
SecondaryVisualizationProvider?.Update();
|
||||
TertiaryVisualizationProvider?.Update();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Instance != null) return;
|
||||
|
||||
Instance = new AudioProcessor();
|
||||
Instance.InitializeInstance();
|
||||
}
|
||||
|
||||
private void InitializeInstance()
|
||||
{
|
||||
_audioInput = new CSCoreAudioInput();
|
||||
_audioInput.Initialize();
|
||||
|
||||
_audioBuffer = new AudioBuffer(4096); // Working with ~93ms -
|
||||
_audioInput.DataAvailable += (data, offset, count) => _audioBuffer.Put(data, offset, count);
|
||||
|
||||
_spectrumProvider = new FourierSpectrumProvider(_audioBuffer);
|
||||
_spectrumProvider.Initialize();
|
||||
|
||||
//TODO DarthAffe 13.08.2017: Refactore Settings-stuff to work with multiple providers
|
||||
|
||||
MultiBandEqualizer equalizer = new MultiBandEqualizer();
|
||||
ApplicationManager.Instance.Settings.EqualizerConfiguration.LoadInto(equalizer);
|
||||
equalizer.PropertyChanged += (sender, args) => ApplicationManager.Instance.Settings.EqualizerConfiguration.SaveFrom(equalizer);
|
||||
|
||||
PrimaryVisualizationProvider = new FrequencyBarsVisualizationProvider(ApplicationManager.Instance.Settings.FrequencyBarsVisualizationProviderConfiguration, _spectrumProvider) { Equalizer = equalizer };
|
||||
//PrimaryVisualizationProvider = new BeatVisualizationProvider(new BeatVisualizationProviderConfiguration(), _spectrumProvider);
|
||||
PrimaryVisualizationProvider.Initialize();
|
||||
|
||||
SecondaryVisualizationProvider = new BeatVisualizationProvider(ApplicationManager.Instance.Settings.BeatVisualizationProviderConfiguration, _spectrumProvider);
|
||||
SecondaryVisualizationProvider.Initialize();
|
||||
|
||||
TertiaryVisualizationProvider = new LevelVisualizationProvider(ApplicationManager.Instance.Settings.LevelVisualizationProviderConfiguration, _audioBuffer);
|
||||
TertiaryVisualizationProvider.Initialize();
|
||||
}
|
||||
|
||||
public void Dispose() => _audioInput.Dispose();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using KeyboardAudioVisualizer.AudioCapture;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Equalizer;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Spectrum;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing
|
||||
{
|
||||
public class AudioVisualizationFactory : IDisposable
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public static AudioVisualizationFactory Instance { get; private set; }
|
||||
|
||||
private IAudioInput _audioInput;
|
||||
private AudioBuffer _audioBuffer;
|
||||
private readonly List<IAudioProcessor> _processors = new List<IAudioProcessor>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
private AudioVisualizationFactory() { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Update()
|
||||
{
|
||||
foreach (IAudioProcessor processor in _processors.Where(x => x.IsActive))
|
||||
processor.Update();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Instance != null) return;
|
||||
|
||||
Instance = new AudioVisualizationFactory();
|
||||
Instance.InitializeInstance();
|
||||
}
|
||||
|
||||
private void InitializeInstance()
|
||||
{
|
||||
_audioInput = new CSCoreAudioInput();
|
||||
_audioInput.Initialize();
|
||||
|
||||
_audioBuffer = new AudioBuffer(4096); // Working with ~93ms -
|
||||
_audioInput.DataAvailable += (data, offset, count) => _audioBuffer.Put(data, offset, count);
|
||||
|
||||
_processors.Add(new FourierSpectrumProvider(_audioBuffer));
|
||||
|
||||
foreach (IAudioProcessor processor in _processors)
|
||||
processor.Initialize();
|
||||
}
|
||||
|
||||
private T GetAudioProcessor<T>() => (T)_processors.FirstOrDefault(x => x.GetType() == typeof(T));
|
||||
|
||||
public IVisualizationProvider CreateVisualizationProvider(VisualizationIndex visualizationIndex, VisualizationType visualizationType)
|
||||
{
|
||||
IVisualizationProvider visualizationProvider = default;
|
||||
switch (visualizationType)
|
||||
{
|
||||
case VisualizationType.FrequencyBars:
|
||||
MultiBandEqualizer equalizer = new MultiBandEqualizer();
|
||||
ApplicationManager.Instance.Settings[visualizationIndex].EqualizerConfiguration.LoadInto(equalizer);
|
||||
equalizer.PropertyChanged += (sender, args) => ApplicationManager.Instance.Settings[visualizationIndex].EqualizerConfiguration.SaveFrom(equalizer);
|
||||
visualizationProvider = new FrequencyBarsVisualizationProvider(ApplicationManager.Instance.Settings[visualizationIndex].GetConfiguration<FrequencyBarsVisualizationProviderConfiguration>(visualizationType), GetAudioProcessor<FourierSpectrumProvider>()) { Equalizer = equalizer };
|
||||
break;
|
||||
|
||||
case VisualizationType.Level:
|
||||
visualizationProvider = new LevelVisualizationProvider(ApplicationManager.Instance.Settings[visualizationIndex].GetConfiguration<LevelVisualizationProviderConfiguration>(visualizationType), _audioBuffer);
|
||||
break;
|
||||
|
||||
case VisualizationType.Beat:
|
||||
visualizationProvider = new BeatVisualizationProvider(ApplicationManager.Instance.Settings[visualizationIndex].GetConfiguration<BeatVisualizationProviderConfiguration>(visualizationType), GetAudioProcessor<FourierSpectrumProvider>());
|
||||
break;
|
||||
}
|
||||
|
||||
visualizationProvider?.Initialize();
|
||||
return visualizationProvider;
|
||||
}
|
||||
|
||||
public void Dispose() => _audioInput.Dispose();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,11 @@
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing
|
||||
using System;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing
|
||||
{
|
||||
public interface IAudioProcessor
|
||||
public interface IAudioProcessor : IDisposable
|
||||
{
|
||||
bool IsActive { get; set; }
|
||||
|
||||
void Initialize();
|
||||
void Update();
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ using MathNet.Numerics.IntegralTransforms;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing.Spectrum
|
||||
{
|
||||
public class FourierSpectrumProvider : ISpectrumProvider
|
||||
public class FourierSpectrumProvider : AbstractAudioProcessor, ISpectrumProvider
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -31,7 +31,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Spectrum
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Initialize()
|
||||
public override void Initialize()
|
||||
{
|
||||
_hamming = Window.Hamming(_audioBuffer.Size);
|
||||
_sampleData = new float[_audioBuffer.Size];
|
||||
@ -40,7 +40,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.Spectrum
|
||||
_spectrum = new float[_usableDataLength];
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public override void Update()
|
||||
{
|
||||
_audioBuffer.CopyMixInto(ref _sampleData, 0);
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Equalizer;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Spectrum;
|
||||
using KeyboardAudioVisualizer.Configuration;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
{
|
||||
@ -79,7 +79,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
|
||||
#endregion
|
||||
|
||||
public class FrequencyBarsVisualizationProvider : IVisualizationProvider
|
||||
public class FrequencyBarsVisualizationProvider : AbstractAudioProcessor, IVisualizationProvider
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -93,6 +93,9 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
public IConfiguration Configuration => _configuration;
|
||||
public float[] VisualizationData { get; private set; }
|
||||
|
||||
public string DisplayName => "Spectrometer";
|
||||
public RGBDeviceType VisualizerFor => RGBDeviceType.Keyboard | RGBDeviceType.LedMatrix;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -109,7 +112,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Initialize() => RecalculateConfigValues(null);
|
||||
public override void Initialize() => RecalculateConfigValues(null);
|
||||
|
||||
private void RecalculateConfigValues(string changedPropertyName)
|
||||
{
|
||||
@ -123,7 +126,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
_emphasiseFactor = (0.75 * (1 + _configuration.EmphasisePeaks));
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public override void Update()
|
||||
{
|
||||
ISpectrum spectrum = GetSpectrum();
|
||||
if (spectrum == null) return;
|
||||
|
||||
@ -2,9 +2,12 @@
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
{
|
||||
public interface IVisualizationProvider : IAudioProcessor
|
||||
public interface IVisualizationProvider
|
||||
{
|
||||
IConfiguration Configuration { get; }
|
||||
float[] VisualizationData { get; }
|
||||
|
||||
void Initialize();
|
||||
void Update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Linq;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.Spectrum;
|
||||
using KeyboardAudioVisualizer.Configuration;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
{
|
||||
@ -16,7 +17,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
#endregion
|
||||
|
||||
// Port of https://github.com/kctess5/Processing-Beat-Detection
|
||||
public class BeatVisualizationProvider : IVisualizationProvider
|
||||
public class BeatVisualizationProvider : AbstractAudioProcessor, IVisualizationProvider
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -61,6 +62,9 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
public IConfiguration Configuration => _configuration;
|
||||
public float[] VisualizationData { get; } = new float[1];
|
||||
|
||||
public string DisplayName => "Beat";
|
||||
public RGBDeviceType VisualizerFor => (RGBDeviceType)0xFF;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -75,7 +79,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Initialize()
|
||||
public override void Initialize()
|
||||
{
|
||||
_deltaArray = new float[_deltaArraySamples][];
|
||||
for (int i = 0; i < _deltaArray.Length; i++)
|
||||
@ -100,7 +104,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
_beatAverage = new float[_beatAverageSamples];
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public override void Update()
|
||||
{
|
||||
ISpectrum spectrum = _specturProvider.GetLogarithmicSpectrum(60, minFrequency: 60);
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Linq;
|
||||
using KeyboardAudioVisualizer.AudioCapture;
|
||||
using KeyboardAudioVisualizer.Configuration;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
{
|
||||
@ -46,7 +47,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
|
||||
#endregion
|
||||
|
||||
public class LevelVisualizationProvider : IVisualizationProvider
|
||||
public class LevelVisualizationProvider : AbstractAudioProcessor, IVisualizationProvider
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -62,6 +63,10 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
public IConfiguration Configuration => _configuration;
|
||||
public float[] VisualizationData { get; } = new float[3];
|
||||
|
||||
public string DisplayName => "Level";
|
||||
|
||||
public RGBDeviceType VisualizerFor => RGBDeviceType.Keyboard | RGBDeviceType.LedMatrix | RGBDeviceType.LedStripe | RGBDeviceType.Mousepad;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -78,7 +83,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Initialize()
|
||||
public override void Initialize()
|
||||
{
|
||||
_sampleDataLeft = new float[_audioBuffer.Size];
|
||||
_sampleDataRight = new float[_audioBuffer.Size];
|
||||
@ -112,7 +117,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public override void Update()
|
||||
{
|
||||
_audioBuffer.CopyLeftInto(ref _sampleDataLeft, 0);
|
||||
_audioBuffer.CopyRightInto(ref _sampleDataRight, 0);
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
using KeyboardAudioVisualizer.Attributes;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
||||
{
|
||||
public enum VisualizationType
|
||||
{
|
||||
None,
|
||||
|
||||
[VisualizerFor(RGBDeviceType.Keyboard | RGBDeviceType.LedMatrix)]
|
||||
[DisplayName("Frequency Bars")]
|
||||
FrequencyBars,
|
||||
|
||||
[VisualizerFor(RGBDeviceType.Keyboard | RGBDeviceType.LedMatrix | RGBDeviceType.LedStripe | RGBDeviceType.Mousepad)]
|
||||
Level,
|
||||
|
||||
Beat,
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,17 @@ namespace KeyboardAudioVisualizer.Configuration
|
||||
{
|
||||
public class AbstractConfiguration : AbstractBindable, IConfiguration, INotifyPropertyChanged
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private IBrush _brush;
|
||||
public IBrush Brush
|
||||
{
|
||||
get => _brush;
|
||||
set => SetProperty(ref _brush, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
using System.ComponentModel;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Configuration
|
||||
{
|
||||
// DarthAffe 05.08.2017: Marker interface
|
||||
public interface IConfiguration : INotifyPropertyChanged { }
|
||||
public interface IConfiguration : INotifyPropertyChanged
|
||||
{
|
||||
IBrush Brush { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,24 +1,95 @@
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Configuration
|
||||
{
|
||||
public class Settings
|
||||
{
|
||||
#region General
|
||||
#region Properties & Fields
|
||||
|
||||
public double UpdateRate { get; set; } = 40.0;
|
||||
|
||||
#endregion
|
||||
public Dictionary<VisualizationIndex, VisualizationSettings> Visualizations { get; set; } = new Dictionary<VisualizationIndex, VisualizationSettings>();
|
||||
|
||||
#region AudioProcessing
|
||||
public VisualizationSettings this[VisualizationIndex visualizationIndex]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Visualizations.TryGetValue(visualizationIndex, out VisualizationSettings settings))
|
||||
Visualizations[visualizationIndex] = (settings = new VisualizationSettings(visualizationIndex));
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class VisualizationSettings
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public VisualizationType SelectedVisualization { get; set; }
|
||||
|
||||
public EqualizerConfiguration EqualizerConfiguration { get; set; } = new EqualizerConfiguration();
|
||||
|
||||
public FrequencyBarsVisualizationProviderConfiguration FrequencyBarsVisualizationProviderConfiguration { get; set; } = new FrequencyBarsVisualizationProviderConfiguration();
|
||||
public FrequencyBarsVisualizationProviderConfiguration FrequencyBarsConfiguration { get; set; } = new FrequencyBarsVisualizationProviderConfiguration();
|
||||
public LevelVisualizationProviderConfiguration LevelConfiguration { get; set; } = new LevelVisualizationProviderConfiguration();
|
||||
public BeatVisualizationProviderConfiguration BeatConfiguration { get; set; } = new BeatVisualizationProviderConfiguration();
|
||||
|
||||
public LevelVisualizationProviderConfiguration LevelVisualizationProviderConfiguration { get; set; } = new LevelVisualizationProviderConfiguration();
|
||||
public IConfiguration this[VisualizationType visualizationType]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (visualizationType)
|
||||
{
|
||||
case VisualizationType.None:
|
||||
return null;
|
||||
|
||||
public BeatVisualizationProviderConfiguration BeatVisualizationProviderConfiguration { get; set; } = new BeatVisualizationProviderConfiguration();
|
||||
case VisualizationType.FrequencyBars:
|
||||
return FrequencyBarsConfiguration;
|
||||
|
||||
case VisualizationType.Level:
|
||||
return LevelConfiguration;
|
||||
|
||||
case VisualizationType.Beat:
|
||||
return BeatConfiguration;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(visualizationType), visualizationType, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public VisualizationSettings(VisualizationIndex visualizationIndex)
|
||||
{
|
||||
switch (visualizationIndex)
|
||||
{
|
||||
case VisualizationIndex.Primary:
|
||||
SelectedVisualization = VisualizationType.FrequencyBars;
|
||||
break;
|
||||
|
||||
case VisualizationIndex.Secondary:
|
||||
SelectedVisualization = VisualizationType.Beat;
|
||||
break;
|
||||
|
||||
case VisualizationIndex.Tertiary:
|
||||
SelectedVisualization = VisualizationType.Level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public T GetConfiguration<T>(VisualizationType visualizationType)
|
||||
where T : IConfiguration, new() => (T)this[visualizationType];
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using KeyboardAudioVisualizer.Attributes;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using VisualizationType = KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider.VisualizationType;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Converter
|
||||
{
|
||||
[ValueConversion(typeof(VisualizationType), typeof(string))]
|
||||
public class VisualizationProviderDisplayNameConverter : IValueConverter
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is VisualizationType visualizationType)) return null;
|
||||
return visualizationType.GetAttribute<DisplayNameAttribute>()?.DisplayName ?? visualizationType.ToString();
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using KeyboardAudioVisualizer.UI.Visualization;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Converter
|
||||
{
|
||||
[ValueConversion(typeof(IVisualizationProvider), typeof(bool))]
|
||||
public class VisualizationToLastChildFillConverter : IValueConverter
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is FrequencyBarsVisualizationProvider;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
using KeyboardAudioVisualizer.Attributes;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using RGB.NET.Core;
|
||||
using VisualizationType = KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider.VisualizationType;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Converter
|
||||
{
|
||||
[ValueConversion(typeof(IEnumerable<VisualizationType>), typeof(IEnumerable<VisualizationType>))]
|
||||
public class VisualizationTypeSelectableConverter : IValueConverter
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is IEnumerable<VisualizationType> visualizationProviders) || !(parameter is RGBDeviceType targetDevice)) return new List<VisualizationType>();
|
||||
return visualizationProviders.Where(x => x.GetAttribute<VisualizerForAttribute>()?.VisualizerFor.HasFlag(targetDevice) ?? true).ToList();
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Decorators
|
||||
{
|
||||
public class BeatDecorator : AbstractDecorator, IBrushDecorator
|
||||
public class BeatDecorator : AbstractUpdateAwareDecorator, IBrushDecorator
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -22,6 +22,8 @@ namespace KeyboardAudioVisualizer.Decorators
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void Update(double deltaTime) => _visualizationProvider.Update();
|
||||
|
||||
public void ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, ref Color color)
|
||||
{
|
||||
color.APercent *= _visualizationProvider.VisualizationData[0];
|
||||
|
||||
@ -6,7 +6,7 @@ using Rectangle = RGB.NET.Core.Rectangle;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Decorators
|
||||
{
|
||||
public class FrequencyBarsDecorator : AbstractDecorator, IBrushDecorator
|
||||
public class FrequencyBarsDecorator : AbstractUpdateAwareDecorator, IBrushDecorator
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -25,9 +25,11 @@ namespace KeyboardAudioVisualizer.Decorators
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void Update(double deltaTime) => _visualizationProvider.Update();
|
||||
|
||||
public void ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, ref Color color)
|
||||
{
|
||||
int barSampleIndex = (int)Math.Floor(_visualizationProvider.VisualizationData.Length * (renderTarget.Point.X / (rectangle.Location.X + rectangle.Size.Width)));
|
||||
int barSampleIndex = Math.Min(_visualizationProvider.VisualizationData.Length, (int)Math.Floor(_visualizationProvider.VisualizationData.Length * (renderTarget.Point.X / (rectangle.Location.X + rectangle.Size.Width))));
|
||||
double curBarHeight = 1.0 - Math.Max(0f, _visualizationProvider.VisualizationData[barSampleIndex]);
|
||||
double verticalPos = (renderTarget.Point.Y / rectangle.Size.Height);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ using RGB.NET.Core;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Decorators
|
||||
{
|
||||
public class LevelBarDecorator : AbstractDecorator, IBrushDecorator
|
||||
public class LevelBarDecorator : AbstractUpdateAwareDecorator, IBrushDecorator
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@ -26,12 +26,32 @@ namespace KeyboardAudioVisualizer.Decorators
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void Update(double deltaTime) => _visualizationProvider.Update();
|
||||
|
||||
public void ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, ref Color color)
|
||||
{
|
||||
double offset = CalculateOffset(rectangle, renderTarget);
|
||||
|
||||
if (offset >= _visualizationProvider.VisualizationData[DataIndex])
|
||||
color.A = 0;
|
||||
if (Direction == LevelBarDirection.Horizontal)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
offset = (-offset * 2);
|
||||
if (offset >= _visualizationProvider.VisualizationData[0])
|
||||
color.A = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset *= 2;
|
||||
if (offset >= _visualizationProvider.VisualizationData[1])
|
||||
color.A = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (offset >= _visualizationProvider.VisualizationData[DataIndex])
|
||||
color.A = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private double CalculateOffset(Rectangle rectangle, BrushRenderTarget renderTarget)
|
||||
@ -50,6 +70,9 @@ namespace KeyboardAudioVisualizer.Decorators
|
||||
case LevelBarDirection.Bottom:
|
||||
return renderTarget.Rectangle.Center.Y / rectangle.Size.Height;
|
||||
|
||||
case LevelBarDirection.Horizontal:
|
||||
return (renderTarget.Rectangle.Center.X / rectangle.Size.Width) - 0.5;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -62,7 +85,10 @@ namespace KeyboardAudioVisualizer.Decorators
|
||||
|
||||
public enum LevelBarDirection
|
||||
{
|
||||
Left, Right, Top, Bottom
|
||||
Left, Right, Top, Bottom,
|
||||
|
||||
//HACK DarthAffe 12.09.2017: Just a bad workaround ...
|
||||
Horizontal
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
15
KeyboardAudioVisualizer/Helper/EnumExtension.cs
Normal file
15
KeyboardAudioVisualizer/Helper/EnumExtension.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Helper
|
||||
{
|
||||
public static class EnumExtension
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public static T GetAttribute<T>(this Enum e)
|
||||
where T : Attribute => e.GetType().GetMember(e.ToString()).FirstOrDefault()?.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,8 @@ namespace KeyboardAudioVisualizer.Helper
|
||||
{
|
||||
if (ex == null) return string.Empty;
|
||||
|
||||
message += ex.Message;
|
||||
|
||||
if (ex.InnerException != null)
|
||||
message += "\r\nInnerException: " + GetFullMessage(ex.InnerException);
|
||||
|
||||
|
||||
309
KeyboardAudioVisualizer/Helper/ObservableDictionary.cs
Normal file
309
KeyboardAudioVisualizer/Helper/ObservableDictionary.cs
Normal file
@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
|
||||
// Taken from https://codereview.stackexchange.com/questions/116562/custom-implementation-of-observabledictionary
|
||||
namespace KeyboardAudioVisualizer.Helper
|
||||
{
|
||||
public class ObservableDictionary<TKey, TValue> : AbstractBindable, IDictionary<TKey, TValue>, INotifyCollectionChanged
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const string INDEXER_NAME = "Item[]";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
private readonly IList<TValue> _values;
|
||||
private readonly IDictionary<TKey, int> _indexMap;
|
||||
|
||||
private readonly SimpleMonitor _monitor = new SimpleMonitor();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public ObservableDictionary()
|
||||
{
|
||||
_values = new List<TValue>();
|
||||
_indexMap = new Dictionary<TKey, int>();
|
||||
}
|
||||
|
||||
public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
|
||||
{
|
||||
_values = new List<TValue>();
|
||||
_indexMap = new Dictionary<TKey, int>();
|
||||
|
||||
int idx = 0;
|
||||
foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
|
||||
{
|
||||
_indexMap.Add(kvp.Key, idx);
|
||||
_values.Add(kvp.Value);
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableDictionary(int capacity)
|
||||
{
|
||||
_values = new List<TValue>(capacity);
|
||||
_indexMap = new Dictionary<TKey, int>(capacity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Virtual Add/Remove/Change Control Methods
|
||||
|
||||
protected virtual void AddItem(TKey key, TValue value)
|
||||
{
|
||||
CheckReentrancy();
|
||||
|
||||
int index = _values.Count;
|
||||
_indexMap.Add(key, index);
|
||||
_values.Add(value);
|
||||
|
||||
OnPropertyChanged(nameof(Count));
|
||||
OnPropertyChanged(nameof(Keys));
|
||||
OnPropertyChanged(nameof(Values));
|
||||
OnPropertyChanged(INDEXER_NAME);
|
||||
OnCollectionChanged(NotifyCollectionChangedAction.Add, key, value, index);
|
||||
}
|
||||
|
||||
protected virtual bool RemoveItem(TKey key)
|
||||
{
|
||||
CheckReentrancy();
|
||||
|
||||
int index = _indexMap[key];
|
||||
TValue value = _values[index];
|
||||
|
||||
if (_indexMap.Remove(key))
|
||||
{
|
||||
_values.RemoveAt(index);
|
||||
|
||||
List<TKey> keys = _indexMap.Keys.ToList();
|
||||
|
||||
foreach (TKey existingKey in keys)
|
||||
{
|
||||
if (_indexMap[existingKey] > index)
|
||||
_indexMap[existingKey]--;
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(Count));
|
||||
OnPropertyChanged(nameof(Keys));
|
||||
OnPropertyChanged(nameof(Values));
|
||||
OnPropertyChanged(INDEXER_NAME);
|
||||
OnCollectionChanged(NotifyCollectionChangedAction.Remove, key, value, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool RemoveItem(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
CheckReentrancy();
|
||||
|
||||
if (_indexMap.ContainsKey(item.Key) && _values[_indexMap[item.Key]].Equals(item.Value))
|
||||
{
|
||||
int index = _indexMap[item.Key];
|
||||
TValue value = _values[index];
|
||||
|
||||
_indexMap.Remove(item.Key);
|
||||
_values.RemoveAt(index);
|
||||
|
||||
List<TKey> keys = _indexMap.Keys.ToList();
|
||||
|
||||
foreach (TKey existingKey in keys)
|
||||
{
|
||||
if (_indexMap[existingKey] > index)
|
||||
_indexMap[existingKey]--;
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(Count));
|
||||
OnPropertyChanged(nameof(Keys));
|
||||
OnPropertyChanged(nameof(Values));
|
||||
OnPropertyChanged(INDEXER_NAME);
|
||||
OnCollectionChanged(NotifyCollectionChangedAction.Remove, item.Key, item.Value, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void RemoveAllItems()
|
||||
{
|
||||
|
||||
CheckReentrancy();
|
||||
_values.Clear();
|
||||
_indexMap.Clear();
|
||||
|
||||
OnPropertyChanged(nameof(Count));
|
||||
OnPropertyChanged(nameof(Keys));
|
||||
OnPropertyChanged(nameof(Values));
|
||||
OnPropertyChanged(INDEXER_NAME);
|
||||
OnCollectionChanged(NotifyCollectionChangedAction.Reset);
|
||||
}
|
||||
|
||||
protected virtual void ChangeItem(TKey key, TValue newValue)
|
||||
{
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
if (!_indexMap.ContainsKey(key))
|
||||
AddItem(key, newValue);
|
||||
else
|
||||
{
|
||||
int index = _indexMap[key];
|
||||
TValue oldValue = _values[index];
|
||||
_values[index] = newValue;
|
||||
|
||||
OnPropertyChanged(nameof(Values));
|
||||
OnPropertyChanged(INDEXER_NAME);
|
||||
OnCollectionChanged(NotifyCollectionChangedAction.Replace, key, oldValue, newValue, index);
|
||||
}
|
||||
}
|
||||
|
||||
protected IDisposable BlockReentrancy()
|
||||
{
|
||||
_monitor.Enter();
|
||||
return (IDisposable)_monitor;
|
||||
}
|
||||
|
||||
protected void CheckReentrancy()
|
||||
{
|
||||
// ISSUE: reference to a compiler-generated field
|
||||
// ISSUE: reference to a compiler-generated field
|
||||
if (_monitor.Busy && CollectionChanged != null && CollectionChanged.GetInvocationList().Length > 1)
|
||||
throw new InvalidOperationException("ObservableCollectionReentrancyNotAllowed");
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDictionary<TKey,TValue> Members
|
||||
|
||||
public void Add(TKey key, TValue value) => AddItem(key, value);
|
||||
|
||||
public bool ContainsKey(TKey key) => _indexMap.ContainsKey(key);
|
||||
|
||||
public bool Remove(TKey key) => RemoveItem(key);
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
if (_indexMap.TryGetValue(key, out int index))
|
||||
{
|
||||
value = _values[index];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ICollection<TKey> Keys => _indexMap.Keys;
|
||||
|
||||
public ICollection<TValue> Values => _values;
|
||||
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = _indexMap[key];
|
||||
return _values[index];
|
||||
}
|
||||
set => ChangeItem(key, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICollection<KeyValuePair<TKey,TValue>> Members
|
||||
|
||||
public void Clear() => RemoveAllItems();
|
||||
|
||||
public int Count => _indexMap.Count;
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) => _indexMap.ContainsKey(item.Key) && _values[_indexMap[item.Key]].Equals(item.Value);
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
foreach (KeyValuePair<TKey, int> kvp in _indexMap)
|
||||
{
|
||||
array[arrayIndex] = new KeyValuePair<TKey, TValue>(kvp.Key, _values[kvp.Value]);
|
||||
arrayIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) => RemoveItem(item);
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<KeyValuePair<TKey,TValue>> Members
|
||||
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
foreach (KeyValuePair<TKey, int> kvp in _indexMap)
|
||||
{
|
||||
KeyValuePair<TKey, TValue> pair = new KeyValuePair<TKey, TValue>(kvp.Key, _values[kvp.Value]);
|
||||
yield return pair;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
#endregion
|
||||
|
||||
#region INotifyCollectionChanged Members
|
||||
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
|
||||
protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
NotifyCollectionChangedEventHandler handler = CollectionChanged;
|
||||
|
||||
using (BlockReentrancy())
|
||||
handler?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected void OnCollectionChanged(NotifyCollectionChangedAction action) => OnCollectionChanged(new NotifyCollectionChangedEventArgs(action));
|
||||
|
||||
protected void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue value, int index) => OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, new KeyValuePair<TKey, TValue>(key, value), index));
|
||||
|
||||
protected void OnCollectionChanged(NotifyCollectionChangedAction action, TKey key, TValue oldValue, TValue newValue, int index)
|
||||
{
|
||||
KeyValuePair<TKey, TValue> newPair = new KeyValuePair<TKey, TValue>(key, newValue);
|
||||
KeyValuePair<TKey, TValue> oldPair = new KeyValuePair<TKey, TValue>(key, oldValue);
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, newPair, oldPair, index));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private class SimpleMonitor : IDisposable
|
||||
{
|
||||
private int _busyCount;
|
||||
|
||||
public bool Busy => _busyCount > 0;
|
||||
|
||||
public void Enter() => _busyCount = _busyCount + 1;
|
||||
|
||||
public void Dispose() => _busyCount = _busyCount - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
KeyboardAudioVisualizer/Helper/VisualizationIndex.cs
Normal file
9
KeyboardAudioVisualizer/Helper/VisualizationIndex.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace KeyboardAudioVisualizer.Helper
|
||||
{
|
||||
public enum VisualizationIndex
|
||||
{
|
||||
Primary,
|
||||
Secondary,
|
||||
Tertiary
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
@ -34,6 +35,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\Icon.ico</ApplicationIcon>
|
||||
@ -48,6 +50,9 @@
|
||||
<Reference Include="MathNet.Numerics, Version=3.20.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MathNet.Numerics.3.20.0\lib\net40\MathNet.Numerics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RGB.NET.Brushes">
|
||||
<HintPath>..\packages\RGB.NET.Brushes.1.0.0\lib\net45\RGB.NET.Brushes.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@ -108,10 +113,13 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ApplicationManager.cs" />
|
||||
<Compile Include="Attributes\DisplayNameAttribute.cs" />
|
||||
<Compile Include="Attributes\VisualizerForAttribute.cs" />
|
||||
<Compile Include="AudioCapture\AudioBuffer.cs" />
|
||||
<Compile Include="AudioCapture\CSCoreAudioInput.cs" />
|
||||
<Compile Include="AudioCapture\IAudioInput.cs" />
|
||||
<Compile Include="AudioProcessing\AudioProcessor.cs" />
|
||||
<Compile Include="AudioProcessing\AbstractAudioProcessor.cs" />
|
||||
<Compile Include="AudioProcessing\AudioVisualizationFactory.cs" />
|
||||
<Compile Include="AudioProcessing\Equalizer\EqualizerBand.cs" />
|
||||
<Compile Include="AudioProcessing\Equalizer\IEqualizer.cs" />
|
||||
<Compile Include="AudioProcessing\Equalizer\MultiBandEqualizer.cs" />
|
||||
@ -129,6 +137,10 @@
|
||||
<Compile Include="AudioProcessing\VisualizationProvider\IVisualizationProvider.cs" />
|
||||
<Compile Include="AudioProcessing\VisualizationProvider\LevelVisualizationProvider.cs" />
|
||||
<Compile Include="AudioProcessing\Spectrum\RawSpectrumProvider.cs" />
|
||||
<Compile Include="AudioProcessing\VisualizationProvider\VisualizationType.cs" />
|
||||
<Compile Include="Converter\VisualizationProviderDisplayNameConverter.cs" />
|
||||
<Compile Include="Converter\VisualizationToLastChildFillConverter.cs" />
|
||||
<Compile Include="Converter\VisualizationTypeSelectableConverter.cs" />
|
||||
<Compile Include="Decorators\BeatDecorator.cs" />
|
||||
<Compile Include="Decorators\FrequencyBarsDecorator.cs" />
|
||||
<Compile Include="Decorators\LevelBarDecorator.cs" />
|
||||
@ -143,12 +155,16 @@
|
||||
<Compile Include="Converter\OffsetToPosXConverter.cs" />
|
||||
<Compile Include="Converter\ValueToPosYConverter.cs" />
|
||||
<Compile Include="Helper\ActionCommand.cs" />
|
||||
<Compile Include="Helper\EnumExtension.cs" />
|
||||
<Compile Include="Helper\ExceptionExtension.cs" />
|
||||
<Compile Include="Helper\FrequencyHelper.cs" />
|
||||
<Compile Include="Helper\MathHelper.cs" />
|
||||
<Compile Include="Helper\ObservableDictionary.cs" />
|
||||
<Compile Include="Helper\VisualizationIndex.cs" />
|
||||
<Compile Include="Helper\WPFHelper.cs" />
|
||||
<Compile Include="Configuration\Settings.cs" />
|
||||
<Compile Include="Controls\BlurredDecorationWindow.cs" />
|
||||
<Compile Include="Legacy\Settings.cs" />
|
||||
<Compile Include="Styles\CachedResourceDictionary.cs" />
|
||||
<Compile Include="UI\ConfigurationWindow.xaml.cs">
|
||||
<DependentUpon>ConfigurationWindow.xaml</DependentUpon>
|
||||
@ -160,7 +176,7 @@
|
||||
<Compile Include="UI\Visualization\LevelVisualizer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Helper\SerializationHelper.cs" />
|
||||
<Compile Include="Legacy\SerializationHelper.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary>
|
||||
@ -2,7 +2,7 @@
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Helper
|
||||
namespace KeyboardAudioVisualizer.Legacy
|
||||
{
|
||||
public static class SerializationHelper
|
||||
{
|
||||
26
KeyboardAudioVisualizer/Legacy/Settings.cs
Normal file
26
KeyboardAudioVisualizer/Legacy/Settings.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using KeyboardAudioVisualizer.Configuration;
|
||||
|
||||
namespace KeyboardAudioVisualizer.Legacy
|
||||
{
|
||||
public class Settings
|
||||
{
|
||||
#region General
|
||||
|
||||
public double UpdateRate { get; set; } = 40.0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region AudioProcessing
|
||||
|
||||
public EqualizerConfiguration EqualizerConfiguration { get; set; } = new EqualizerConfiguration();
|
||||
|
||||
public FrequencyBarsVisualizationProviderConfiguration FrequencyBarsVisualizationProviderConfiguration { get; set; } = new FrequencyBarsVisualizationProviderConfiguration();
|
||||
|
||||
public LevelVisualizationProviderConfiguration LevelVisualizationProviderConfiguration { get; set; } = new LevelVisualizationProviderConfiguration();
|
||||
|
||||
public BeatVisualizationProviderConfiguration BeatVisualizationProviderConfiguration { get; set; } = new BeatVisualizationProviderConfiguration();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider;
|
||||
using KeyboardAudioVisualizer.Helper;
|
||||
using RGB.NET.Core;
|
||||
|
||||
@ -24,6 +25,36 @@ namespace KeyboardAudioVisualizer.UI
|
||||
}
|
||||
}
|
||||
|
||||
public VisualizationType SelectedPrimaryVisualization
|
||||
{
|
||||
get => ApplicationManager.Instance.Settings[VisualizationIndex.Primary].SelectedVisualization;
|
||||
set
|
||||
{
|
||||
ApplicationManager.Instance.Settings[VisualizationIndex.Primary].SelectedVisualization = value;
|
||||
ApplicationManager.Instance.ApplyVisualization(VisualizationIndex.Primary, value);
|
||||
}
|
||||
}
|
||||
|
||||
public VisualizationType SelectedSecondaryVisualization
|
||||
{
|
||||
get => ApplicationManager.Instance.Settings[VisualizationIndex.Secondary].SelectedVisualization;
|
||||
set
|
||||
{
|
||||
ApplicationManager.Instance.Settings[VisualizationIndex.Secondary].SelectedVisualization = value;
|
||||
ApplicationManager.Instance.ApplyVisualization(VisualizationIndex.Secondary, value);
|
||||
}
|
||||
}
|
||||
|
||||
public VisualizationType SelectedTertiaryVisualization
|
||||
{
|
||||
get => ApplicationManager.Instance.Settings[VisualizationIndex.Tertiary].SelectedVisualization;
|
||||
set
|
||||
{
|
||||
ApplicationManager.Instance.Settings[VisualizationIndex.Tertiary].SelectedVisualization = value;
|
||||
ApplicationManager.Instance.ApplyVisualization(VisualizationIndex.Tertiary, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
|
||||
@ -7,7 +7,12 @@
|
||||
xmlns:controls="clr-namespace:KeyboardAudioVisualizer.Controls"
|
||||
xmlns:styles="clr-namespace:KeyboardAudioVisualizer.Styles"
|
||||
xmlns:core="clr-namespace:RGB.NET.Core;assembly=RGB.NET.Core"
|
||||
xmlns:keyboardAudioVisualizer="clr-namespace:KeyboardAudioVisualizer"
|
||||
xmlns:audioProcessing="clr-namespace:KeyboardAudioVisualizer.AudioProcessing"
|
||||
xmlns:converter="clr-namespace:KeyboardAudioVisualizer.Converter"
|
||||
xmlns:visualizationProvider="clr-namespace:KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider"
|
||||
xmlns:helper="clr-namespace:KeyboardAudioVisualizer.Helper"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
mc:Ignorable="d"
|
||||
Title="Keyboard Audio-Visualizer # Configuration"
|
||||
Icon="pack://application:,,,/KeyboardAudioVisualizer;component/Resources/Icon.ico"
|
||||
@ -25,6 +30,20 @@
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Configuration/BeatConfiguration.xaml" />
|
||||
<styles:CachedResourceDictionary Source="/KeyboardAudioVisualizer;component/UI/Visualization/BeatVisualization.xaml" />
|
||||
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||
|
||||
<converter:VisualizationTypeSelectableConverter x:Key="VisualizationProviderSelectableConverter" />
|
||||
<converter:VisualizationProviderDisplayNameConverter x:Key="VisualizationProviderDisplayNameConverter" />
|
||||
<converter:VisualizationToLastChildFillConverter x:Key="VisualizationToLastChildFillConverter" />
|
||||
|
||||
<DataTemplate x:Key="DataTemplateVisualizationSelection" DataType="{x:Type visualizationProvider:VisualizationType}">
|
||||
<TextBlock Text="{Binding Converter={StaticResource VisualizationProviderDisplayNameConverter}}" />
|
||||
</DataTemplate>
|
||||
|
||||
<ObjectDataProvider x:Key="DataProviderVisualizationTypes" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type TypeName="visualizationProvider:VisualizationType" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
</styles:CachedResourceDictionary>
|
||||
</controls:BlurredDecorationWindow.Resources>
|
||||
|
||||
@ -34,7 +53,7 @@
|
||||
|
||||
<TabControl Style="{StaticResource StyleTabControlNavigation}">
|
||||
<TabItem Header="Keyboard">
|
||||
<DockPanel>
|
||||
<DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary], Converter={StaticResource VisualizationToLastChildFillConverter}}">
|
||||
<GroupBox DockPanel.Dock="Top">
|
||||
<controls:Formular>
|
||||
<controls:Formular.Resources>
|
||||
@ -44,26 +63,26 @@
|
||||
</controls:Formular.Resources>
|
||||
|
||||
<Label controls:Formular.IsLabel="True" Content="Visualization: " />
|
||||
<ComboBox controls:Formular.Fill="True" SelectedIndex="0">
|
||||
<ComboBox.Items>
|
||||
<ComboBoxItem>Frequency Bars</ComboBoxItem>
|
||||
</ComboBox.Items>
|
||||
</ComboBox>
|
||||
<ComboBox controls:Formular.Fill="True" SelectedIndex="0"
|
||||
ItemTemplate="{StaticResource DataTemplateVisualizationSelection}"
|
||||
ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes},
|
||||
Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Keyboard}}"
|
||||
SelectedItem="{Binding SelectedPrimaryVisualization}" />
|
||||
</controls:Formular>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
|
||||
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=PrimaryVisualizationProvider.Configuration}" />
|
||||
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary].Configuration}" />
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Margin="0,8,0,0">
|
||||
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=PrimaryVisualizationProvider}" />
|
||||
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
|
||||
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Primary]}" />
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Mouse/Headset">
|
||||
<DockPanel LastChildFill="False">
|
||||
<DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary], Converter={StaticResource VisualizationToLastChildFillConverter}}">
|
||||
<GroupBox DockPanel.Dock="Top">
|
||||
<controls:Formular>
|
||||
<controls:Formular.Resources>
|
||||
@ -73,26 +92,26 @@
|
||||
</controls:Formular.Resources>
|
||||
|
||||
<Label controls:Formular.IsLabel="True" Content="Visualization: " />
|
||||
<ComboBox controls:Formular.Fill="True" SelectedIndex="0">
|
||||
<ComboBox.Items>
|
||||
<ComboBoxItem>Beat-Detection</ComboBoxItem>
|
||||
</ComboBox.Items>
|
||||
</ComboBox>
|
||||
<ComboBox controls:Formular.Fill="True" SelectedIndex="0"
|
||||
ItemTemplate="{StaticResource DataTemplateVisualizationSelection}"
|
||||
ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes},
|
||||
Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Mouse}}"
|
||||
SelectedItem="{Binding SelectedSecondaryVisualization}" />
|
||||
</controls:Formular>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
|
||||
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=SecondaryVisualizationProvider.Configuration}" />
|
||||
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary].Configuration}" />
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
|
||||
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=SecondaryVisualizationProvider}" />
|
||||
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Secondary]}" />
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="Lightbar/Mousepad">
|
||||
<DockPanel LastChildFill="False">
|
||||
<DockPanel LastChildFill="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary], Converter={StaticResource VisualizationToLastChildFillConverter}}">
|
||||
<GroupBox DockPanel.Dock="Top">
|
||||
<controls:Formular>
|
||||
<controls:Formular.Resources>
|
||||
@ -102,20 +121,20 @@
|
||||
</controls:Formular.Resources>
|
||||
|
||||
<Label controls:Formular.IsLabel="True" Content="Visualization: " />
|
||||
<ComboBox controls:Formular.Fill="True" SelectedIndex="0">
|
||||
<ComboBox.Items>
|
||||
<ComboBoxItem>Level</ComboBoxItem>
|
||||
</ComboBox.Items>
|
||||
</ComboBox>
|
||||
<ComboBox controls:Formular.Fill="True" SelectedIndex="0"
|
||||
ItemTemplate="{StaticResource DataTemplateVisualizationSelection}"
|
||||
ItemsSource="{Binding Source={StaticResource DataProviderVisualizationTypes},
|
||||
Converter={StaticResource VisualizationProviderSelectableConverter}, ConverterParameter={x:Static core:RGBDeviceType.Mousepad}}"
|
||||
SelectedItem="{Binding SelectedTertiaryVisualization}" />
|
||||
</controls:Formular>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
|
||||
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=TertiaryVisualizationProvider.Configuration}" />
|
||||
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary].Configuration}" />
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Margin="0,8,0,0" DockPanel.Dock="Top">
|
||||
<ContentControl Content="{Binding Source={x:Static audioProcessing:AudioProcessor.Instance}, Path=TertiaryVisualizationProvider}" />
|
||||
<ContentControl Content="{Binding Source={x:Static keyboardAudioVisualizer:ApplicationManager.Instance}, Path=Visualizations[(helper:VisualizationIndex)Tertiary]}" />
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
</Style>
|
||||
|
||||
<DataTemplate DataType="{x:Type visualizationProvider:FrequencyBarsVisualizationProvider}">
|
||||
<Grid>
|
||||
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<visualization:FrequencyBarsVisualizer Style="{StaticResource StyleFrequencyBarsVisualizer}" VisualizationProvider="{Binding}" />
|
||||
<visualization:EqualizerVisualizer Style="{StaticResource StyleEqualizerVisualizer}" Equalizer="{Binding Equalizer}" />
|
||||
</Grid>
|
||||
|
||||
@ -88,6 +88,8 @@ namespace KeyboardAudioVisualizer.UI.Visualization
|
||||
if (_panel == null) return;
|
||||
|
||||
_panel.Children.Clear();
|
||||
if (VisualizationProvider == null) return;
|
||||
|
||||
_bars = new Rectangle[((FrequencyBarsVisualizationProviderConfiguration)VisualizationProvider.Configuration).Bars];
|
||||
|
||||
for (int i = 0; i < _bars.Length; i++)
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
<package id="CSCore" version="1.2.1.1" targetFramework="net461" />
|
||||
<package id="Hardcodet.NotifyIcon.Wpf" version="1.0.8" targetFramework="net461" />
|
||||
<package id="MathNet.Numerics" version="3.20.0" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
|
||||
<package id="RGB.NET.Brushes" version="1.0.0" targetFramework="net461" />
|
||||
<package id="RGB.NET.Core" version="1.0.0" targetFramework="net461" />
|
||||
<package id="RGB.NET.Devices.CoolerMaster" version="1.0.0" targetFramework="net461" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user