1
0
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:
SpoinkyNL 2017-01-11 22:34:05 +01:00
parent 1fa6063706
commit 0656687b88
17 changed files with 232 additions and 208 deletions

View File

@ -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">

View File

@ -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();
} }

View File

@ -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);
} }
} }

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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>

View File

@ -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");
} }
} }
} }

View File

@ -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);

View File

@ -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");
}
}
} }
} }

View File

@ -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;
}
} }
} }
} }

View File

@ -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;
}
}
}

View File

@ -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);
}
}
} }
} }

View File

@ -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));

View File

@ -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);

View File

@ -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();
} }

View File

@ -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;
} }