Skip to content

Commit

Permalink
Merge branch 'master' into no-madmom
Browse files Browse the repository at this point in the history
  • Loading branch information
larryfenn committed Aug 23, 2022
2 parents adc7f0d + c1e1c9f commit 7b737b1
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 63 deletions.
2 changes: 2 additions & 0 deletions Base/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public interface Configuration : INotifyPropertyChanged {
// Dome Visualizer settings
// TODO: move "volume" settings down here?
int domeRadialEffect { get; set; }
double domeGlobalFadeSpeed { get; set; }
double domeGlobalHueSpeed { get; set; }
double domeRadialSize { get; set; }
int domeRadialFrequency { get; set; }
double domeRadialCenterAngle { get; set; }
Expand Down
70 changes: 66 additions & 4 deletions LEDs/LEDDomeOutputBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,72 @@ public class LEDDomeOutputBuffer {

public void Fade(double mul, double sub) {
for (int i = 0; i < pixels.Length; i++) {
//pixels[i].color /= 2;
pixels[i].r = pixels[i].r * mul - sub;
pixels[i].g = pixels[i].g * mul - sub;
pixels[i].b = pixels[i].b * mul - sub;
if (pixels[i].color != 0) {
pixels[i].r = pixels[i].r * mul - sub;
pixels[i].g = pixels[i].g * mul - sub;
pixels[i].b = pixels[i].b * mul - sub;
}
}
}

public void HueRotate(double rate) {
for (int i = 0; i < pixels.Length; i++) {
double r = pixels[i].r / 255d;
double g = pixels[i].g / 255d;
double b = pixels[i].b / 255d;

double max = Math.Max(Math.Max(r, g), b);
double min = Math.Min(Math.Min(r, g), b);

double d = max - min;
double s = max == 0 ? 0 : d / max;
if (s != 0) {
double v = max;
double h = 0;

if (max != min) {
if (r > g) {
if (r > b) {
h = (g - b) / d + (g < b ? 6 : 0);
} else {
h = (r - g) / d + 4;
}
} else {
if (g > b) {
h = (b - r) / d + 2;
} else {
h = (r - g) / d + 4;
}
}

h /= 6;
}
double shifted_hue = (h + rate) % 1;
if (shifted_hue > 1) {
shifted_hue -= 1;
}
if (shifted_hue < 0) {
shifted_hue += 1;
}

int j = (int)Math.Floor(shifted_hue * 6);
double f = shifted_hue * 6 - j;
double p = v * (1 - s);
double q = v * (1 - f * s);
double t = v * (1 - (1 - f) * s);

switch (j % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}
pixels[i].r = r * 255;
pixels[i].g = g * 255;
pixels[i].b = b * 255;
}
}
}
}
Expand Down
23 changes: 14 additions & 9 deletions Spectrum/Color.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ internal class Color {
public byte R;
public byte G;
public byte B;
public double H;
public double S;
public double V;
public double H; // Hue - [0, 1] from Red to Green to Blue back to Red (periodic)
public double S; // Saturation - [0, 1] (grayness)
public double V; // Value - [0, 1] (brightness)

public Color(byte r, byte g, byte b) {
R = r;
G = g;
B = b;
double max = Math.Max(Math.Max(r / 255.0d, g / 255.0d), b / 255.0d);
double min = Math.Max(Math.Max(r / 255.0d, g / 255.0d), b / 255.0d);
public Color(byte _r, byte _g, byte _b) {
R = _r;
G = _g;
B = _b;

double r = _r / 255d;
double g = _g / 255d;
double b = _b / 255d;

double max = Math.Max(Math.Max(r, g), b);
double min = Math.Min(Math.Min(r, g), b);

double d = max - min;
double s = max == 0 ? 0 : d / max;
Expand Down
2 changes: 2 additions & 0 deletions Spectrum/SpectrumConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ public class SpectrumConfiguration : Configuration {
public int domeSkipLEDs { get; set; } = 0;
public int domeTestPattern { get; set; } = 0;
public int domeActiveVis { get; set; } = 0;
public double domeGlobalFadeSpeed { get; set; } = 0;
public double domeGlobalHueSpeed { get; set; } = 1;
public int domeRadialEffect { get; set; } = 0;
public double domeRadialSize { get; set; } = 0.1;
public int domeRadialFrequency { get; set; } = 1;
Expand Down
33 changes: 17 additions & 16 deletions Spectrum/Visualizers/LEDDomeQuaternionPaintbrushVisualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class LEDDomeQuaternionPaintbrushVisualizer : Visualizer {
private AudioInput audio;
private OrientationInput orientation;
private LEDDomeOutput dome;
private LEDDomeOutputBuffer buffer;
private Vector3 spot = new Vector3(0, 1, 0);

public LEDDomeQuaternionPaintbrushVisualizer(
Expand All @@ -25,6 +26,7 @@ LEDDomeOutput dome
this.orientation = orientation;
this.dome = dome;
this.dome.RegisterVisualizer(this);
this.buffer = this.dome.MakeDomeOutputBuffer();
}

public int Priority {
Expand All @@ -40,24 +42,23 @@ LEDDomeOutput dome
}

void Render() {
for (int i = 0; i < LEDDomeOutput.GetNumStruts(); i++) {
var leds = LEDDomeOutput.GetNumLEDs(i);
for (int j = 0; j < leds; j++) {
var p = StrutLayoutFactory.GetProjectedLEDPoint(i, j); // centered on (.5, .5), [0, 1] x [0, 1]
var x = 2 * p.Item1 - 1; // now centered on (0, 0) and with range [0, 1]
var y = 1 - 2 * p.Item2; // this is because in the original mapping x, y come "out of" the top left corner
float z = (float)Math.Sqrt(1 - x * x - y * y);
Vector3 pixelPoint = new Vector3((float)x, (float)y, z);
// Calibration assigns (0, 1, 0) to be 'forward'
// So we want the post-transformed pixel closest to (0, 1, 0)?
Color color = new Color(0, 0, 0);
if(Vector3.Distance(Vector3.Transform(pixelPoint, orientation.rotation), spot) < .25) {
color = new Color((256 * (orientation.rotation.W + 1)) / 256d, 1, 1);
}
// todo : rework to use jan karls buffer
this.dome.SetPixel(i, j, color.ToInt());
buffer.Fade(1 - Math.Pow(10, -this.config.domeGlobalFadeSpeed), 0);
buffer.HueRotate(Math.Pow(10, -this.config.domeGlobalHueSpeed));
for (int i = 0; i < buffer.pixels.Length; i++) {
var p = buffer.pixels[i];
var x = 2 * p.x - 1; // now centered on (0, 0) and with range [0, 1]
var y = 1 - 2 * p.y; // this is because in the original mapping x, y come "out of" the top left corner
float z = (float)Math.Sqrt(1 - x * x - y * y);
Vector3 pixelPoint = new Vector3((float)x, (float)y, z);
// Calibration assigns (0, 1, 0) to be 'forward'
// So we want the post-transformed pixel closest to (0, 1, 0)?
if(Vector3.Distance(Vector3.Transform(pixelPoint, orientation.rotation), spot) < .25) {
Color color = new Color((256 * (orientation.rotation.W + 1) / 2) / 256d, 1, 1);
buffer.pixels[i].color = color.ToInt();
}
}
this.dome.WriteBuffer(buffer);

}

public void Visualize() {
Expand Down
40 changes: 20 additions & 20 deletions Spectrum/Visualizers/LEDDomeQuaternionTestVisualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class LEDDomeQuaternionTestVisualizer : Visualizer{
private Configuration config;
private OrientationInput orientation;
private LEDDomeOutput dome;
private LEDDomeOutputBuffer buffer;

public LEDDomeQuaternionTestVisualizer(
Configuration config,
Expand All @@ -19,6 +20,7 @@ LEDDomeOutput dome
this.orientation = orientation;
this.dome = dome;
this.dome.RegisterVisualizer(this);
this.buffer = this.dome.MakeDomeOutputBuffer();
}

public int Priority {
Expand All @@ -34,28 +36,26 @@ LEDDomeOutput dome
}

void Render() {
for (int i = 0; i < LEDDomeOutput.GetNumStruts(); i++) {
var leds = LEDDomeOutput.GetNumLEDs(i);
for (int j = 0; j < leds; j++) {
var p = StrutLayoutFactory.GetProjectedLEDPoint(i, j); // centered on (.5, .5), [0, 1] x [0, 1]
var x = 2 * p.Item1 - 1; // now centered on (0, 0) and with range [0, 1]
var y = 1 - 2 * p.Item2; // this is because in the original mapping x, y come "out of" the top left corner
float z = (float)Math.Sqrt(1 - x * x - y * y);
Vector3 pixelPoint = new Vector3((float)x, (float)y, z);
Vector3 pixelPointQuat = Vector3.Transform(pixelPoint, orientation.rotation);
// Color maxes
int maxIndex = MaxBy(pixelPointQuat);
Color color = new Color(0, 0, 0);
if(maxIndex == 0) {
color = new Color(255, 0, 0);
} else if(maxIndex == 1) {
color = new Color(0, 255, 0);
} else if(maxIndex == 2) {
color = new Color(0, 0, 255);
}
this.dome.SetPixel(i, j, color.ToInt());
for (int i = 0; i < buffer.pixels.Length; i++) {
var p = buffer.pixels[i];
var x = 2 * p.x - 1; // now centered on (0, 0) and with range [0, 1]
var y = 1 - 2 * p.y; // this is because in the original mapping x, y come "out of" the top left corner
float z = (float)Math.Sqrt(1 - x * x - y * y);
Vector3 pixelPoint = new Vector3((float)x, (float)y, z);
Vector3 pixelPointQuat = Vector3.Transform(pixelPoint, orientation.rotation);
// Color maxes
int maxIndex = MaxBy(pixelPointQuat);
Color color = new Color(0, 0, 0);
if(maxIndex == 0) {
color = new Color(255, 0, 0);
} else if(maxIndex == 1) {
color = new Color(0, 255, 0);
} else if(maxIndex == 2) {
color = new Color(0, 0, 255);
}
buffer.pixels[i].color = color.ToInt();
}
this.dome.WriteBuffer(buffer);
}

public void Visualize() {
Expand Down
20 changes: 7 additions & 13 deletions Spectrum/Visualizers/LEDDomeRadialVisualizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ LEDDomeOutput dome
}

void Render() {

buffer.Fade(1 - Math.Pow(10, -this.config.domeGlobalFadeSpeed), 0);
double level = this.audio.LevelForChannel(0);
// Sqrt makes values larger and gives more resolution for lower values
double adjustedLevel = Clamp(Math.Sqrt(level), 0.1, 1);
Expand Down Expand Up @@ -139,23 +139,17 @@ LEDDomeOutput dome
// size limit is scaled according the size slider and the current
// level
var sizeLimit = this.config.domeRadialSize * adjustedLevel;
bool on = val <= sizeLimit;

// use level to determine which colors to use
int whichGradient = (int)(level * 8);

var color = on
? this.dome.GetGradientColor(
if(val <= sizeLimit) {
// use level to determine which colors to use
int whichGradient = (int)(level * 8);
buffer.pixels[i].color = this.dome.GetGradientColor(
whichGradient,
gradientVal,
currentGradient,
true
)
: 0;

buffer.pixels[i].color = color;
);
}
}

this.dome.WriteBuffer(buffer);
}

Expand Down
10 changes: 10 additions & 0 deletions Spectrum/Windows/VJHUDWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,16 @@
<ComboBoxItem x:Name="dre3" Content="Bubbles" />
</ComboBox>
</Grid>
<Grid Height="24">
<Label Content="Global Fade Speed" Margin="-2,3,2.4,0" Padding="0" />
<Slider x:Name="domeGlobalFadeSpeedSlider" Value="0" HorizontalAlignment="Left" Margin="100,0,0,0" VerticalAlignment="Top" Height="20" Width="115" Maximum="4.0" LargeChange="1" SmallChange="0.1" Thumb.DragStarted="SliderStarted" Thumb.DragCompleted="SliderCompleted" />
<Label x:Name="domeGlobalFadeSpeedLabel" Content="0" HorizontalAlignment="Left" Margin="215,0,0,0" Padding="0" ContentStringFormat="F3" />
</Grid>
<Grid Height="24">
<Label Content="Global Hue Speed" Margin="-2,3,2.4,0" Padding="0" />
<Slider x:Name="domeGlobalHueSpeedSlider" Value="1" HorizontalAlignment="Left" Margin="100,0,0,0" VerticalAlignment="Top" Height="20" Width="115" Minimum="1.0" Maximum="4.0" LargeChange="1" SmallChange="0.1" Thumb.DragStarted="SliderStarted" Thumb.DragCompleted="SliderCompleted" />
<Label x:Name="domeGlobalHueSpeedLabel" Content="0" HorizontalAlignment="Left" Margin="215,0,0,0" Padding="0" ContentStringFormat="F3" />
</Grid>
<Grid Height="24">
<Label Content="Radial Size" Margin="-2,3,2.4,0" Padding="0" />
<Slider x:Name="domeRadialSizeSlider" Value="0.1" HorizontalAlignment="Left" Margin="100,0,0,0" VerticalAlignment="Top" Height="20" Width="115" Maximum="4.0" LargeChange="0.1" SmallChange="0.001" Thumb.DragStarted="SliderStarted" Thumb.DragCompleted="SliderCompleted" />
Expand Down
6 changes: 5 additions & 1 deletion Spectrum/Windows/VJHUDWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,12 @@ private class LevelDriverPresetEntry {
}, true));
this.Bind("domeVolumeRotationSpeed", this.domeVolumeRotationSpeed, ComboBox.SelectedItemProperty, BindingMode.TwoWay, new SpecificValuesConverter<double, ComboBoxItem>(new Dictionary<double, ComboBoxItem> { [0] = this.dprs0, [0.125] = this.dprs1, [0.25] = this.dprs2, [0.5] = this.dprs3, [1.0] = this.dprs4, [2.0] = this.dprs5, [4.0] = this.dprs6 }, true));
this.Bind("domeGradientSpeed", this.domeGradientSpeed, ComboBox.SelectedItemProperty, BindingMode.TwoWay, new SpecificValuesConverter<double, ComboBoxItem>(new Dictionary<double, ComboBoxItem> { [0] = this.dsrs0, [0.125] = this.dsrs1, [0.25] = this.dsrs2, [0.5] = this.dsrs3, [1.0] = this.dsrs4, [2.0] = this.dsrs5, [4.0] = this.dsrs6 }, true));
this.Bind("domeRadialCenterSpeed", this.domeRadialCenterSpeed, ComboBox.SelectedItemProperty, BindingMode.TwoWay, new SpecificValuesConverter<double, ComboBoxItem>(new Dictionary<double, ComboBoxItem> { [0] = this.rcs0, [0.125] = this.rcs1, [0.25] = this.rcs2, [0.5] = this.rcs3, [1.0] = this.rcs4, [2.0] = this.rcs5, [4.0] = this.rcs6 }, true));
this.Bind("domeRadialCenterSpeed", this.domeRadialCenterSpeed, ComboBox.SelectedItemProperty, BindingMode.TwoWay, new SpecificValuesConverter<double, ComboBoxItem>(new Dictionary<double, ComboBoxItem> { [0] = this.rcs0, [0.125] = this.rcs1, [0.25] = this.rcs2, [0.5] = this.rcs3, [1.0] = this.rcs4, [2.0] = this.rcs5, [4.0] = this.rcs6 }, true));

this.Bind("domeGlobalFadeSpeed", this.domeGlobalFadeSpeedSlider, Slider.ValueProperty);
this.Bind("domeGlobalFadeSpeed", this.domeGlobalFadeSpeedLabel, Label.ContentProperty);
this.Bind("domeGlobalHueSpeed", this.domeGlobalHueSpeedSlider, Slider.ValueProperty);
this.Bind("domeGlobalHueSpeed", this.domeGlobalHueSpeedLabel, Label.ContentProperty);
this.Bind("domeRadialEffect", this.domeRadialEffect, ComboBox.SelectedIndexProperty, BindingMode.TwoWay);
this.Bind("domeRadialSize", this.domeRadialSizeSlider, Slider.ValueProperty);
this.Bind("domeRadialSize", this.domeRadialSizeLabel, Label.ContentProperty);
Expand Down

0 comments on commit 7b737b1

Please sign in to comment.