From 8ecaff872264503a669ca36563c505110849bb69 Mon Sep 17 00:00:00 2001 From: TCBSnowsun Date: Wed, 16 Aug 2017 18:05:45 +0200 Subject: [PATCH] Implement Novation device detection (at start only Launchpad S supported) and implement updating of leds --- RGB.NET.Core/Extensions/EnumExtensions.cs | 21 ++++++++ RGB.NET.Core/RGB.NET.Core.csproj | 1 + .../Enum/NovationDevices.cs | 10 ++++ .../Generic/NovationRGBDevice.cs | 52 ++++++++++++++++++- .../Generic/NovationRGBDeviceInfo.cs | 6 ++- .../Launchpad/NovationLaunchpadRGBDevice.cs | 1 + .../NovationLaunchpadRGBDeviceInfo.cs | 5 +- .../NovationDeviceProvider.cs | 31 +++++++---- .../RGB.NET.Devices.Novation.csproj | 5 ++ RGB.NET.Devices.Novation/packages.config | 1 + 10 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 RGB.NET.Core/Extensions/EnumExtensions.cs create mode 100644 RGB.NET.Devices.Novation/Enum/NovationDevices.cs diff --git a/RGB.NET.Core/Extensions/EnumExtensions.cs b/RGB.NET.Core/Extensions/EnumExtensions.cs new file mode 100644 index 0000000..2122229 --- /dev/null +++ b/RGB.NET.Core/Extensions/EnumExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; +using System.Reflection; +namespace RGB.NET.Core.Extensions +{ + public static class EnumExtensions + { + /// + /// A generic extension method that aids in reflecting + /// and retrieving any attribute that is applied to an `Enum`. + /// + public static TAttribute GetAttribute(this Enum enumValue) + where TAttribute : Attribute + { + return enumValue.GetType() + .GetMember(enumValue.ToString()) + .First() + .GetCustomAttribute(); + } + } +} diff --git a/RGB.NET.Core/RGB.NET.Core.csproj b/RGB.NET.Core/RGB.NET.Core.csproj index f4cb0ae..5f6b550 100644 --- a/RGB.NET.Core/RGB.NET.Core.csproj +++ b/RGB.NET.Core/RGB.NET.Core.csproj @@ -54,6 +54,7 @@ + diff --git a/RGB.NET.Devices.Novation/Enum/NovationDevices.cs b/RGB.NET.Devices.Novation/Enum/NovationDevices.cs new file mode 100644 index 0000000..a61474d --- /dev/null +++ b/RGB.NET.Devices.Novation/Enum/NovationDevices.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations; + +namespace RGB.NET.Devices.Novation +{ + public enum NovationDevices + { + [Display(Name = "Launchpad S")] + LaunchpadS + } +} diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs index 4c3db2b..c2b9a7c 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using RGB.NET.Core; using RGB.NET.Core.Layout; +using Sanford.Multimedia.Midi; namespace RGB.NET.Devices.Novation { @@ -13,6 +14,9 @@ namespace RGB.NET.Devices.Novation public abstract class NovationRGBDevice : AbstractRGBDevice { #region Properties & Fields + + private readonly OutputDevice _outputDevice; + /// /// Gets information about the . /// @@ -29,6 +33,7 @@ namespace RGB.NET.Devices.Novation protected NovationRGBDevice(IRGBDeviceInfo info) { this.DeviceInfo = info; + _outputDevice = new OutputDevice(((NovationRGBDeviceInfo)DeviceInfo).DeviceId); } #endregion @@ -104,14 +109,57 @@ namespace RGB.NET.Devices.Novation if (leds.Count > 0) { - //TODO DarthAffe 15.08.2017: Update Leds + foreach (Led led in leds) + { + NovationLedId ledId = (NovationLedId)led.Id; + + int color = 0; + + if (led.Color.R > 0) + { + color = 1; + + if (led.Color.R > 127) + color = 2; + if (led.Color.R == 255) + color = 3; + } + + if (led.Color.G > 0) + { + color = 16; + + if (led.Color.G > 127) + color = 32; + if (led.Color.G == 255) + color = 48; + } + + if ((led.Color.R > 0) && (led.Color.G > 0)) + { + color = 17; + + if(((led.Color.R > 127) && (led.Color.G < 127)) || ((led.Color.R < 127) && (led.Color.G > 127))) + color = 34; + if((led.Color.R > 127) && (led.Color.G > 127)) + color = 51; + } + + SendMessage(ledId.LedId.GetStatus(), ledId.LedId.GetId(), color); + } } } + private void SendMessage(int status, int data1, int data2) + { + ShortMessage shortMessage = new ShortMessage(Convert.ToByte(status), Convert.ToByte(data1), Convert.ToByte(data2)); + _outputDevice.SendShort(shortMessage.Message); + } + /// public override void Dispose() { - //TODO DarthAffe 15.08.2017: Dispose + _outputDevice.Dispose(); base.Dispose(); } diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs index 7384f03..d95cb42 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs @@ -25,6 +25,9 @@ namespace RGB.NET.Devices.Novation /// public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public int DeviceId { get; } + #endregion #region Constructors @@ -34,10 +37,11 @@ namespace RGB.NET.Devices.Novation /// /// The type of the . /// The represented device model. - internal NovationRGBDeviceInfo(RGBDeviceType deviceType, string model) + internal NovationRGBDeviceInfo(RGBDeviceType deviceType, string model, int deviceId) { this.DeviceType = deviceType; this.Model = model; + this.DeviceId = deviceId; } #endregion diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs index 7b69ca5..8cc5435 100644 --- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs @@ -1,5 +1,6 @@ using System; using RGB.NET.Core; +using Sanford.Multimedia.Midi; namespace RGB.NET.Devices.Novation { diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs index 82f81f9..cf134ec 100644 --- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs @@ -14,8 +14,9 @@ namespace RGB.NET.Devices.Novation /// Internal constructor of managed . /// /// The represented device model. - internal NovationLaunchpadRGBDeviceInfo(string model) - : base(RGBDeviceType.LedMatrix, model) + /// + internal NovationLaunchpadRGBDeviceInfo(string model, int deviceId) + : base(RGBDeviceType.LedMatrix, model, deviceId) { Image = new Uri(PathHelper.GetAbsolutePath($@"Images\Novation\Launchpads\{Model.Replace(" ", string.Empty).ToUpper()}.png"), UriKind.Absolute); } diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs index 72676c9..604d60c 100644 --- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs +++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel.DataAnnotations; using RGB.NET.Core; +using RGB.NET.Core.Extensions; +using Sanford.Multimedia.Midi; namespace RGB.NET.Devices.Novation { @@ -46,6 +49,7 @@ namespace RGB.NET.Devices.Novation #region Methods + /// public bool Initialize(bool exclusiveAccessIfPossible = false, bool throwExceptions = false) { IsInitialized = false; @@ -54,21 +58,24 @@ namespace RGB.NET.Devices.Novation { IList devices = new List(); - //TODO DarthAffe 15.08.2017: Get devices - // foreach ... try { - NovationRGBDevice device = null; - device = new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo("Launchpad S")); - device.Initialize(); - devices.Add(device); + for (int index = 0; index < OutputDeviceBase.DeviceCount; index++) + { + MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index); + + if (outCaps.name.Equals(NovationDevices.LaunchpadS.GetAttribute().Name)) + { + NovationRGBDevice device = new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index)); + device.Initialize(); + devices.Add(device); + } + } } catch { if (throwExceptions) throw; - //else - //continue; } Devices = new ReadOnlyCollection(devices); @@ -86,9 +93,15 @@ namespace RGB.NET.Devices.Novation return true; } + /// public void ResetDevices() { - //TODO DarthAffe 15.08.2017: Is this possible? + foreach (IRGBDevice device in Devices) + { + NovationLaunchpadRGBDeviceInfo deviceInfo = (NovationLaunchpadRGBDeviceInfo)device.DeviceInfo; + OutputDevice outputDevice = new OutputDevice(deviceInfo.DeviceId); + outputDevice.Reset(); + } } #endregion diff --git a/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj b/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj index 6cc41d6..5f5ad76 100644 --- a/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj +++ b/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj @@ -32,7 +32,11 @@ ..\bin\RGB.NET.Devices.Novation.XML + + ..\packages\Sanford.Multimedia.Midi.6.4.1\lib\net20\Sanford.Multimedia.Midi.dll + + ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll @@ -45,6 +49,7 @@ + diff --git a/RGB.NET.Devices.Novation/packages.config b/RGB.NET.Devices.Novation/packages.config index a59695c..a386c00 100644 --- a/RGB.NET.Devices.Novation/packages.config +++ b/RGB.NET.Devices.Novation/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file