From 0656687b881fd5bd00ffe61d1f6e3a8b8133b67a Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Wed, 11 Jan 2017 22:34:05 +0100 Subject: [PATCH] Audio layer progress --- Artemis/Artemis/Artemis.csproj | 1 + Artemis/Artemis/ArtemisBootstrapper.cs | 1 + Artemis/Artemis/DAL/ProfileProvider.cs | 2 +- .../DeviceProviders/Corsair/CorsairHeadset.cs | 2 +- .../DeviceProviders/Corsair/CorsairMouse.cs | 2 +- .../Corsair/CorsairMousemat.cs | 2 +- .../DeviceProviders/KeyboardProvider.cs | 5 +- .../Logitech/LogitechGeneric.cs | 2 +- Artemis/Artemis/Managers/ProfileManager.cs | 5 + .../Audio/AudioCapturing/AudioCapture.cs | 147 ++++++++++---- .../Audio/AudioCapturing/LineSpectrum.cs | 25 ++- .../Audio/AudioCapturing/SingleSpectrum.cs | 31 +++ .../Profiles/Layers/Types/Audio/AudioType.cs | 188 ++++++------------ Artemis/Artemis/Profiles/ProfileModel.cs | 8 +- Artemis/Artemis/Utilities/ImageUtilities.cs | 1 + .../Profiles/ProfileEditorViewModel.cs | 15 +- .../ViewModels/Profiles/ProfileViewModel.cs | 3 +- 17 files changed, 232 insertions(+), 208 deletions(-) create mode 100644 Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SingleSpectrum.cs diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index ab2de8b36..8f81676a9 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -494,6 +494,7 @@ + diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs index e15174d44..bfd41ad63 100644 --- a/Artemis/Artemis/ArtemisBootstrapper.cs +++ b/Artemis/Artemis/ArtemisBootstrapper.cs @@ -91,6 +91,7 @@ namespace Artemis JsonConvert.DefaultSettings = () => settings; //TODO DarthAffe 17.12.2016: Is this the right location for this? + //TODO Move to Mainmanager and make disposable ActiveWindowHelper.Initialize(); } diff --git a/Artemis/Artemis/DAL/ProfileProvider.cs b/Artemis/Artemis/DAL/ProfileProvider.cs index 547582dc0..2721ae7d6 100644 --- a/Artemis/Artemis/DAL/ProfileProvider.cs +++ b/Artemis/Artemis/DAL/ProfileProvider.cs @@ -89,7 +89,7 @@ namespace Artemis.DAL } 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); } } diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs index 908d4ae07..9883c0253 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairHeadset.cs @@ -34,7 +34,7 @@ namespace Artemis.DeviceProviders.Corsair 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) diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs index 7e18ba746..20767e34b 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMouse.cs @@ -34,7 +34,7 @@ namespace Artemis.DeviceProviders.Corsair 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) diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs index 3062862d5..421d3b958 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairMousemat.cs @@ -34,7 +34,7 @@ namespace Artemis.DeviceProviders.Corsair 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) diff --git a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs index afa83b09c..59b4889fa 100644 --- a/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs +++ b/Artemis/Artemis/DeviceProviders/KeyboardProvider.cs @@ -89,13 +89,12 @@ namespace Artemis.DeviceProviders 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() { - throw new NotImplementedException( - "KeyboardProvider doesn't implement TryEnable, use CanEnableAsync instead."); + throw new NotSupportedException("KeyboardProvider doesn't implement TryEnable, use CanEnableAsync instead."); } /// diff --git a/Artemis/Artemis/DeviceProviders/Logitech/LogitechGeneric.cs b/Artemis/Artemis/DeviceProviders/Logitech/LogitechGeneric.cs index 5da53fe28..9c978a791 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/LogitechGeneric.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/LogitechGeneric.cs @@ -49,7 +49,7 @@ namespace Artemis.DeviceProviders.Logitech public override void Disable() { - throw new NotImplementedException("Can only disable a keyboard"); + throw new NotSupportedException("Can only disable a keyboard"); } } } \ No newline at end of file diff --git a/Artemis/Artemis/Managers/ProfileManager.cs b/Artemis/Artemis/Managers/ProfileManager.cs index a28397959..ed0268ff8 100644 --- a/Artemis/Artemis/Managers/ProfileManager.cs +++ b/Artemis/Artemis/Managers/ProfileManager.cs @@ -76,6 +76,11 @@ namespace Artemis.Managers return; _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(); if (lastModule != null) _moduleManager.ChangeActiveModule(lastModule); diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs index a8602a20b..c1092fc31 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCapture.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Timers; using CSCore; using CSCore.CoreAudioAPI; @@ -12,32 +13,31 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing public class AudioCapture { 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 GainSource _source; private BasicSpectrumProvider _spectrumProvider; private GainSource _volume; - private Timer _timer; + private int _volumeIndex; public AudioCapture(ILogger logger, MMDevice device) { Logger = logger; Device = device; + DesiredAverage = 0.75; - _timer = new Timer(1000); - _timer.Elapsed += TimerOnElapsed; + _volumeValues = new double[5]; + _volumeIndex = 0; + _activityTimer = new Timer(1000); + _activityTimer.Elapsed += ActivityTimerOnElapsed; + _volumeTimer = new Timer(200); + _volumeTimer.Elapsed += VolumeTimerOnElapsed; } - private void TimerOnElapsed(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 double DesiredAverage { get; set; } public bool MayStop { get; set; } @@ -52,7 +52,64 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing public MMDevice Device { get; } 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) { @@ -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) return; + Logger.Debug("Starting audio capture for device: {0}", Device?.FriendlyName ?? "default"); + try { _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(); - _timer.Start(); Running = true; MayStop = false; } @@ -109,27 +200,5 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing 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"); - } - } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/LineSpectrum.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/LineSpectrum.cs index 39c900ea4..c4373e78b 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/LineSpectrum.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/LineSpectrum.cs @@ -1,6 +1,5 @@ using System; -using System.Collections.Generic; -using Artemis.Profiles.Layers.Models; +using System.Windows; using CSCore.DSP; namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing @@ -27,30 +26,36 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing } } - public void SetupLayersVertical(double height, List 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 if (!SpectrumProvider.GetFftData(fftBuffer, this)) return; var spectrumPoints = CalculateSpectrumPoints(height, fftBuffer); - foreach (var p in spectrumPoints) - audioLayers[p.SpectrumPointIndex].Height = p.Value; + for (var index = 0; index < spectrumPoints.Length; index++) + { + var spectrumPointData = spectrumPoints[index]; + points[index].Y = spectrumPointData.Value; + } } - public void SetupLayersHorizontal(double width, List 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 if (!SpectrumProvider.GetFftData(fftBuffer, this)) return; var spectrumPoints = CalculateSpectrumPoints(width, fftBuffer); - foreach (var p in spectrumPoints) - audioLayers[p.SpectrumPointIndex].Width = p.Value; + for (var index = 0; index < spectrumPoints.Length; index++) + { + var spectrumPointData = spectrumPoints[index]; + points[index].X = spectrumPointData.Value; + } } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SingleSpectrum.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SingleSpectrum.cs new file mode 100644 index 000000000..4757f1dfa --- /dev/null +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/SingleSpectrum.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs index 99879e224..f2d3dfde8 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows; +using System.Windows; using System.Windows.Media; using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; @@ -11,25 +8,18 @@ using Artemis.Profiles.Layers.Types.Audio.AudioCapturing; using Artemis.Properties; using Artemis.Utilities; using Artemis.ViewModels.Profiles; -using Newtonsoft.Json; -using Ninject; namespace Artemis.Profiles.Layers.Types.Audio { public class AudioType : ILayerType { - private readonly List _audioLayers = new List(); - private readonly IKernel _kernel; - - private DateTime _lastUpdate; + private readonly AudioCapture _audioCapture; private int _lines; - private string _previousSettings; 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); } @@ -52,26 +42,29 @@ namespace Artemis.Profiles.Layers.Types.Audio 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 oldWidth = audioLayer.Properties.Width; - var oldHeight = audioLayer.Properties.Height; - var oldX = audioLayer.Properties.X; - var oldY = audioLayer.Properties.Y; - - audioLayer.Properties.Width = layerModel.Properties.Width; - audioLayer.Properties.Height = layerModel.Properties.Height; - audioLayer.Properties.X = layerModel.Properties.X; - audioLayer.Properties.Y = layerModel.Properties.Y; - audioLayer.LayerType.Draw(audioLayer, c); - - audioLayer.Properties.Width = oldWidth; - audioLayer.Properties.Height = oldHeight; - audioLayer.Properties.X = oldX; - audioLayer.Properties.Y = oldY; + var startPoint = new Point(index * 4 + 2 + parentX, _points[index].Y * 4 + parentY); + var endPoint = new Point(index * 4 + 2 + parentX, parentY); + var clip = new Rect(startPoint, endPoint); + clip.Width = 4; + c.PushClip(new RectangleGeometry(new Rect(startPoint, endPoint))); + var point = new Point(index * 4 + 2 + parentX, _points[index].Y * 4 + parentY); + c.DrawLine(pen, startPoint, endPoint); + } + } + else + { + for (var index = 0; index < _points.Length; index++) + { + var point = new Point(_points[index].X * 4 + parentX, index * 4 + 2 + parentY); + c.DrawLine(pen, point, new Point(parentX, index * 4 + 2 + parentY)); } } } @@ -79,31 +72,39 @@ namespace Artemis.Profiles.Layers.Types.Audio public void Update(LayerModel layerModel, ModuleDataModel dataModel, bool isPreview = false) { 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; - // Start audio capture in case it wasn't running - _audioCapture.Start(); - _audioCapture.MayStop = false; - - 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; - } - } + if (direction == Direction.BottomToTop || direction == Direction.TopToBottom) + _lineSpectrum.UpdateLinesVertical(currentHeight, _points); + else + _lineSpectrum.UpdateLinesHorizontal(currentHeight, _points); } public void SetupProperties(LayerModel layerModel) @@ -125,82 +126,5 @@ namespace Artemis.Profiles.Layers.Types.Audio return layerPropertiesViewModel; return new AudioPropertiesViewModel(layerEditorViewModel); } - - /// - /// Sets up the inner layers when the settings have changed - /// - /// - 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); - } - } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs index 0f076058a..5dd3cbfed 100644 --- a/Artemis/Artemis/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Profiles/ProfileModel.cs @@ -108,8 +108,10 @@ namespace Artemis.Profiles Rect rect, bool preview) { renderLayers = renderLayers.Where(rl => rl.LayerType.DrawType == drawType).ToList(); + if (!renderLayers.Any()) + return; + var visual = new DrawingVisual(); - var layerModels = renderLayers.ToList(); using (var c = visual.RenderOpen()) { // Setup the DrawingVisual's size @@ -117,12 +119,12 @@ namespace Artemis.Profiles c.DrawRectangle(new SolidColorBrush(Color.FromArgb(0, 0, 0, 0)), null, rect); // Update the layers - foreach (var layerModel in layerModels) + foreach (var layerModel in renderLayers) layerModel.Update(dataModel, preview, true); RaiseDeviceUpdatedEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, null)); // Draw the layers - foreach (var layerModel in layerModels) + foreach (var layerModel in renderLayers) layerModel.Draw(dataModel, c, preview, true); RaiseDeviceDrawnEvent(new ProfileDeviceEventsArg(drawType, dataModel, preview, c)); diff --git a/Artemis/Artemis/Utilities/ImageUtilities.cs b/Artemis/Artemis/Utilities/ImageUtilities.cs index 51fc2f66f..d8ac1122d 100644 --- a/Artemis/Artemis/Utilities/ImageUtilities.cs +++ b/Artemis/Artemis/Utilities/ImageUtilities.cs @@ -56,6 +56,7 @@ namespace Artemis.Utilities 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); bmp.Render(visual); diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs index 13afbfbd3..af0659dd9 100644 --- a/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/ProfileEditorViewModel.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Timers; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media; @@ -31,7 +30,6 @@ using DragDropEffects = System.Windows.DragDropEffects; using IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget; using MouseEventArgs = System.Windows.Input.MouseEventArgs; using Screen = Caliburn.Micro.Screen; -using Timer = System.Timers.Timer; namespace Artemis.ViewModels.Profiles { @@ -41,7 +39,6 @@ namespace Artemis.ViewModels.Profiles private readonly MetroDialogService _dialogService; private readonly LuaManager _luaManager; private readonly ModuleModel _moduleModel; - private readonly Timer _saveTimer; private readonly WindowService _windowService; private ImageSource _keyboardPreview; private ObservableCollection _layers; @@ -69,10 +66,6 @@ namespace Artemis.ViewModels.Profiles _deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; _moduleModel.ProfileChanged += ModuleModelOnProfileChanged; LoadProfiles(); - - _saveTimer = new Timer(5000); - _saveTimer.Elapsed += ProfileSaveHandler; - _saveTimer.Start(); } public ProfileViewModel ProfileViewModel { get; set; } @@ -695,11 +688,6 @@ namespace Artemis.ViewModels.Profiles NotifyOfPropertyChange(() => LayerSelected); } - private void ProfileSaveHandler(object sender, ElapsedEventArgs e) - { - SaveSelectedProfile(); - } - public void SaveSelectedProfile() { if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard) @@ -779,9 +767,8 @@ namespace Artemis.ViewModels.Profiles public void Dispose() { + SaveSelectedProfile(); ProfileViewModel.Dispose(); - _saveTimer?.Stop(); - _saveTimer?.Dispose(); _watcher?.Dispose(); } diff --git a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs index 0df27992d..bc74299a0 100644 --- a/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/ProfileViewModel.cs @@ -167,7 +167,7 @@ namespace Artemis.ViewModels.Profiles 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 drawingContext.Pop(); @@ -380,7 +380,6 @@ namespace Artemis.ViewModels.Profiles public void Dispose() { - _keyboardPreviewCursor?.Dispose(); _loopManager.RenderCompleted -= LoopManagerOnRenderCompleted; _deviceManager.OnKeyboardChanged -= DeviceManagerOnOnKeyboardChanged; }