From: Mark Slee Date: Fri, 27 Sep 2013 19:58:32 +0000 (-0400) Subject: New ViolinWave pattern to play with for Paramount show X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=4760e696dd25f659896876c10ff5cb98b69fb84f;p=SugarCubes.git New ViolinWave pattern to play with for Paramount show --- diff --git a/Audio.pde b/Audio.pde index 4547a74..def7d0e 100644 --- a/Audio.pde +++ b/Audio.pde @@ -39,8 +39,8 @@ public static class GraphicEQ { } } - final float logTen = log(10); - public float log10(float val) { + static final float logTen = log(10); + public static float log10(float val) { return log(val) / logTen; } @@ -70,13 +70,13 @@ public static class GraphicEQ { float value = constrain(positiveDecibels / decibelRange, 0, 1); if (value > bandVals[i].getValuef()) { - bandVals[i].setEndVal(value, attack.getValuef() * 20).trigger(); + bandVals[i].setRangeFromHereTo(value, attack.getValuef() * 20).trigger(); } } for (LinearEnvelope band : bandVals) { band.run(deltaMs); if (!band.isRunning() && band.getValuef() > 0) { - band.setEndVal(0, release.getValuef() * 1600).trigger(); + band.setRangeFromHereTo(0, release.getValuef() * 1600).trigger(); } } } diff --git a/MarkSlee.pde b/MarkSlee.pde index 699df38..ee686b7 100644 --- a/MarkSlee.pde +++ b/MarkSlee.pde @@ -1,3 +1,131 @@ +class ViolinWave extends SCPattern { + + BasicParameter level = new BasicParameter("LVL", 0.45); + BasicParameter range = new BasicParameter("RNG", 0.5); + BasicParameter edge = new BasicParameter("EDG", 0.5); + BasicParameter release = new BasicParameter("RLS", 0.5); + BasicParameter speed = new BasicParameter("SPD", 0.5); + BasicParameter amp = new BasicParameter("AMP", 0.25); + BasicParameter period = new BasicParameter("WAVE", 0.5); + BasicParameter pSize = new BasicParameter("PSIZE", 0.5); + BasicParameter pSpeed = new BasicParameter("PSPD", 0.5); + BasicParameter pDensity = new BasicParameter("PDENS", 0.25); + + LinearEnvelope dbValue = new LinearEnvelope(0, 0, 10); + + ViolinWave(GLucose glucose) { + super(glucose); + addParameter(level); + addParameter(edge); + addParameter(range); + addParameter(release); + addParameter(speed); + addParameter(amp); + addParameter(period); + addParameter(pSize); + addParameter(pSpeed); + addParameter(pDensity); + + addModulator(dbValue); + } + + final List particles = new ArrayList(); + + class Particle { + + LinearEnvelope x = new LinearEnvelope(0, 0, 0); + LinearEnvelope y = new LinearEnvelope(0, 0, 0); + + Particle() { + addModulator(x); + addModulator(y); + } + + Particle trigger(boolean direction) { + float xInit = random(model.xMin, model.xMax); + float time = 3000 - 2500*pSpeed.getValuef(); + x.setRange(xInit, xInit + random(-40, 40), time).trigger(); + y.setRange(model.cy + 10, direction ? model.yMax + 50 : model.yMin - 50, time).trigger(); + return this; + } + + boolean isActive() { + return x.isRunning() || y.isRunning(); + } + + public void run(double deltaMs) { + if (!isActive()) { + return; + } + + float pFalloff = (30 - 27*pSize.getValuef()); + for (Point p : model.points) { + float b = 100 - pFalloff * (abs(p.x - x.getValuef()) + abs(p.y - y.getValuef())); + if (b > 0) { + colors[p.index] = blendColor(colors[p.index], color( + lx.getBaseHuef(), 20, b + ), ADD); + } + } + } + } + + float[] centers = new float[30]; + double accum = 0; + boolean rising = true; + + void fireParticle(boolean direction) { + boolean gotOne = false; + for (Particle p : particles) { + if (!p.isActive()) { + p.trigger(direction); + return; + } + } + particles.add(new Particle().trigger(direction)); + } + + public void run(double deltaMs) { + accum += deltaMs / (1000. - 900.*speed.getValuef()); + for (int i = 0; i < centers.length; ++i) { + centers[i] = model.cy + 30*amp.getValuef()*sin((float) (accum + (i-centers.length/2.)/(1. + 9.*period.getValuef()))); + } + + float zeroDBReference = pow(10, (50 - 190*level.getValuef())/20.); + float dB = 20*GraphicEQ.log10(lx.audioInput().mix.level() / zeroDBReference); + if (dB > dbValue.getValuef()) { + rising = true; + dbValue.setRangeFromHereTo(dB, 10).trigger(); + } else { + if (rising) { + for (int j = 0; j < pDensity.getValuef()*3; ++j) { + fireParticle(true); + fireParticle(false); + } + } + rising = false; + dbValue.setRangeFromHereTo(max(dB, -96), 50 + 1000*release.getValuef()).trigger(); + } + float edg = 1 + edge.getValuef() * 40; + float rng = (78 - 64 * range.getValuef()) / (model.yMax - model.cy); + float val = max(2, dbValue.getValuef()); + + for (Point p : model.points) { + int ci = (int) lerp(0, centers.length-1, (p.x - model.xMin) / (model.xMax - model.xMin)); + float rFactor = 1.0 - 0.9 * abs(p.x - model.cx) / (model.xMax - model.cx); + colors[p.index] = color( + (lx.getBaseHuef() + abs(p.x - model.cx)) % 360, + min(100, 20 + 8*abs(p.y - centers[ci])), + constrain(edg*(val*rFactor - rng * abs(p.y-centers[ci])), 0, 100) + ); + } + + for (Particle p : particles) { + p.run(deltaMs); + } + } +} + class BouncyBalls extends SCPattern { static final int NUM_BALLS = 6; diff --git a/SugarCubes.pde b/SugarCubes.pde index 656d7c4..0f5ca26 100644 --- a/SugarCubes.pde +++ b/SugarCubes.pde @@ -27,6 +27,7 @@ LXPattern[] patterns(GLucose glucose) { return new LXPattern[] { // Slee + new ViolinWave(glucose), new BouncyBalls(glucose), new Swarm(glucose), new SpaceTime(glucose),