diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index 6452856de..c18676f4b 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -493,6 +493,7 @@ + diff --git a/Artemis/Artemis/Events/AudioDeviceChangedEventArgs.cs b/Artemis/Artemis/Events/AudioDeviceChangedEventArgs.cs new file mode 100644 index 000000000..05977f452 --- /dev/null +++ b/Artemis/Artemis/Events/AudioDeviceChangedEventArgs.cs @@ -0,0 +1,17 @@ +using System; +using CSCore.CoreAudioAPI; + +namespace Artemis.Events +{ + public class AudioDeviceChangedEventArgs : EventArgs + { + public AudioDeviceChangedEventArgs(MMDevice defaultPlayback, MMDevice defaultRecording) + { + DefaultPlayback = defaultPlayback; + DefaultRecording = defaultRecording; + } + + public MMDevice DefaultPlayback { get; } + public MMDevice DefaultRecording { get; } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs index cece1ddb0..cf7d34ee5 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioCapturing/AudioCaptureManager.cs @@ -1,5 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Timers; +using Artemis.Events; using CSCore.CoreAudioAPI; using Ninject.Extensions.Logging; @@ -8,17 +11,41 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing public class AudioCaptureManager { private readonly List _audioCaptures; + private MMDevice _lastDefaultPlayback; + private MMDevice _lastDefaultRecording; public AudioCaptureManager(ILogger logger) { Logger = logger; _audioCaptures = new List(); + _lastDefaultPlayback = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); + _lastDefaultRecording = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia); + + var defaultDeviceTimer = new Timer(1000); + defaultDeviceTimer.Elapsed += DefaultDeviceTimerOnElapsed; + defaultDeviceTimer.Start(); + } + + public event EventHandler AudioDeviceChanged; + + private void DefaultDeviceTimerOnElapsed(object sender, ElapsedEventArgs e) + { + var defaultPlayback = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); + var defaultRecording = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia); + + if (defaultPlayback.DeviceID == _lastDefaultPlayback.DeviceID && + defaultRecording.DeviceID == _lastDefaultRecording.DeviceID) + return; + + _lastDefaultPlayback = defaultPlayback; + _lastDefaultRecording = defaultRecording; + OnAudioDeviceChanged(new AudioDeviceChangedEventArgs(_lastDefaultPlayback, _lastDefaultRecording)); } public AudioCapture GetAudioCapture(MMDevice device) { // Return existing audio capture if found - var audioCapture = _audioCaptures.FirstOrDefault(a => a.Device == device); + var audioCapture = _audioCaptures.FirstOrDefault(a => a.Device.DeviceID == device.DeviceID); if (audioCapture != null) return audioCapture; @@ -29,5 +56,10 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing } public ILogger Logger { get; set; } + + protected virtual void OnAudioDeviceChanged(AudioDeviceChangedEventArgs e) + { + AudioDeviceChanged?.Invoke(this, e); + } } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesModel.cs index 1c2b2b9be..f7768e3ff 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioPropertiesModel.cs @@ -9,9 +9,23 @@ namespace Artemis.Profiles.Layers.Types.Audio { } - public int Sensitivity { get; set; } - public double FadeSpeed { get; set; } + [DefaultValue(MmDeviceType.Ouput)] + public MmDeviceType DeviceType { get; set; } + + [DefaultValue("Default")] + public string Device { get; set; } + + [DefaultValue(Direction.BottomToTop)] public Direction Direction { get; set; } + + [DefaultValue(ScalingStrategy.Decibel)] + public ScalingStrategy ScalingStrategy { get; set; } + } + + public enum MmDeviceType + { + [Description("Ouput")] Ouput, + [Description("Input")] Input } public enum Direction diff --git a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs index a115f9bcb..2e52bff3c 100644 --- a/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs +++ b/Artemis/Artemis/Profiles/Layers/Types/Audio/AudioType.cs @@ -1,6 +1,10 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; using System.Windows; using System.Windows.Media; +using Artemis.Events; using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Abstract; using Artemis.Profiles.Layers.Animations; @@ -11,20 +15,35 @@ using Artemis.Properties; using Artemis.Utilities; using Artemis.ViewModels; using Artemis.ViewModels.Profiles; +using CSCore.CoreAudioAPI; namespace Artemis.Profiles.Layers.Types.Audio { public class AudioType : ILayerType { + private readonly AudioCaptureManager _audioCaptureManager; private const GeometryCombineMode CombineMode = GeometryCombineMode.Union; - private readonly AudioCapture _audioCapture; + private AudioCapture _audioCapture; private int _lines; private LineSpectrum _lineSpectrum; private List _lineValues; + private int _drawCount; public AudioType(AudioCaptureManager audioCaptureManager) { - _audioCapture = audioCaptureManager.GetAudioCapture(null); + _audioCaptureManager = audioCaptureManager; + + // TODO: Setup according to settings + _audioCapture = _audioCaptureManager.GetAudioCapture(MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia)); + _audioCaptureManager.AudioDeviceChanged += OnAudioDeviceChanged; + } + + private void OnAudioDeviceChanged(object sender, AudioDeviceChangedEventArgs e) + { + // TODO: Check if layer must use default + // TODO: Check recording type + _audioCapture = _audioCaptureManager.GetAudioCapture(e.DefaultPlayback); + _lines = 0; } public string Name => "Keyboard - Audio visualization"; @@ -46,6 +65,7 @@ namespace Artemis.Profiles.Layers.Types.Audio public void Draw(LayerModel layerModel, DrawingContext c) { + _drawCount++; if (_lineValues == null) return; @@ -136,8 +156,10 @@ namespace Artemis.Profiles.Layers.Types.Audio layerModel.Properties = new AudioPropertiesModel(layerModel.Properties) { - FadeSpeed = 0.2, - Sensitivity = 2 + DeviceType = MmDeviceType.Ouput, + Device = "Default", + Direction = Direction.BottomToTop, + ScalingStrategy = ScalingStrategy.Decibel }; }