Skip to content

Commit

Permalink
Support selectable 8-bit or 16-bit colour in LXChannel.
Browse files Browse the repository at this point in the history
  • Loading branch information
zestyping committed Apr 28, 2018
1 parent 86f511b commit 5b59044
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 37 deletions.
31 changes: 31 additions & 0 deletions src/heronarts/lx/HybridBuffer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package heronarts.lx;

import heronarts.lx.blend.LXBlend;
import heronarts.lx.color.LXColor;
import heronarts.lx.color.LXColor16;

Expand Down Expand Up @@ -50,6 +51,14 @@ public LXBuffer16 getBuffer16() {
return buffer16;
}

public int[] getArray() {
return getBuffer().getArray();
}

public long[] getArray16() {
return getBuffer16().getArray16();
}

/** Sets the 8-bit buffer where data will be read from and written to. */
public void setBuffer(LXBuffer buffer) {
this.buffer = buffer;
Expand All @@ -76,6 +85,28 @@ public void markBuffer16Modified() {
state = State.BUFFER16_IS_NEWER;
}

public void copyFrom(HybridBuffer src, boolean use16) {
if (src != this) {
if (use16) {
System.arraycopy(src.getArray16(), 0, getArray16(), 0, getArray16().length);
markBuffer16Modified();
} else {
System.arraycopy(src.getArray(), 0, getArray(), 0, getArray().length);
markBufferModified();
}
}
}

public void blendFrom(LXBlend blend, HybridBuffer base, HybridBuffer overlay, double alpha, boolean use16) {
if (use16) {
blend.blend16(base.getArray16(), overlay.getArray16(), alpha, getArray16());
markBuffer16Modified();
} else {
blend.blend(base.getArray(), overlay.getArray(), alpha, getArray());
markBufferModified();
}
}

/**
* If both the 8-bit and 16-buffers exist, ensures that they have matching data,
* performing a conversion if necessary that gives priority to whichever has newer data.
Expand Down
72 changes: 35 additions & 37 deletions src/heronarts/lx/LXChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ public enum CrossfadeGroup {
new BooleanParameter("On", true)
.setDescription("Sets whether this channel is on or off");

/**
* Whether this channel uses 16-bit color buffers.
*/
public final BooleanParameter use16BitColor =
new BooleanParameter("16-bit", false)
.setDescription("Enables 16-bit color");

/**
* Crossfade group this channel belongs to
*/
Expand Down Expand Up @@ -219,12 +226,8 @@ public enum CrossfadeGroup {
private final List<LXPattern> mutablePatterns = new ArrayList<LXPattern>();
public final List<LXPattern> patterns = Collections.unmodifiableList(mutablePatterns);

/**
* This is a local buffer used for transition blending on this channel
*/
private final ModelBuffer blendBuffer;

private int[] colors;
/** A local buffer used for transition blending and effects on this channel */
private final HybridBuffer hybridBuffer;

private double autoCycleProgress = 0;
private double transitionProgress = 0;
Expand Down Expand Up @@ -283,7 +286,7 @@ public void run() {
super(lx, "Channel-" + (index+1));
this.index = index;
this.label.setDescription("The name of this channel");
this.blendBuffer = new ModelBuffer(lx);
this.hybridBuffer = new HybridBuffer(lx);

this.focusedPattern =
new DiscreteParameter("Focused Pattern", 0, patterns.length)
Expand All @@ -297,7 +300,6 @@ public void run() {

this.transitionMillis = lx.engine.nowMillis;
_updatePatterns(patterns);
this.colors = this.getActivePattern().getColors();

addParameter("enabled", this.enabled);
addParameter("cue", this.cueActive);
Expand Down Expand Up @@ -573,6 +575,10 @@ public final LXPattern getActivePattern() {
return this.mutablePatterns.get(this.activePatternIndex);
}

public final HybridBuffer getHybridBuffer() {
return hybridBuffer;
}

public final int getNextPatternIndex() {
return this.nextPatternIndex;
}
Expand Down Expand Up @@ -640,7 +646,7 @@ public LXBus disableAutoTransition() {
/**
* Enable automatic transition from pattern to pattern on this channel
*
* @param autoTransitionThresholdTransition time in seconds
* @param autoTransitionThreshold time in seconds
* @return
*/
public LXBus enableAutoTransition(double autoTransitionThreshold) {
Expand Down Expand Up @@ -728,59 +734,51 @@ public void loop(double deltaMs) {
}

// Run active pattern
LXPattern activePattern = getActivePattern();
activePattern.loop(deltaMs);
int[] colors = activePattern.getColors();
boolean use16 = use16BitColor.getValueb();
getActivePattern().loop(deltaMs);

// Run transition!
if (this.transition != null) {
this.autoCycleProgress = 1.;
this.autoCycleProgress = 1;
this.transitionProgress = (this.lx.engine.nowMillis - this.transitionMillis) / (1000 * this.transitionTimeSecs.getValue());
getNextPattern().loop(deltaMs);;
// TODO(mcslee): this is incorrect. the blend objects are shared, so the same one may be run on multiple
// channels. either they need to be per-channel instances, or they are not loopable with modulators etc.
this.transition.loop(deltaMs);
colors = this.blendBuffer.getArray();
if (this.transitionProgress < .5) {
double alpha = Math.min(1, this.transitionProgress*2.);
this.transition.blend(
getActivePattern().getColors(),
getNextPattern().getColors(),
alpha,
colors
);

if (transitionProgress < 0.5) {
hybridBuffer.blendFrom(transition, getActivePattern().getHybridBuffer(),
getNextPattern().getHybridBuffer(), transitionProgress * 2, use16);
} else {
double alpha = Math.max(0, (1-this.transitionProgress)*2.);
this.transition.blend(
getNextPattern().getColors(),
getActivePattern().getColors(),
alpha,
colors
);
hybridBuffer.blendFrom(transition, getNextPattern().getHybridBuffer(),
getActivePattern().getHybridBuffer(), (1 - transitionProgress) * 2, use16);
}
} else {
this.transitionProgress = 0;
hybridBuffer.copyFrom(getActivePattern().getHybridBuffer(), use16);
}

// Apply effects
if (this.mutableEffects.size() > 0) {
int[] array = this.blendBuffer.getArray();
if (colors != array) {
System.arraycopy(colors, 0, array, 0, colors.length);
}
colors = array;
for (LXEffect effect : this.mutableEffects) {
effect.setBuffer(this.blendBuffer);
if (use16) {
effect.setBuffer16(hybridBuffer.getBuffer16());
} else {
effect.setBuffer(hybridBuffer.getBuffer());
}
effect.loop(deltaMs);
}
}

this.colors = colors;
this.timer.loopNanos = System.nanoTime() - loopStart;
}

int[] getColors() {
return this.colors;
return hybridBuffer.getArray();
}

long[] getColors16() {
return hybridBuffer.getArray16();
}

@Override
Expand Down
1 change: 1 addition & 0 deletions src/heronarts/lx/LXEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import heronarts.lx.blend.SubtractBlend;
import heronarts.lx.clip.LXClip;
import heronarts.lx.color.LXColor;
import heronarts.lx.color.LXColor16;
import heronarts.lx.midi.LXMidiEngine;
import heronarts.lx.model.LXPoint;
import heronarts.lx.osc.LXOscComponent;
Expand Down
4 changes: 4 additions & 0 deletions src/heronarts/lx/LXLayeredComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ protected LXLayeredComponent(LX lx, LXBuffer16 externalLongBuffer) {
setBuffer16(externalLongBuffer);
}

public HybridBuffer getHybridBuffer() {
return hybridBuffer;
}

/** Gets the 8-bit color buffer (performing conversions if necessary). */
protected LXBuffer getBuffer() {
return hybridBuffer.getBuffer();
Expand Down

0 comments on commit 5b59044

Please sign in to comment.