Update music pattern
[SugarCubes.git] / MarkSlee.pde
index 649d61cc4594c71e29e1960704854bb3241e3363..bf41de1204e52013ffbf7d9758e83f4739c014e7 100644 (file)
@@ -4,9 +4,18 @@ class MidiMusic extends SCPattern {
   private final List<LightUp> allLights = new ArrayList<LightUp>();
   
   private final Stack<LightUp> newLayers = new Stack<LightUp>();
+  private final BasicParameter lightSize = new BasicParameter("SIZE", 0.5);
+
+  private final LinearEnvelope sparkle = new LinearEnvelope(0, 1, 500);
+  private float sparkleBright = 100;
+
+  private final LinearEnvelope sweep = new LinearEnvelope(0, 1, 1000);
   
   MidiMusic(GLucose glucose) {
     super(glucose);
+    addParameter(lightSize);
+    addModulator(sparkle).setValue(1);
+    addModulator(sweep);
   }
   
   class LightUp extends LXLayer {
@@ -25,7 +34,7 @@ class MidiMusic extends SCPattern {
     }
     
     void noteOn(Note note) {
-      xPos = lerp(0, model.xMax, constrain(0.5 + (note.getPitch() - 64) / 12., 0, 1));
+      xPos = lerp(0, model.xMax, constrain(0.5 + (note.getPitch() - 60) / 26., 0, 1));
       yPos.setValue(lerp(20, model.yMax, note.getVelocity() / 127.));
       brt.setRangeFromHereTo(lerp(40, 100, note.getVelocity() / 127.), 20).start();     
     }
@@ -42,10 +51,11 @@ class MidiMusic extends SCPattern {
       }
       float yVal = yPos.getValuef();
       for (Point p : model.points) {
-        float b = max(0, bVal - 3*dist(p.x, p.y, xPos, yVal));
+        float falloff = 6 - 5*lightSize.getValuef();
+        float b = max(0, bVal - falloff*dist(p.x, p.y, xPos, yVal));
         if (b > 0) {
           colors[p.index] = blendColor(colors[p.index], lx.hsb(
-            (lx.getBaseHuef() + abs(p.x - model.cx) + abs(p.y - model.cy)) % 360,
+            (lx.getBaseHuef() + .2*abs(p.x - model.cx) + .2*abs(p.y - model.cy)) % 360,
             100,
             b
           ), ADD);
@@ -70,6 +80,18 @@ class MidiMusic extends SCPattern {
         newLayers.push(newLight);
       }
     } else if (note.getChannel() == 1) {
+    } else if (note.getChannel() == 9) {
+      if (note.getVelocity() > 0) {
+        switch (note.getPitch()) {
+          case 36:
+            sparkleBright = note.getVelocity() / 127. * 100;
+            sparkle.trigger();
+            break;
+          case 37:
+            sweep.trigger();
+            break;
+        }
+      }
     }
     return true;
   }
@@ -85,7 +107,30 @@ class MidiMusic extends SCPattern {
   }
   
   public synchronized void run(double deltaMs) {
-    setColors(#000000);
+    float sparklePos = sparkle.getValuef() * Cube.POINTS_PER_STRIP * .75;
+    float maxBright = sparkleBright * (1 - sparkle.getValuef());
+    for (Strip s : model.strips) {
+      int i = 0;
+      for (Point p : s.points) {
+        colors[p.index] = color(
+          (lx.getBaseHuef() + .2*abs(p.x - model.cx) + .2*abs(p.y - model.cy)) % 360,
+          100,
+          maxBright - 40.*abs(sparklePos - abs(i - (Cube.POINTS_PER_STRIP-1)/2.))
+        );
+        ++i;
+      }
+    }
+    
+    if (sweep.isRunning()) {
+      for (Point p : model.points) {
+        colors[p.index] = blendColor(colors[p.index], color(
+          (lx.getBaseHuef() + .2*abs(p.x - model.cx) + .2*abs(p.y - model.cy)) % 360,
+          100 - 100.*sweep.getValuef(),
+          100 - 15.*abs(p.y - sweep.getValuef()*model.yMax)
+        ), ADD);
+      }
+    }
+    
     if (!newLayers.isEmpty()) {
       synchronized(newLayers) {
         while (!newLayers.isEmpty()) {
@@ -173,11 +218,13 @@ class Pulley extends SCPattern {
     }
 
     // A little silliness to test the grid API    
-    for (int i = 0; i < 7; ++i) {
-      for (int j = 0; j < 8; ++j) {
-        int gi = (int) constrain(j * NUM_DIVISIONS / 8, 0, NUM_DIVISIONS-1);
-        float b = 1 - 4.*abs((6-i)/7. - gravity[gi].getValuef() / model.yMax);
-        midiEngine.grid.setState(i, j, (b < 0) ? 0 : 1);
+    if (midiEngine != null && midiEngine.getFocusedPattern() == this) {
+           for (int i = 0; i < 5; ++i) {
+        for (int j = 0; j < 8; ++j) {
+          int gi = (int) constrain(j * NUM_DIVISIONS / 8, 0, NUM_DIVISIONS-1);
+          float b = 1 - 4.*abs((6-i)/6. - gravity[gi].getValuef() / model.yMax);
+          midiEngine.grid.setState(i, j, (b < 0) ? 0 : 3);
+        }
       }
     }
     
@@ -1195,38 +1242,98 @@ class Traktor extends SCPattern {
 
 class ColorFuckerEffect extends SCEffect {
   
-  BasicParameter hueShift = new BasicParameter("HSHFT", 0);
-  BasicParameter sat = new BasicParameter("SAT", 1);  
-  BasicParameter bright = new BasicParameter("BRT", 1);
+  final BasicParameter level = new BasicParameter("BRT", 1);
+  final BasicParameter desat = new BasicParameter("DSAT", 0);
+  final BasicParameter sharp = new BasicParameter("SHARP", 0);
+  final BasicParameter soft = new BasicParameter("SOFT", 0);
+  final BasicParameter mono = new BasicParameter("MONO", 0);
+  final BasicParameter invert = new BasicParameter("INVERT", 0);
+  final BasicParameter hueShift = new BasicParameter("HSHFT", 0);
+  
   float[] hsb = new float[3];
   
   ColorFuckerEffect(GLucose glucose) {
     super(glucose);
+    addParameter(level);
+    addParameter(desat);
+    addParameter(sharp);
+    addParameter(soft);
+    addParameter(mono);
+    addParameter(invert);
     addParameter(hueShift);
-    addParameter(bright);
-    addParameter(sat);    
   }
   
   public void doApply(int[] colors) {
     if (!enabled) {
       return;
     }
-    float bMod = bright.getValuef();
-    float sMod = sat.getValuef();
+    float bMod = level.getValuef();
+    float sMod = 1 - desat.getValuef();
     float hMod = hueShift.getValuef();
-    if (bMod < 1 || sMod < 1 || hMod > 0) {    
+    float fSharp = 1/(1.0001-sharp.getValuef());
+    float fSoft = soft.getValuef();
+    boolean mon = mono.getValuef() > 0.5;
+    boolean ivt = invert.getValuef() > 0.5;
+    if (bMod < 1 || sMod < 1 || hMod > 0 || fSharp > 0 || ivt || mon || fSoft > 0) {
       for (int i = 0; i < colors.length; ++i) {
         lx.RGBtoHSB(colors[i], hsb);
+        if (mon) {
+          hsb[0] = lx.getBaseHuef() / 360.;
+        }
+        if (ivt) {
+          hsb[2] = 1 - hsb[2];
+        }
+        if (fSharp > 0) {
+          hsb[2] = hsb[2] < .5 ? pow(hsb[2],fSharp) : 1-pow(1-hsb[2],fSharp);
+        }
+        if (fSoft > 0) {
+          if (hsb[2] > 0.5) {
+            hsb[2] = lerp(hsb[2], 0.5 + 2 * (hsb[2]-0.5)*(hsb[2]-0.5), fSoft);
+          } else {
+            hsb[2] = lerp(hsb[2], 0.5 * sqrt(2*hsb[2]), fSoft);
+          }
+        }
         colors[i] = lx.hsb(
-          (360. * hsb[0] + hueShift.getValuef()*360.) % 360,
-          100. * hsb[1] * sat.getValuef(),
-          100. * hsb[2] * bright.getValuef()
+          (360. * hsb[0] + hMod*360.) % 360,
+          100. * hsb[1] * sMod,
+          100. * hsb[2] * bMod
         );
       }
     }
   }
 }
 
+class QuantizeEffect extends SCEffect {
+  
+  color[] quantizedFrame;
+  float lastQuant;
+  final BasicParameter amount = new BasicParameter("AMT", 0);
+  
+  QuantizeEffect(GLucose glucose) {
+    super(glucose);
+    quantizedFrame = new color[glucose.lx.total];
+    lastQuant = 0;
+  } 
+  
+  public void doApply(int[] colors) {
+    float fQuant = amount.getValuef();
+    if (fQuant > 0) {
+      float tRamp = (lx.tempo.rampf() % (1./pow(2,floor((1-fQuant) * 4))));
+      float f = lastQuant;
+      lastQuant = tRamp;
+      if (tRamp > f) {
+        for (int i = 0; i < colors.length; ++i) {
+          colors[i] = quantizedFrame[i];
+        }
+        return;
+      }
+    }
+    for (int i = 0; i < colors.length; ++i) {
+      quantizedFrame[i] = colors[i];
+    }
+  }
+}
+
 class BlurEffect extends SCEffect {
   
   final LXParameter amount = new BasicParameter("AMT", 0);