mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-01 10:13:30 +00:00
Audio layer progress
This commit is contained in:
parent
1fa6063706
commit
0656687b88
@ -494,6 +494,7 @@
|
|||||||
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\BaseSpectrumProvider.cs" />
|
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\BaseSpectrumProvider.cs" />
|
||||||
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\ISpectrumProvider.cs" />
|
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\ISpectrumProvider.cs" />
|
||||||
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\LineSpectrum.cs" />
|
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\LineSpectrum.cs" />
|
||||||
|
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\SingleSpectrum.cs" />
|
||||||
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\SpectrumBase.cs" />
|
<Compile Include="Profiles\Layers\Types\Audio\AudioCapturing\SpectrumBase.cs" />
|
||||||
<Compile Include="Profiles\Layers\Types\Audio\AudioPropertiesModel.cs" />
|
<Compile Include="Profiles\Layers\Types\Audio\AudioPropertiesModel.cs" />
|
||||||
<Compile Include="Profiles\Layers\Types\Audio\AudioPropertiesView.xaml.cs">
|
<Compile Include="Profiles\Layers\Types\Audio\AudioPropertiesView.xaml.cs">
|
||||||
|
|||||||
@ -91,6 +91,7 @@ namespace Artemis
|
|||||||
JsonConvert.DefaultSettings = () => settings;
|
JsonConvert.DefaultSettings = () => settings;
|
||||||
|
|
||||||
//TODO DarthAffe 17.12.2016: Is this the right location for this?
|
//TODO DarthAffe 17.12.2016: Is this the right location for this?
|
||||||
|
//TODO Move to Mainmanager and make disposable
|
||||||
ActiveWindowHelper.Initialize();
|
ActiveWindowHelper.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,7 @@ namespace Artemis.DAL
|
|||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(path + $@"\{prof.Slug}.json", json);
|
File.WriteAllText(path + $@"\{prof.Slug}.json", json);
|
||||||
Logger.Trace("Saved profile {0}/{1}/{2}", prof.KeyboardSlug, prof.GameName, prof.Name);
|
Logger.Debug("Saved profile {0}/{1}/{2}", prof.KeyboardSlug, prof.GameName, prof.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace Artemis.DeviceProviders.Corsair
|
|||||||
|
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Can only disable a keyboard");
|
throw new NotSupportedException("Can only disable a keyboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateDevice(Bitmap bitmap)
|
public override void UpdateDevice(Bitmap bitmap)
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace Artemis.DeviceProviders.Corsair
|
|||||||
|
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Can only disable a keyboard");
|
throw new NotSupportedException("Can only disable a keyboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateDevice(Bitmap bitmap)
|
public override void UpdateDevice(Bitmap bitmap)
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace Artemis.DeviceProviders.Corsair
|
|||||||
|
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Can only disable a keyboard");
|
throw new NotSupportedException("Can only disable a keyboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateDevice(Bitmap bitmap)
|
public override void UpdateDevice(Bitmap bitmap)
|
||||||
|
|||||||
@ -89,13 +89,12 @@ namespace Artemis.DeviceProviders
|
|||||||
|
|
||||||
public override void UpdateDevice(Bitmap bitmap)
|
public override void UpdateDevice(Bitmap bitmap)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead.");
|
throw new NotSupportedException("KeyboardProvider doesn't implement UpdateDevice, use DrawBitmap instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool TryEnable()
|
public override bool TryEnable()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException(
|
throw new NotSupportedException("KeyboardProvider doesn't implement TryEnable, use CanEnableAsync instead.");
|
||||||
"KeyboardProvider doesn't implement TryEnable, use CanEnableAsync instead.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -49,7 +49,7 @@ namespace Artemis.DeviceProviders.Logitech
|
|||||||
|
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Can only disable a keyboard");
|
throw new NotSupportedException("Can only disable a keyboard");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,6 +76,11 @@ namespace Artemis.Managers
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_logger.Debug("Deactivate profile preview");
|
_logger.Debug("Deactivate profile preview");
|
||||||
|
|
||||||
|
// Save the profile the editor was using
|
||||||
|
var activePreview = PreviewViewModules.FirstOrDefault(p => p.IsModuleActive);
|
||||||
|
activePreview?.ProfileEditor?.SaveSelectedProfile();
|
||||||
|
|
||||||
var lastModule = _moduleManager.GetLastModule();
|
var lastModule = _moduleManager.GetLastModule();
|
||||||
if (lastModule != null)
|
if (lastModule != null)
|
||||||
_moduleManager.ChangeActiveModule(lastModule);
|
_moduleManager.ChangeActiveModule(lastModule);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using CSCore;
|
using CSCore;
|
||||||
using CSCore.CoreAudioAPI;
|
using CSCore.CoreAudioAPI;
|
||||||
@ -12,32 +13,31 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
|||||||
public class AudioCapture
|
public class AudioCapture
|
||||||
{
|
{
|
||||||
private const FftSize FftSize = CSCore.DSP.FftSize.Fft4096;
|
private const FftSize FftSize = CSCore.DSP.FftSize.Fft4096;
|
||||||
|
private readonly Timer _activityTimer;
|
||||||
|
private readonly Timer _volumeTimer;
|
||||||
|
private readonly double[] _volumeValues;
|
||||||
|
private SingleSpectrum _singleSpectrum;
|
||||||
private WasapiLoopbackCapture _soundIn;
|
private WasapiLoopbackCapture _soundIn;
|
||||||
private GainSource _source;
|
private GainSource _source;
|
||||||
private BasicSpectrumProvider _spectrumProvider;
|
private BasicSpectrumProvider _spectrumProvider;
|
||||||
private GainSource _volume;
|
private GainSource _volume;
|
||||||
private Timer _timer;
|
private int _volumeIndex;
|
||||||
|
|
||||||
public AudioCapture(ILogger logger, MMDevice device)
|
public AudioCapture(ILogger logger, MMDevice device)
|
||||||
{
|
{
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
Device = device;
|
Device = device;
|
||||||
|
DesiredAverage = 0.75;
|
||||||
|
|
||||||
_timer = new Timer(1000);
|
_volumeValues = new double[5];
|
||||||
_timer.Elapsed += TimerOnElapsed;
|
_volumeIndex = 0;
|
||||||
|
_activityTimer = new Timer(1000);
|
||||||
|
_activityTimer.Elapsed += ActivityTimerOnElapsed;
|
||||||
|
_volumeTimer = new Timer(200);
|
||||||
|
_volumeTimer.Elapsed += VolumeTimerOnElapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
|
public double DesiredAverage { get; set; }
|
||||||
{
|
|
||||||
// If MayStop is true for longer than a second, this will stop the audio capture
|
|
||||||
if (MayStop)
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
MayStop = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
MayStop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool MayStop { get; set; }
|
public bool MayStop { get; set; }
|
||||||
|
|
||||||
@ -52,7 +52,64 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
|||||||
public MMDevice Device { get; }
|
public MMDevice Device { get; }
|
||||||
public bool Running { get; set; }
|
public bool Running { get; set; }
|
||||||
|
|
||||||
public LineSpectrum GetLineSpectrum(int barCount, int volume, ScalingStrategy scalingStrategy)
|
private void VolumeTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (Volume <= 0)
|
||||||
|
Volume = 1;
|
||||||
|
|
||||||
|
var currentValue = _singleSpectrum.GetValue();
|
||||||
|
if (currentValue == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_volumeValues[_volumeIndex] = currentValue.Value;
|
||||||
|
|
||||||
|
if (_volumeIndex == 4)
|
||||||
|
{
|
||||||
|
_volumeIndex = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_volumeIndex++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var averageVolume = _volumeValues.Average();
|
||||||
|
// Don't adjust when there is virtually no audio
|
||||||
|
if (averageVolume < 0.01)
|
||||||
|
return;
|
||||||
|
// Don't bother when the volume with within a certain marigin
|
||||||
|
if (averageVolume > DesiredAverage - 0.1 && averageVolume < DesiredAverage + 0.1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (averageVolume < DesiredAverage && Volume < 50)
|
||||||
|
{
|
||||||
|
Logger.Trace("averageVolume:{0} | DesiredAverage:{1} | Volume:{2} so increase.", currentValue,
|
||||||
|
DesiredAverage, Volume);
|
||||||
|
Volume++;
|
||||||
|
}
|
||||||
|
else if (Volume > 1)
|
||||||
|
{
|
||||||
|
Logger.Trace("averageVolume:{0} | DesiredAverage:{1} | Volume:{2} so decrease.", currentValue,
|
||||||
|
DesiredAverage, Volume);
|
||||||
|
Volume--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ActivityTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
// If MayStop is true for longer than a second, this will stop the audio capture
|
||||||
|
if (MayStop)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
MayStop = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MayStop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LineSpectrum GetLineSpectrum(int barCount, ScalingStrategy scalingStrategy)
|
||||||
{
|
{
|
||||||
return new LineSpectrum(FftSize)
|
return new LineSpectrum(FftSize)
|
||||||
{
|
{
|
||||||
@ -64,11 +121,41 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Stop()
|
||||||
{
|
{
|
||||||
|
if (!Running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Logger.Debug("Stopping audio capture for device: {0}", Device?.FriendlyName ?? "default");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_activityTimer.Stop();
|
||||||
|
_volumeTimer.Stop();
|
||||||
|
|
||||||
|
_soundIn.Stop();
|
||||||
|
_soundIn.Dispose();
|
||||||
|
_source.Dispose();
|
||||||
|
_soundIn = null;
|
||||||
|
_source = null;
|
||||||
|
|
||||||
|
Running = false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Warn(e, "Failed to stop WASAPI audio capture");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pulse()
|
||||||
|
{
|
||||||
|
MayStop = false;
|
||||||
|
|
||||||
if (Running)
|
if (Running)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Logger.Debug("Starting audio capture for device: {0}", Device?.FriendlyName ?? "default");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_soundIn = new WasapiLoopbackCapture();
|
_soundIn = new WasapiLoopbackCapture();
|
||||||
@ -99,8 +186,12 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_singleSpectrum = new SingleSpectrum(FftSize, _spectrumProvider);
|
||||||
|
|
||||||
|
_activityTimer.Start();
|
||||||
|
_volumeTimer.Start();
|
||||||
|
|
||||||
_soundIn.Start();
|
_soundIn.Start();
|
||||||
_timer.Start();
|
|
||||||
Running = true;
|
Running = true;
|
||||||
MayStop = false;
|
MayStop = false;
|
||||||
}
|
}
|
||||||
@ -109,27 +200,5 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
|||||||
Logger.Warn(e, "Failed to start WASAPI audio capture");
|
Logger.Warn(e, "Failed to start WASAPI audio capture");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
if (!Running)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_timer.Stop();
|
|
||||||
_soundIn.Stop();
|
|
||||||
_soundIn.Dispose();
|
|
||||||
_source.Dispose();
|
|
||||||
_soundIn = null;
|
|
||||||
_source = null;
|
|
||||||
|
|
||||||
Running = false;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.Warn(e, "Failed to stop WASAPI audio capture");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Windows;
|
||||||
using Artemis.Profiles.Layers.Models;
|
|
||||||
using CSCore.DSP;
|
using CSCore.DSP;
|
||||||
|
|
||||||
namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
||||||
@ -27,30 +26,36 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetupLayersVertical(double height, List<LayerModel> audioLayers)
|
public void UpdateLinesVertical(double height, Point[] points)
|
||||||
{
|
{
|
||||||
var fftBuffer = new float[(int)FftSize];
|
var fftBuffer = new float[(int) FftSize];
|
||||||
|
|
||||||
// get the fft result from the spectrum provider
|
// get the fft result from the spectrum provider
|
||||||
if (!SpectrumProvider.GetFftData(fftBuffer, this))
|
if (!SpectrumProvider.GetFftData(fftBuffer, this))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var spectrumPoints = CalculateSpectrumPoints(height, fftBuffer);
|
var spectrumPoints = CalculateSpectrumPoints(height, fftBuffer);
|
||||||
foreach (var p in spectrumPoints)
|
for (var index = 0; index < spectrumPoints.Length; index++)
|
||||||
audioLayers[p.SpectrumPointIndex].Height = p.Value;
|
{
|
||||||
|
var spectrumPointData = spectrumPoints[index];
|
||||||
|
points[index].Y = spectrumPointData.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetupLayersHorizontal(double width, List<LayerModel> audioLayers)
|
public void UpdateLinesHorizontal(double width, Point[] points)
|
||||||
{
|
{
|
||||||
var fftBuffer = new float[(int)FftSize];
|
var fftBuffer = new float[(int) FftSize];
|
||||||
|
|
||||||
// get the fft result from the spectrum provider
|
// get the fft result from the spectrum provider
|
||||||
if (!SpectrumProvider.GetFftData(fftBuffer, this))
|
if (!SpectrumProvider.GetFftData(fftBuffer, this))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var spectrumPoints = CalculateSpectrumPoints(width, fftBuffer);
|
var spectrumPoints = CalculateSpectrumPoints(width, fftBuffer);
|
||||||
foreach (var p in spectrumPoints)
|
for (var index = 0; index < spectrumPoints.Length; index++)
|
||||||
audioLayers[p.SpectrumPointIndex].Width = p.Value;
|
{
|
||||||
|
var spectrumPointData = spectrumPoints[index];
|
||||||
|
points[index].X = spectrumPointData.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Profiles.Layers.Models;
|
||||||
|
using CSCore.DSP;
|
||||||
|
|
||||||
|
namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
|
||||||
|
{
|
||||||
|
public sealed class SingleSpectrum : SpectrumBase
|
||||||
|
{
|
||||||
|
public SingleSpectrum(FftSize fftSize, ISpectrumProvider spectrumProvider)
|
||||||
|
{
|
||||||
|
SpectrumProvider = spectrumProvider;
|
||||||
|
SpectrumResolution = 1;
|
||||||
|
FftSize = fftSize;
|
||||||
|
|
||||||
|
UpdateFrequencyMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double? GetValue()
|
||||||
|
{
|
||||||
|
var fftBuffer = new float[(int)FftSize];
|
||||||
|
|
||||||
|
// get the fft result from the spectrum provider
|
||||||
|
if (SpectrumProvider == null || !SpectrumProvider.GetFftData(fftBuffer, this))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var spectrumPoints = CalculateSpectrumPoints(1, fftBuffer);
|
||||||
|
return spectrumPoints[0].Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Windows;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Artemis.Modules.Abstract;
|
using Artemis.Modules.Abstract;
|
||||||
using Artemis.Profiles.Layers.Abstract;
|
using Artemis.Profiles.Layers.Abstract;
|
||||||
@ -11,25 +8,18 @@ using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
|
|||||||
using Artemis.Properties;
|
using Artemis.Properties;
|
||||||
using Artemis.Utilities;
|
using Artemis.Utilities;
|
||||||
using Artemis.ViewModels.Profiles;
|
using Artemis.ViewModels.Profiles;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ninject;
|
|
||||||
|
|
||||||
namespace Artemis.Profiles.Layers.Types.Audio
|
namespace Artemis.Profiles.Layers.Types.Audio
|
||||||
{
|
{
|
||||||
public class AudioType : ILayerType
|
public class AudioType : ILayerType
|
||||||
{
|
{
|
||||||
private readonly List<LayerModel> _audioLayers = new List<LayerModel>();
|
private readonly AudioCapture _audioCapture;
|
||||||
private readonly IKernel _kernel;
|
|
||||||
|
|
||||||
private DateTime _lastUpdate;
|
|
||||||
private int _lines;
|
private int _lines;
|
||||||
private string _previousSettings;
|
|
||||||
private LineSpectrum _lineSpectrum;
|
private LineSpectrum _lineSpectrum;
|
||||||
private AudioCapture _audioCapture;
|
private Point[] _points;
|
||||||
|
|
||||||
public AudioType(IKernel kernel, AudioCaptureManager audioCaptureManager)
|
public AudioType(AudioCaptureManager audioCaptureManager)
|
||||||
{
|
{
|
||||||
_kernel = kernel;
|
|
||||||
_audioCapture = audioCaptureManager.GetAudioCapture(null);
|
_audioCapture = audioCaptureManager.GetAudioCapture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,26 +42,29 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
|||||||
|
|
||||||
public void Draw(LayerModel layerModel, DrawingContext c)
|
public void Draw(LayerModel layerModel, DrawingContext c)
|
||||||
{
|
{
|
||||||
lock (_audioLayers)
|
var parentX = layerModel.X * 4;
|
||||||
|
var parentY = layerModel.Y * 4;
|
||||||
|
var pen = new Pen(layerModel.Brush, 4);
|
||||||
|
var direction = ((AudioPropertiesModel) layerModel.Properties).Direction;
|
||||||
|
if (direction == Direction.BottomToTop || direction == Direction.TopToBottom)
|
||||||
{
|
{
|
||||||
foreach (var audioLayer in _audioLayers)
|
for (var index = 0; index < _points.Length; index++)
|
||||||
{
|
{
|
||||||
// This is cheating but it ensures that the brush is drawn across the entire main-layer
|
var startPoint = new Point(index * 4 + 2 + parentX, _points[index].Y * 4 + parentY);
|
||||||
var oldWidth = audioLayer.Properties.Width;
|
var endPoint = new Point(index * 4 + 2 + parentX, parentY);
|
||||||
var oldHeight = audioLayer.Properties.Height;
|
var clip = new Rect(startPoint, endPoint);
|
||||||
var oldX = audioLayer.Properties.X;
|
clip.Width = 4;
|
||||||
var oldY = audioLayer.Properties.Y;
|
c.PushClip(new RectangleGeometry(new Rect(startPoint, endPoint)));
|
||||||
|
var point = new Point(index * 4 + 2 + parentX, _points[index].Y * 4 + parentY);
|
||||||
audioLayer.Properties.Width = layerModel.Properties.Width;
|
c.DrawLine(pen, startPoint, endPoint);
|
||||||
audioLayer.Properties.Height = layerModel.Properties.Height;
|
}
|
||||||
audioLayer.Properties.X = layerModel.Properties.X;
|
}
|
||||||
audioLayer.Properties.Y = layerModel.Properties.Y;
|
else
|
||||||
audioLayer.LayerType.Draw(audioLayer, c);
|
{
|
||||||
|
for (var index = 0; index < _points.Length; index++)
|
||||||
audioLayer.Properties.Width = oldWidth;
|
{
|
||||||
audioLayer.Properties.Height = oldHeight;
|
var point = new Point(_points[index].X * 4 + parentX, index * 4 + 2 + parentY);
|
||||||
audioLayer.Properties.X = oldX;
|
c.DrawLine(pen, point, new Point(parentX, index * 4 + 2 + parentY));
|
||||||
audioLayer.Properties.Y = oldY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,31 +72,39 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
|||||||
public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false)
|
public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false)
|
||||||
{
|
{
|
||||||
layerModel.ApplyProperties(true);
|
layerModel.ApplyProperties(true);
|
||||||
if (isPreview)
|
|
||||||
|
var direction = ((AudioPropertiesModel) layerModel.Properties).Direction;
|
||||||
|
|
||||||
|
int currentLines;
|
||||||
|
double currentHeight;
|
||||||
|
if (direction == Direction.BottomToTop || direction == Direction.TopToBottom)
|
||||||
|
{
|
||||||
|
currentLines = (int) layerModel.Width;
|
||||||
|
currentHeight = layerModel.Height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentLines = (int) layerModel.Height;
|
||||||
|
currentHeight = layerModel.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lines != currentLines)
|
||||||
|
{
|
||||||
|
_lines = currentLines;
|
||||||
|
_points = new Point[_lines];
|
||||||
|
_lineSpectrum = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let audio capture know it is being listened to
|
||||||
|
_audioCapture.Pulse();
|
||||||
|
|
||||||
|
if (_lineSpectrum == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Start audio capture in case it wasn't running
|
if (direction == Direction.BottomToTop || direction == Direction.TopToBottom)
|
||||||
_audioCapture.Start();
|
_lineSpectrum.UpdateLinesVertical(currentHeight, _points);
|
||||||
_audioCapture.MayStop = false;
|
else
|
||||||
|
_lineSpectrum.UpdateLinesHorizontal(currentHeight, _points);
|
||||||
lock (_audioLayers)
|
|
||||||
{
|
|
||||||
// Called every update but only runs every second
|
|
||||||
SetupLayers(layerModel);
|
|
||||||
|
|
||||||
var settings = (AudioPropertiesModel) layerModel.Properties;
|
|
||||||
switch (settings.Direction)
|
|
||||||
{
|
|
||||||
case Direction.TopToBottom:
|
|
||||||
case Direction.BottomToTop:
|
|
||||||
_lineSpectrum.SetupLayersVertical(layerModel.Height, _audioLayers);
|
|
||||||
break;
|
|
||||||
case Direction.LeftToRight:
|
|
||||||
case Direction.RightToLeft:
|
|
||||||
_lineSpectrum.SetupLayersHorizontal(layerModel.Width, _audioLayers);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetupProperties(LayerModel layerModel)
|
public void SetupProperties(LayerModel layerModel)
|
||||||
@ -125,82 +126,5 @@ namespace Artemis.Profiles.Layers.Types.Audio
|
|||||||
return layerPropertiesViewModel;
|
return layerPropertiesViewModel;
|
||||||
return new AudioPropertiesViewModel(layerEditorViewModel);
|
return new AudioPropertiesViewModel(layerEditorViewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets up the inner layers when the settings have changed
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="layerModel"></param>
|
|
||||||
private void SetupLayers(LayerModel layerModel)
|
|
||||||
{
|
|
||||||
// Checking on settings update is expensive, only do it every second
|
|
||||||
if (DateTime.Now - _lastUpdate < TimeSpan.FromSeconds(1))
|
|
||||||
return;
|
|
||||||
_lastUpdate = DateTime.Now;
|
|
||||||
|
|
||||||
var settings = (AudioPropertiesModel) layerModel.Properties;
|
|
||||||
var currentSettings = JsonConvert.SerializeObject(settings, Formatting.Indented);
|
|
||||||
var currentType = _audioLayers.FirstOrDefault()?.LayerAnimation?.GetType();
|
|
||||||
|
|
||||||
if (currentSettings == _previousSettings && layerModel.LayerAnimation.GetType() == currentType)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_previousSettings = JsonConvert.SerializeObject(settings, Formatting.Indented);
|
|
||||||
|
|
||||||
_audioLayers.Clear();
|
|
||||||
switch (settings.Direction)
|
|
||||||
{
|
|
||||||
case Direction.TopToBottom:
|
|
||||||
case Direction.BottomToTop:
|
|
||||||
SetupVertical(layerModel);
|
|
||||||
break;
|
|
||||||
case Direction.LeftToRight:
|
|
||||||
case Direction.RightToLeft:
|
|
||||||
SetupHorizontal(layerModel);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
_lineSpectrum = _audioCapture.GetLineSpectrum(_audioLayers.Count, 5, ScalingStrategy.Decibel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetupVertical(LayerModel layerModel)
|
|
||||||
{
|
|
||||||
_lines = (int) layerModel.Properties.Width;
|
|
||||||
for (var i = 0; i < _lines; i++)
|
|
||||||
{
|
|
||||||
var layer = LayerModel.CreateLayer();
|
|
||||||
layer.Properties.X = layerModel.Properties.X + i;
|
|
||||||
layer.Properties.Y = layerModel.Properties.Y;
|
|
||||||
layer.Properties.Width = 1;
|
|
||||||
layer.Properties.Height = 0;
|
|
||||||
layer.Properties.AnimationSpeed = layerModel.Properties.AnimationSpeed;
|
|
||||||
layer.Properties.Brush = layerModel.Properties.Brush;
|
|
||||||
layer.Properties.Contain = false;
|
|
||||||
layer.LayerAnimation = (ILayerAnimation) _kernel.Get(layerModel.LayerAnimation.GetType());
|
|
||||||
|
|
||||||
_audioLayers.Add(layer);
|
|
||||||
layer.Update(null, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetupHorizontal(LayerModel layerModel)
|
|
||||||
{
|
|
||||||
_lines = (int) layerModel.Properties.Height;
|
|
||||||
for (var i = 0; i < _lines; i++)
|
|
||||||
{
|
|
||||||
var layer = LayerModel.CreateLayer();
|
|
||||||
layer.Properties.X = layerModel.Properties.X;
|
|
||||||
layer.Properties.Y = layerModel.Properties.Y + i;
|
|
||||||
layer.Properties.Width = 0;
|
|
||||||
layer.Properties.Height = 1;
|
|
||||||
layer.Properties.AnimationSpeed = layerModel.Properties.AnimationSpeed;
|
|
||||||
layer.Properties.Brush = layerModel.Properties.Brush;
|
|
||||||
layer.Properties.Contain = false;
|
|
||||||
layer.LayerAnimation = (ILayerAnimation) _kernel.Get(layerModel.LayerAnimation.GetType());
|
|
||||||
|
|
||||||
_audioLayers.Add(layer);
|
|
||||||
layer.Update(null, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,8 +108,10 @@ namespace Artemis.Profiles
|
|||||||
Rect rect, bool preview)
|
Rect rect, bool preview)
|
||||||
{
|
{
|
||||||
renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList();
|
renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList();
|
||||||
|
if (!renderLayers.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
var visual = new DrawingVisual();
|
var visual = new DrawingVisual();
|
||||||
var layerModels = renderLayers.ToList();
|
|
||||||
using (var c = visual.RenderOpen())
|
using (var c = visual.RenderOpen())
|
||||||
{
|
{
|
||||||
// Setup the DrawingVisual's size
|
// Setup the DrawingVisual's size
|
||||||
@ -117,12 +119,12 @@ namespace Artemis.Profiles
|
|||||||
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, rect);
|
c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, rect);
|
||||||
|
|
||||||
// Update the layers
|
// Update the layers
|
||||||
foreach (var layerModel in layerModels)
|
foreach (var layerModel in renderLayers)
|
||||||
layerModel.Update(dataModel, preview, true);
|
layerModel.Update(dataModel, preview, true);
|
||||||
RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null));
|
RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null));
|
||||||
|
|
||||||
// Draw the layers
|
// Draw the layers
|
||||||
foreach (var layerModel in layerModels)
|
foreach (var layerModel in renderLayers)
|
||||||
layerModel.Draw(dataModel, c, preview, true);
|
layerModel.Draw(dataModel, c, preview, true);
|
||||||
RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c));
|
RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c));
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,7 @@ namespace Artemis.Utilities
|
|||||||
|
|
||||||
public static Bitmap DrawingVisualToBitmap(DrawingVisual visual, Rect rect)
|
public static Bitmap DrawingVisualToBitmap(DrawingVisual visual, Rect rect)
|
||||||
{
|
{
|
||||||
|
// TODO: Improve performance by dividing by 4 here
|
||||||
var bmp = new RenderTargetBitmap((int) rect.Width, (int) rect.Height, 96, 96, PixelFormats.Pbgra32);
|
var bmp = new RenderTargetBitmap((int) rect.Width, (int) rect.Height, 96, 96, PixelFormats.Pbgra32);
|
||||||
bmp.Render(visual);
|
bmp.Render(visual);
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Timers;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
@ -31,7 +30,6 @@ using DragDropEffects = System.Windows.DragDropEffects;
|
|||||||
using IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget;
|
using IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget;
|
||||||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||||
using Screen = Caliburn.Micro.Screen;
|
using Screen = Caliburn.Micro.Screen;
|
||||||
using Timer = System.Timers.Timer;
|
|
||||||
|
|
||||||
namespace Artemis.ViewModels.Profiles
|
namespace Artemis.ViewModels.Profiles
|
||||||
{
|
{
|
||||||
@ -41,7 +39,6 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
private readonly MetroDialogService _dialogService;
|
private readonly MetroDialogService _dialogService;
|
||||||
private readonly LuaManager _luaManager;
|
private readonly LuaManager _luaManager;
|
||||||
private readonly ModuleModel _moduleModel;
|
private readonly ModuleModel _moduleModel;
|
||||||
private readonly Timer _saveTimer;
|
|
||||||
private readonly WindowService _windowService;
|
private readonly WindowService _windowService;
|
||||||
private ImageSource _keyboardPreview;
|
private ImageSource _keyboardPreview;
|
||||||
private ObservableCollection<LayerModel> _layers;
|
private ObservableCollection<LayerModel> _layers;
|
||||||
@ -69,10 +66,6 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
_deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged;
|
_deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged;
|
||||||
_moduleModel.ProfileChanged += ModuleModelOnProfileChanged;
|
_moduleModel.ProfileChanged += ModuleModelOnProfileChanged;
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
|
|
||||||
_saveTimer = new Timer(5000);
|
|
||||||
_saveTimer.Elapsed += ProfileSaveHandler;
|
|
||||||
_saveTimer.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileViewModel ProfileViewModel { get; set; }
|
public ProfileViewModel ProfileViewModel { get; set; }
|
||||||
@ -695,11 +688,6 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
NotifyOfPropertyChange(() => LayerSelected);
|
NotifyOfPropertyChange(() => LayerSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileSaveHandler(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
SaveSelectedProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveSelectedProfile()
|
public void SaveSelectedProfile()
|
||||||
{
|
{
|
||||||
if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
|
if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
|
||||||
@ -779,9 +767,8 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
SaveSelectedProfile();
|
||||||
ProfileViewModel.Dispose();
|
ProfileViewModel.Dispose();
|
||||||
_saveTimer?.Stop();
|
|
||||||
_saveTimer?.Dispose();
|
|
||||||
_watcher?.Dispose();
|
_watcher?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -167,7 +167,7 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7));
|
new Point(layerRect.BottomRight.X - 0.7, layerRect.BottomRight.Y - 0.7));
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectedProfile.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(DrawType.Preview, null, true, drawingContext));
|
SelectedProfile?.RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(DrawType.Preview, null, true, drawingContext));
|
||||||
|
|
||||||
// Remove the clip
|
// Remove the clip
|
||||||
drawingContext.Pop();
|
drawingContext.Pop();
|
||||||
@ -380,7 +380,6 @@ namespace Artemis.ViewModels.Profiles
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_keyboardPreviewCursor?.Dispose();
|
|
||||||
_loopManager.RenderCompleted -= LoopManagerOnRenderCompleted;
|
_loopManager.RenderCompleted -= LoopManagerOnRenderCompleted;
|
||||||
_deviceManager.OnKeyboardChanged -= DeviceManagerOnOnKeyboardChanged;
|
_deviceManager.OnKeyboardChanged -= DeviceManagerOnOnKeyboardChanged;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user