From: Mark Slee Date: Sun, 26 May 2013 22:23:23 +0000 (-0700) Subject: Add a MIDI-responding piano key pattern that lights up cubes based on notes X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=5d70e4d754301bd011da0d3ea821c92ac6a8d362;p=SugarCubes.git Add a MIDI-responding piano key pattern that lights up cubes based on notes --- diff --git a/MarkSlee.pde b/MarkSlee.pde index 07c8ce2..95e8545 100644 --- a/MarkSlee.pde +++ b/MarkSlee.pde @@ -276,3 +276,71 @@ class BoomEffect extends SCEffect { } } +public class PianoKeyPattern extends SCPattern { + + final LinearEnvelope[] cubeBrt; + final SinLFO base[]; + final BasicParameter attack = new BasicParameter("ATK", 0.1); + final BasicParameter release = new BasicParameter("REL", 0.5); + final BasicParameter level = new BasicParameter("AMB", 0.6); + + PianoKeyPattern(GLucose glucose) { + super(glucose); + + for (MidiInputDevice input : RWMidi.getInputDevices()) { + input.createInput(this); + } + + addParameter(attack); + addParameter(release); + addParameter(level); + cubeBrt = new LinearEnvelope[Cube.list.size() / 4]; + for (int i = 0; i < cubeBrt.length; ++i) { + addModulator(cubeBrt[i] = new LinearEnvelope(0, 0, 100)); + } + base = new SinLFO[Cube.list.size() / 12]; + for (int i = 0; i < base.length; ++i) { + addModulator(base[i] = new SinLFO(0, 1, 7000 + 1000*i)).trigger(); + } + } + + private float getAttackTime() { + return 15 + attack.getValuef()*attack.getValuef() * 2000; + } + + private float getReleaseTime() { + return 15 + release.getValuef() * 3000; + } + + private LinearEnvelope getEnvelope(int index) { + return cubeBrt[index % cubeBrt.length]; + } + + private SinLFO getBase(int index) { + return base[index % base.length]; + } + + public void noteOnReceived(Note note) { + LinearEnvelope env = getEnvelope(note.getPitch()); + env.setEndVal(min(1, env.getValuef() + (note.getVelocity() / 127.)), getAttackTime()).start(); + } + + public void noteOffReceived(Note note) { + getEnvelope(note.getPitch()).setEndVal(0, getReleaseTime()).start(); + } + + public void run(int deltaMs) { + int i = 0; + float huef = lx.getBaseHuef(); + float levelf = level.getValuef(); + for (Cube c : Cube.list) { + float v = max(getBase(i).getValuef() * levelf/4., getEnvelope(i++).getValuef()); + setColor(c, color( + (huef + 20*v + abs(c.fy-128.)*.3 + c.fz) % 360, + min(100, 120*v), + 100*v + )); + } + } +} + diff --git a/SugarCubes.pde b/SugarCubes.pde index 3a5354c..9ec4f07 100644 --- a/SugarCubes.pde +++ b/SugarCubes.pde @@ -28,6 +28,7 @@ LXPattern[] patterns(GLucose glucose) { new SpaceTime(glucose), new Swarm(glucose), new CubeEQ(glucose), + new PianoKeyPattern(glucose), // Basic test patterns for reference, not art // new TestHuePattern(glucose), diff --git a/_Internals.pde b/_Internals.pde index 05336ec..a458052 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -20,6 +20,7 @@ import ddf.minim.*; import ddf.minim.analysis.*; import processing.opengl.*; import java.lang.reflect.*; +import rwmidi.*; final int VIEWPORT_WIDTH = 900; final int VIEWPORT_HEIGHT = 700; diff --git a/code/GLucose.jar b/code/GLucose.jar index cc16b16..74084b6 100644 Binary files a/code/GLucose.jar and b/code/GLucose.jar differ