public ScreenColourUI(ScreenColourSettings settings, MaxLifxBulbController bulbController) { InitializeComponent(); SuspendUI = true; Settings = settings; BulbController = bulbController; SetPositionTextBoxesFromSettings(); SetupLabels(lbLabels, Settings.LabelsAndLocations.Select(x => x.Label).ToList(), Settings); SuspendUI = false; }
public void SoundGenerator(MaxLifxBulbController bulbController, Random random) { _r = random; if (Settings == null) { Settings = new SoundGeneratorSettings(); } var f = Directory.GetFiles( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MaxLifx\\Sounds\\Loops", "*.wav"); var enu = f.GetEnumerator(); while (enu.MoveNext()) { SettingsCast.Sounds.Add( new Sound( enu.Current.ToString() .Replace( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MaxLifx\\Sounds\\Loops\\", "") .Replace(".wav", ""), enu.Current.ToString(), Sound.SoundTypes.Looping)); } f = Directory.GetFiles( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MaxLifx\\Sounds\\Random", "*.wav"); enu = f.GetEnumerator(); while (enu.MoveNext()) { SettingsCast.Sounds.Add( new Sound( enu.Current.ToString() .Replace( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MaxLifx\\Sounds\\Random\\", "") .Replace(".wav", ""), enu.Current.ToString(), Sound.SoundTypes.Random)); } var de = new MMDeviceEnumerator(); de.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); DoMainLoop(); }
public void ScreenColour(MaxLifxBulbController bulbController, Random random) { var frames = 0; var start = DateTime.Now; if (Settings == null) { Settings = new ScreenColourSettings(); } foreach (var bulb in bulbController.Bulbs.Select(x => x)) { if (!SettingsCast.LabelsAndLocations.Select(x => x.Label).Contains(bulb.Label)) { // populating SettingsCast fields var l = new LabelAndLocationType(); l.Label = bulb.Label; l.ScreenLocation = ScreenLocation.All; l.Zones = bulb.Zones; // default to None if more than 1 zone, so that can proper setup if (bulb.Zones > 1) { l.ScreenLocation = ScreenLocation.None; // if multizone enabled keep track of number of zones SettingsCast.MultiColourZones.Add(bulb.Zones); } SettingsCast.LabelsAndLocations.Add(l); } } while (!TerminateThread) { // check if area has changed if (TopLeft == SettingsCast.TopLeft && BottomRight == SettingsCast.BottomRight) { DoMainLoop(bulbController, ref frames, start); } else { // if it has changed then recalculate zones and set zoneCalculation(); TopLeft = SettingsCast.TopLeft; BottomRight = SettingsCast.BottomRight; } } }
public void ScreenColour(MaxLifxBulbController bulbController, Random random) { var frames = 0; var start = DateTime.Now; if (Settings == null) { Settings = new ScreenColourSettings(); } foreach (var label in bulbController.Bulbs.Select(x => x.Label)) { if (!SettingsCast.LabelsAndLocations.Select(x => x.Label).Contains(label)) { var l = new LabelAndLocationType(); l.Label = label; l.ScreenLocation = ScreenLocation.All; SettingsCast.LabelsAndLocations.Add(l); } } var payload = new SetColourPayload { Kelvin = 3500, TransitionDuration = (uint)(SettingsCast.Fade) }; while (!TerminateThread) { using (var screenPixel = new Bitmap(CaptureResolution.Width, CaptureResolution.Height, PixelFormat.Format32bppArgb)) { using (var gdest = Graphics.FromImage(screenPixel)) { using (var gsrc = Graphics.FromHwnd(IntPtr.Zero)) { DoMainLoop(bulbController, ref frames, start, ref payload, screenPixel, gdest, gsrc); } } } } }
public void SoundResponse(MaxLifxBulbController bulbController, Random random) { r = random; if (Settings == null) { Settings = new SoundResponseSettings(); SettingsCast.Hues.Add(0); SettingsCast.HueRanges.Add(0); SettingsCast.Saturations.Add(0); SettingsCast.SaturationRanges.Add(0); SettingsCast.Brightnesses.Add(.9f); SettingsCast.BrightnessRanges.Add(.1f); SettingsCast.Levels.Add(50); SettingsCast.LevelRanges.Add(25); SettingsCast.Bins.Add(10); } var de = new MMDeviceEnumerator(); var device = de.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); DoMainLoop(bulbController, device); }
private void DoMainLoop(MaxLifxBulbController bulbController, MMDevice device) { SettingsCast.WaveStartTime = DateTime.Now; var persistentFloatH = (float)r.NextDouble(); var persistentFloatS = (float)r.NextDouble(); var persistentFloatB = (float)r.NextDouble(); var persistedSince = DateTime.Now; var spectrumEngine = new SpectrumAnalyserEngine(); spectrumEngine.StartCapture(); while (!TerminateThread) { if (ShowUI) { var t = new Thread(() => { var form = new SoundResponseUI(SettingsCast, bulbController.Bulbs.Select(x => x.Label).ToList(), r); /* (SettingsCast, bulbController.Bulbs);*/ form.ShowDialog(); }); t.Start(); ShowUI = false; } var _offOrOn = Settings.OffOrOn(); if (_offOrOn) { ushort brightness = 0; ushort saturation = 0; var _hue = 0; var timeRunning = DateTime.Now - SettingsCast.WaveStartTime; var floatValueH = 0f; var floatValueS = 0f; var floatValueB = 0f; var bulbCtr = 0; foreach (var label in SettingsCast.SelectedLabels) { var bulbNumber = SettingsCast.PerBulb ? bulbCtr : 0; // don't raise an exception if there's no input... if (bulbNumber >= SettingsCast.Levels.Count) { continue; } try { switch (SettingsCast.WaveType) { case WaveTypes.Audio: var levelMin = 1 - (((float)(SettingsCast.Levels[bulbNumber] + SettingsCast.LevelRanges[bulbNumber] / 2 > 255 ? 255 : SettingsCast.Levels[bulbNumber] + SettingsCast.LevelRanges[bulbNumber] / 2) / 255)); var levelMax = 1 - (((float)(SettingsCast.Levels[bulbNumber] - SettingsCast.LevelRanges[bulbNumber] / 2 < 0 ? 0 : SettingsCast.Levels[bulbNumber] - SettingsCast.LevelRanges[bulbNumber] / 2) / 255)); var levelRange = levelMax - levelMin; float rawLevel; // don't raise an exception if there's no input... if (SettingsCast.Bins[bulbNumber] > spectrumEngine.LatestPoints.Count - 1) { rawLevel = 0; } else { rawLevel = 1 - (spectrumEngine.LatestPoints[SettingsCast.Bins[bulbNumber]].Y / 255); } float adjustedLevel; if (rawLevel < levelMin) { adjustedLevel = 0; } else if (rawLevel > levelMax) { adjustedLevel = 1; } else { adjustedLevel = (rawLevel - levelMin) / levelRange; if (adjustedLevel < 0 || adjustedLevel > 1) { MessageBox.Show("D'oh!"); } } floatValueH = floatValueS = floatValueB = adjustedLevel; // device.AudioMeterInformation.MasterPeakValue; break; case WaveTypes.Sine: floatValueH = floatValueS = floatValueB = (float) (Math.Sin(timeRunning.TotalSeconds * 6.283 * 500 / SettingsCast.WaveDuration) + 1) / 2; break; case WaveTypes.Square: floatValueH = floatValueS = floatValueB = ((int)(timeRunning.TotalMilliseconds / SettingsCast.WaveDuration)) % 2; break; case WaveTypes.Sawtooth: floatValueH = floatValueS = floatValueB = ((float)timeRunning.TotalMilliseconds - (((int)timeRunning.TotalMilliseconds / SettingsCast.WaveDuration) * SettingsCast.WaveDuration)) / SettingsCast.WaveDuration; break; case WaveTypes.Noise: var span = DateTime.Now - persistedSince; if (span.TotalMilliseconds > SettingsCast.WaveDuration) { floatValueH = (float)r.NextDouble(); floatValueS = (float)r.NextDouble(); floatValueB = (float)r.NextDouble(); persistentFloatH = floatValueH; persistentFloatS = floatValueS; persistentFloatB = floatValueB; persistedSince = DateTime.Now; } else { floatValueH = persistentFloatH; floatValueS = persistentFloatS; floatValueB = persistentFloatB; } break; } if (SettingsCast.Hues.Count > bulbNumber) { brightness = (ushort) (((SettingsCast.BrightnessInvert ? 1 - floatValueB : floatValueB) * SettingsCast.BrightnessRanges[bulbNumber] * 2 + (SettingsCast.Brightnesses[bulbNumber] - SettingsCast.BrightnessRanges[bulbNumber])) * 65535); saturation = (ushort) (((SettingsCast.SaturationInvert ? 1 - floatValueS : floatValueS) * SettingsCast.SaturationRanges[bulbNumber] * 2 + (SettingsCast.Saturations[bulbNumber] - SettingsCast.SaturationRanges[bulbNumber])) * 65535); _hue = ((int) ((SettingsCast.HueInvert ? 1 - floatValueH : floatValueH) * SettingsCast.HueRanges[bulbNumber] * 2 + (SettingsCast.Hues[bulbNumber] - SettingsCast.HueRanges[0])) + 720) % 360; var _payload = new SetColourPayload { Hue = _hue, Saturation = saturation, Brightness = brightness, Kelvin = SettingsCast.Kelvin, TransitionDuration = (uint)SettingsCast.TransitionDuration }; bulbController.SetColour(label, _payload, true); if (SettingsCast.Delay > 200) { bulbController.SetColour(label, _payload, true); Thread.Sleep(1); } } else { Thread.Sleep(1); } } catch (ArgumentOutOfRangeException) { Thread.Sleep(1); } Thread.Sleep(1); bulbCtr++; } } Thread.Sleep(SettingsCast.Delay); } spectrumEngine.StopCapture(); }
// this is where the actual colours are determined and set for the bulbs private void DoMainLoop(MaxLifxBulbController bulbController, ref int frames, DateTime start) { if (ShowUI) { var t = new Thread(() => { var form2 = new ScreenColourUI(SettingsCast, bulbController); /* (SettingsCast, bulbController.Bulbs);*/ form2.ShowDialog(); }); t.Start(); ShowUI = false; } frames++; // determine colours on screen // var screenColourSet = GetScreenColours(SettingsCast.TopLeft, SettingsCast.BottomRight, screenPixel, gdest, gsrc); Color? avgColour = null; ScreenColorSet screenColourSet = null; foreach (var label in SettingsCast.SelectedLabels) { var multiFlag = false; var labelsAndLocations = SettingsCast.LabelsAndLocations.Single(x => x.Label == label); var location = labelsAndLocations.ScreenLocation; var zones = labelsAndLocations.Zones; // skip if set to None if (location == ScreenLocation.None) { continue; } if (zones > 1) { List <Rectangle> rectList = null; bool found = false; // try and grab the zones switch (location) { case ScreenLocation.SurroundCounterClockwise: found = ZoneAreas.TryGetValue(zones.ToString() + "ccw", out rectList); break; case ScreenLocation.SurroundClockwise: found = ZoneAreas.TryGetValue(zones.ToString() + "cw", out rectList); break; // for all other ScreenLocations we skip } if (found) { // our average colour pixel var screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb); var gdest = Graphics.FromImage(screenPixel); var gsrc = Graphics.FromHwnd(IntPtr.Zero); var srcData = screenPixel.LockBits( new Rectangle(0, 0, screenPixel.Width, screenPixel.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); screenPixel.UnlockBits(srcData); for (int i = 0; i < zones; i++) { var areaColour = GetScreenColourZones(rectList[i], srcData, gdest, gsrc); // code for using most dominant colour; doesn't look very good tbh /*var bmpScreenshot = new Bitmap(rectList[i].Width, rectList[i].Height, PixelFormat.Format32bppArgb); * var gfxScreenshot = Graphics.FromImage(bmpScreenshot); * gfxScreenshot.CopyFromScreen(rectList[i].X, rectList[i].Y, 0, 0, rectList[i].Size, CopyPixelOperation.SourceCopy); * Bitmap resized = new Bitmap(bmpScreenshot, new Size(bmpScreenshot.Width / 3, bmpScreenshot.Height / 3)); * var areaColour = dominantColour(resized);*/ if (areaColour != null) { Color avgZoneColour = (Color)areaColour; // Color isn't HSV, so need to convert double hue = 0; double saturation = 0; double brightness = 0; Utils.ColorToHSV((Color)avgZoneColour, out hue, out saturation, out brightness); brightness = (brightness * (SettingsCast.Brightness - SettingsCast.MinBrightness) + SettingsCast.MinBrightness); saturation = (saturation * (SettingsCast.Saturation - SettingsCast.MinSaturation) + SettingsCast.MinSaturation); var zonePayload = new SetColourZonesPayload { start_index = new byte[1] { (byte)(i) }, end_index = new byte[1] { (byte)(i) }, Kelvin = (ushort)SettingsCast.Kelvin, TransitionDuration = (uint)(SettingsCast.Fade), Hue = (int)hue, Saturation = (ushort)saturation, Brightness = (ushort)brightness, // 0 for delayed apply; 1 for immediate (don't wait for other zones); apply = new byte[1] { 1 } }; // send bulbController.SetColour(label, zonePayload, false); } } multiFlag = true; } } // only do this calc if necessary if (!multiFlag) { // set once var screenPixel = new Bitmap(2, 2, PixelFormat.Format32bppArgb); var gdest = Graphics.FromImage(screenPixel); var gsrc = Graphics.FromHwnd(IntPtr.Zero); screenColourSet = GetScreenColours(SettingsCast.TopLeft, SettingsCast.BottomRight, screenPixel, gdest, gsrc); // default is all avgColour = screenColourSet.all; switch (location) { case ScreenLocation.Top: avgColour = screenColourSet.top; break; case ScreenLocation.Bottom: avgColour = screenColourSet.bottom; break; case ScreenLocation.Left: avgColour = screenColourSet.left; break; case ScreenLocation.Right: avgColour = screenColourSet.right; break; case ScreenLocation.TopLeft: avgColour = screenColourSet.topleft; break; case ScreenLocation.TopRight: avgColour = screenColourSet.topright; break; case ScreenLocation.BottomLeft: avgColour = screenColourSet.bottomleft; break; case ScreenLocation.BottomRight: avgColour = screenColourSet.bottomright; break; } // Color isn't HSV, so need to convert double hue = 0; double saturation = 0; double brightness = 0; Utils.ColorToHSV((Color)avgColour, out hue, out saturation, out brightness); brightness = (brightness * (SettingsCast.Brightness - SettingsCast.MinBrightness) + SettingsCast.MinBrightness); saturation = (saturation * (SettingsCast.Saturation - SettingsCast.MinSaturation) + SettingsCast.MinSaturation); var payload = new SetColourPayload { Kelvin = (ushort)SettingsCast.Kelvin, TransitionDuration = (uint)(SettingsCast.Fade), Hue = (int)hue, Saturation = (ushort)saturation, Brightness = (ushort)brightness }; bulbController.SetColour(label, payload, true); } // this is for when multizone apply is set to 0: need to send another packet to apply everything /*else { * var payload = new SetColourZonesPayload * { * start_index = new byte[1] { 0 }, * end_index = new byte[1] { 0 }, * Kelvin = 3500, * TransitionDuration = 0, * Hue = 0, * Saturation = 0, * Brightness = 0, * // ignore this payload and apply previous ones * apply = new byte[1] { 2 } * }; * bulbController.SetColourZoneFinder(label, payload); * //bulbController.SetColour(label, payload); * }*/ // } } Thread.Sleep(SettingsCast.Delay); }
static void Main(string[] args) { if (args.Length > 0 && args[0].Contains("list")) { MaxLifxBulbController bulbController = new MaxLifxBulbController(); bulbController.SetupNetwork(); bulbController.DiscoverBulbs(); foreach (Bulb b in bulbController.Bulbs) { Console.WriteLine(b.Label + " - " + b.MacAddress); } } else if (args.Length > 0 && args[0].Contains("setcolour")) { if (args.Length != 7) { B0Rk("Wrong number of arguments for setcolour."); } string macAddress = args[1].ToUpper(); int hue; int.TryParse(args[2], out hue); ushort sat; ushort.TryParse(args[3], out sat); ushort bri; ushort.TryParse(args[4], out bri); ushort kel; ushort.TryParse(args[5], out kel); UInt32 tra; UInt32.TryParse(args[6], out tra); if (args[1].Length != 12) { B0Rk("Mac address must be 12 characters."); } MaxLifxBulbController bulbController = new MaxLifxBulbController(); bulbController.SetupNetwork(); var payload = new SetColourPayload() { Hue = hue, Brightness = bri, Kelvin = kel, Saturation = sat, TransitionDuration = tra }; bulbController.SendPayloadToMacAddress(payload, macAddress); } else { Console.WriteLine("\r\nMaxLifxCmd - a C# LAN protocol Lifx bulb controller\r\n" + "===================================================\r\n\r\n" + "Usage:\r\n\r\n" + "Search for bulbs and list their labels and MAC addresses:\r\n\r\n" + "maxlifxcmd list\r\n\r\n" + "Set one or all bulb colours:\r\n\r\n" + "maxlifxcmd setcolour <macaddress> <hue> <saturation> <brightness>\r\n" + " <kelvin> <transition>\r\n\r\n" + "mac address: ABCDEF012345 or 000000000000 for all bulbs\r\n" + "hue : between 0 and 360\r\n" + "saturation, brightness, kelvin: between 0 and 65535\r\n" + "transition duration: between 0 and " + UInt32.MaxValue + " (ms)"); } }
public FakeBulb(MaxLifxBulbController bulbController, string label) { InitializeComponent(); Label = label; bulbController.ColourSet += SetColour; }
private void DoMainLoop(MaxLifxBulbController bulbController, ref int frames, DateTime start, ref SetColourPayload payload, Bitmap screenPixel, Graphics gdest, Graphics gsrc) { if (ShowUI) { var t = new Thread(() => { var form2 = new ScreenColourUI(SettingsCast); /* (SettingsCast, bulbController.Bulbs);*/ form2.ShowDialog(); }); t.Start(); ShowUI = false; } frames++; var screenColourSet = GetScreenColours(SettingsCast.TopLeft, SettingsCast.BottomRight, screenPixel, gdest, gsrc); if (screenColourSet != null) { foreach (var label in SettingsCast.SelectedLabels) { var location = SettingsCast.LabelsAndLocations.Single(x => x.Label == label).ScreenLocation; var avgColour = screenColourSet.all; switch (location) { case ScreenLocation.Top: avgColour = screenColourSet.top; break; case ScreenLocation.Bottom: avgColour = screenColourSet.bottom; break; case ScreenLocation.Left: avgColour = screenColourSet.left; break; case ScreenLocation.Right: avgColour = screenColourSet.right; break; case ScreenLocation.TopLeft: avgColour = screenColourSet.topleft; break; case ScreenLocation.TopRight: avgColour = screenColourSet.topright; break; case ScreenLocation.BottomLeft: avgColour = screenColourSet.bottomleft; break; case ScreenLocation.BottomRight: avgColour = screenColourSet.bottomright; break; } var hue = (int) (avgColour.GetHue()); var saturation = (ushort) (avgColour.GetSaturation()*(SettingsCast.Saturation-SettingsCast.MinSaturation) + SettingsCast.MinSaturation); var brightness = (ushort) (avgColour.GetBrightness()*(SettingsCast.Brightness-SettingsCast.MinBrightness) + SettingsCast.MinBrightness); payload = new SetColourPayload { Kelvin = 3500, TransitionDuration = (uint) (SettingsCast.Fade), Hue = hue, Saturation = saturation, Brightness = brightness }; bulbController.SetColour(label, payload); bulbController.SetColour(label, payload); } } Thread.Sleep(SettingsCast.Delay); }
private void DoMainLoop(MaxLifxBulbController bulbController, ref int frames, DateTime start, ref SetColourPayload payload, Bitmap screenPixel, Graphics gdest, Graphics gsrc) { if (ShowUI) { var t = new Thread(() => { var form2 = new ScreenColourUI(SettingsCast); /* (SettingsCast, bulbController.Bulbs);*/ form2.ShowDialog(); }); t.Start(); ShowUI = false; } frames++; var screenColourSet = GetScreenColours(SettingsCast.TopLeft, SettingsCast.BottomRight, screenPixel, gdest, gsrc); if (screenColourSet != null) { foreach (var label in SettingsCast.SelectedLabels) { var location = SettingsCast.LabelsAndLocations.FirstOrDefault(x => x.Label == label); if (location == null) { continue; } int r = 0, g = 0, b = 0, ctr = 0; foreach (var pixel in location.SelectedPixels) { r += screenColourSet.colours[pixel].R; g += screenColourSet.colours[pixel].G; b += screenColourSet.colours[pixel].B; ctr++; } var avgColour = ctr == 0 ? Color.Black : Color.FromArgb(255, r / ctr, g / ctr, b / ctr); var HSV = RGBToHSV(avgColour); var hue = (int)(HSV[0]); var saturation = (ushort)(HSV[1] * (SettingsCast.Saturation - SettingsCast.MinSaturation) + SettingsCast.MinSaturation); var brightness = (ushort)(HSV[2] * (SettingsCast.Brightness - SettingsCast.MinBrightness) + SettingsCast.MinBrightness); payload = new SetColourPayload { Kelvin = 3500, TransitionDuration = (uint)(SettingsCast.Fade), Hue = hue, Saturation = saturation, Brightness = brightness, RGBColour = avgColour }; payload.PayloadType = bulbController.Bulbs.FirstOrDefault(x => x.Label == label).BulbType; bulbController.SetColour(label, payload); } } Thread.Sleep(SettingsCast.Delay); }