1 class SpaceTime extends SCPattern {
3 SinLFO pos = new SinLFO(0, 15, 3000);
4 SinLFO rate = new SinLFO(1000, 9000, 13000);
5 SinLFO falloff = new SinLFO(10, 70, 5000);
8 BasicKnob rateKnob = new BasicKnob("RATE", 0.5);
9 BasicKnob sizeKnob = new BasicKnob("SIZE", 0.5);
11 public SpaceTime(GLucose glucose) {
13 addModulator(pos).trigger();
14 addModulator(rate).trigger();
15 addModulator(falloff).trigger();
16 pos.modulateDurationBy(rate);
21 public void onKnobChange(Knob knob) {
22 if (knob == rateKnob) {
23 rate.stop().setValue(9000 - 8000*knob.getValuef());
24 } else if (knob == sizeKnob) {
25 falloff.stop().setValue(70 - 60*knob.getValuef());
29 void run(int deltaMs) {
30 sat += deltaMs * 0.00004;
31 float sVal1 = Strip.list.size() * (0.5 + 0.5*sin(sat));
32 float sVal2 = Strip.list.size() * (0.5 + 0.5*cos(sat));
34 float pVal = pos.getValuef();
35 float fVal = falloff.getValuef();
38 for (Strip strip : Strip.list) {
40 for (Point p : strip.points) {
41 colors[p.index] = color(
42 (lx.getBaseHuef() + s*.2 + i*3) % 360,
43 min(100, min(abs(s - sVal1), abs(s - sVal2))),
44 max(0, 100 - fVal*abs(i - pVal))
52 class Swarm extends SCPattern {
54 SawLFO offset = new SawLFO(0, 16, 1000);
55 SinLFO rate = new SinLFO(350, 1200, 63000);
56 SinLFO falloff = new SinLFO(15, 50, 17000);
57 SinLFO fY = new SinLFO(0, 250, 19000);
58 SinLFO fZ = new SinLFO(0, 127, 11000);
59 SinLFO hOffY = new SinLFO(0, 255, 13000);
61 public Swarm(GLucose glucose) {
63 addModulator(offset).trigger();
64 addModulator(rate).trigger();
65 addModulator(falloff).trigger();
66 addModulator(fY).trigger();
67 addModulator(fZ).trigger();
68 addModulator(hOffY).trigger();
69 offset.modulateDurationBy(rate);
72 float modDist(float v1, float v2, float mod) {
76 return min(v2-v1, v1+mod-v2);
79 return min(v1-v2, v2+mod-v1);
83 void run(int deltaMs) {
85 for (Strip strip : Strip.list) {
87 for (Point p : strip.points) {
88 float fV = max(-1, 1 - dist(p.fy/2., p.fz, fY.getValuef()/2., fZ.getValuef()) / 64.);
89 colors[p.index] = color(
90 (lx.getBaseHuef() + 0.3 * abs(p.fy - hOffY.getValuef())) % 360,
91 constrain(80 + 40 * fV, 0, 100),
92 constrain(100 - (30 - fV * falloff.getValuef()) * modDist(i + (s*63)%61, offset.getValuef(), 16), 0, 100)
101 class SwipeTransition extends SCTransition {
102 SwipeTransition(GLucose glucose) {
107 void computeBlend(int[] c1, int[] c2, double progress) {
109 float yPos = (float) (-bleed + progress * (255. + bleed));
110 for (Point p : Point.list) {
111 float d = (p.fy - yPos) / 50.;
113 colors[p.index] = c2[p.index];
115 colors[p.index] = c1[p.index];
117 colors[p.index] = lerpColor(c2[p.index], c1[p.index], d, RGB);
123 class CubeEQ extends SCPattern {
125 private FFT fft = null;
126 private LinearEnvelope[] bandVals = null;
129 private final BasicKnob thrsh = new BasicKnob("LVL", 0.35);
130 private final BasicKnob range = new BasicKnob("RANG", 0.45);
131 private final BasicKnob edge = new BasicKnob("EDGE", 0.5);
132 private final BasicKnob speed = new BasicKnob("SPD", 0.5);
133 private final BasicKnob tone = new BasicKnob("TONE", 0.5);
134 private final BasicKnob clr = new BasicKnob("CLR", 0.5);
136 public CubeEQ(GLucose glucose) {
146 protected void onActive() {
147 if (this.fft == null) {
148 this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate());
149 this.fft.window(FFT.HAMMING);
150 this.fft.logAverages(40, 1);
151 this.avgSize = this.fft.avgSize();
152 this.bandVals = new LinearEnvelope[this.avgSize];
153 for (int i = 0; i < this.bandVals.length; ++i) {
154 this.addModulator(this.bandVals[i] = (new LinearEnvelope(0, 0, 700+i*4))).trigger();
159 public void run(int deltaMs) {
160 this.fft.forward(this.lx.audioInput().mix);
161 float toneConst = .35 + .4 * (tone.getValuef() - 0.5);
162 float edgeConst = 2 + 30*(edge.getValuef()*edge.getValuef()*edge.getValuef());
164 for (int i = 0; i < avgSize; ++i) {
165 float value = this.fft.getAvg(i);
166 value = 20*log(1 + sqrt(value));
167 float sqdist = avgSize - i;
168 value -= toneConst*sqdist*sqdist + .5*sqdist;
170 if (value > this.bandVals[i].getValue()) {
171 this.bandVals[i].setEndVal(value, 40).trigger();
173 this.bandVals[i].setEndVal(value, 1000 - 900*speed.getValuef()).trigger();
177 float jBase = 120 - 360*thrsh.getValuef();
178 float jConst = 300.*(1-range.getValuef());
179 float clrConst = 1.1 + clr.getValuef();
181 for (Point p : Point.list) {
182 float avgIndex = constrain((p.fy / 256. * avgSize), 0, avgSize-2);
183 int avgFloor = (int) avgIndex;
184 float j = jBase + jConst * (p.fz / 128.);
186 this.bandVals[avgFloor].getValuef(),
187 this.bandVals[avgFloor+1].getValuef(),
191 float b = constrain(edgeConst * (value - j), 0, 100);
192 colors[p.index] = color(
193 (480 + lx.getBaseHuef() - min(clrConst*p.fz, 120)) % 360,