New music patterns and Arturia controller
authorMark Slee <mcslee@Mark-Slees-MacBook-Pro.local>
Fri, 25 Oct 2013 00:10:06 +0000 (17:10 -0700)
committerMark Slee <mcslee@Mark-Slees-MacBook-Pro.local>
Fri, 25 Oct 2013 00:10:06 +0000 (17:10 -0700)
MarkSlee.pde
SugarCubes.pde
_MIDI.pde

index fde5fc7eda9a7b828652ba2b25c0335ca20d6a44..c598e19d5fe0d4b4363d32be7966ef8475aaff7d 100644 (file)
@@ -4,9 +4,14 @@ 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;
   
   MidiMusic(GLucose glucose) {
     super(glucose);
+    addParameter(lightSize);
+    addModulator(sparkle).setValue(1);
   }
   
   class LightUp extends LXLayer {
@@ -25,7 +30,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 +47,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 +76,17 @@ class MidiMusic extends SCPattern {
         newLayers.push(newLight);
       }
     } else if (note.getChannel() == 1) {
+    } else if (note.getChannel() == 9) {
+      switch (note.getPitch()) {
+        case 36:
+          if (note.getVelocity() > 0) {
+            sparkleBright = note.getVelocity() / 127. * 100;
+            if (sparkleBright > 0) {
+              sparkle.trigger();
+            }
+          }
+          break;
+      }
     }
     return true;
   }
@@ -85,7 +102,19 @@ 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 (!newLayers.isEmpty()) {
       synchronized(newLayers) {
         while (!newLayers.isEmpty()) {
index 6877613e4cca823f389e25b53c0aa024a4d967f3..00cc3b85725357fe911451147469dbaf3abcfde5 100644 (file)
@@ -28,7 +28,7 @@ LXPattern[] patterns(GLucose glucose) {
 
     
     // Slee
-    // new MidiMusic(glucose),
+    new MidiMusic(glucose),
     new Pulley(glucose),
     new Swarm(glucose),
     new ViolinWave(glucose),
index 59c5f826f7eea8e88acc00c396efe00dc7885614..5e5236973ce5f501a2b7f3c912816719bb5b79ef 100644 (file)
--- a/_MIDI.pde
+++ b/_MIDI.pde
@@ -62,8 +62,12 @@ class MidiEngine {
         midiControllers.add(new APC40MidiInput(this, device, apcDeck).setEnabled(true));
       } else if (device.getName().contains("SLIDER/KNOB KORG")) {
         midiControllers.add(new KorgNanoKontrolMidiInput(this, device).setEnabled(true));
+      } else if (device.getName().contains("Arturia MINILAB")) {
+        midiControllers.add(new ArturiaMinilabMidiInput(this, device).setEnabled(true));
       } else {
-        boolean enabled = device.getName().contains("KEYBOARD KORG") || device.getName().contains("Bus 1 Apple");
+        boolean enabled =
+          device.getName().contains("KEYBOARD KORG") ||
+          device.getName().contains("Bus 1 Apple");
         midiControllers.add(new GenericDeviceMidiInput(this, device).setEnabled(enabled));
       }
     }
@@ -863,6 +867,36 @@ class APC40MidiOutput implements LXParameter.Listener, GridOutput {
   }
 }
 
+class ArturiaMinilabMidiInput extends GenericDeviceMidiInput {
+  ArturiaMinilabMidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+    super(midiEngine, d);
+  }
+  
+  protected boolean handleControllerChange(rwmidi.Controller cc) {
+    int parameterIndex = -1;
+    switch (cc.getCC()) {
+      case 7:   parameterIndex = 0; break;
+      case 74:  parameterIndex = 1; break;
+      case 71:  parameterIndex = 2; break;
+      case 76:  parameterIndex = 3; break;
+      case 114: parameterIndex = 4; break;
+      case 18:  parameterIndex = 5; break;
+      case 19:  parameterIndex = 6; break;
+      case 16:  parameterIndex = 7; break;
+    }
+    if (parameterIndex >= 0) {
+      List<LXParameter> parameters = midiEngine.getFocusedPattern().getParameters();
+      if (parameterIndex < parameters.size()) {
+        LXParameter p = parameters.get(parameterIndex);
+        float curVal = p.getValuef();
+        curVal += (cc.getValue() - 64) / 127.;
+        p.setValue(constrain(curVal, 0, 1));
+      }
+    }
+    return false;
+  }
+}
+
 interface GridOutput {
   public static final int OFF = 0;
   public static final int GREEN = 1;