}
}
- public synchronized boolean noteOnReceived(Note note) {
+ public synchronized boolean noteOn(Note note) {
if (note.getChannel() == 0) {
for (LightUp light : allLights) {
if (light.isAvailable()) {
return true;
}
- public synchronized boolean noteOffReceived(Note note) {
+ public synchronized boolean noteOff(Note note) {
if (note.getChannel() == 0) {
LightUp light = lightMap.get(note.getPitch());
if (light != null) {
addParameter(sz);
addParameter(beatAmount);
trigger();
+
}
private void trigger() {
if (reset.click()) {
trigger();
}
+
if (isRising) {
// Fucking A, had to comment this all out because of that bizarre
// Processing bug where some simple loop takes an absurd amount of
}
}
}
+
+ // 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);
+ }
+ }
float fPos = 1 - lx.tempo.rampf();
if (fPos < .2) {
}
}
- public boolean noteOnReceived(Note note) {
+ public boolean noteOn(Note note) {
int pitch = (note.getPitch() + note.getChannel()) % NUM_BALLS;
balls[pitch].bounce(note.getVelocity());
return true;
return base[index % base.length];
}
- public boolean noteOnReceived(Note note) {
+ public boolean noteOn(Note note) {
LinearEnvelope env = getEnvelope(note.getPitch());
env.setEndVal(min(1, env.getValuef() + (note.getVelocity() / 127.)), getAttackTime()).start();
return true;
}
- public boolean noteOffReceived(Note note) {
+ public boolean noteOff(Note note) {
getEnvelope(note.getPitch()).setEndVal(0, getReleaseTime()).start();
return true;
}
class MidiEngine {
+ public final GridController grid;
private final List<MidiEngineListener> listeners = new ArrayList<MidiEngineListener>();
private final List<SCMidiInput> midiControllers = new ArrayList<SCMidiInput>();
private int activeDeckIndex = 0;
public MidiEngine() {
-
- midiControllers.add(midiQwertyKeys = new SCMidiInput(SCMidiInput.KEYS));
- midiControllers.add(midiQwertyAPC = new SCMidiInput(SCMidiInput.APC));
+ grid = new GridController(this);
+ midiControllers.add(midiQwertyKeys = new SCMidiInput(this, SCMidiInput.KEYS));
+ midiControllers.add(midiQwertyAPC = new SCMidiInput(this, SCMidiInput.APC));
for (MidiInputDevice device : RWMidi.getInputDevices()) {
if (device.getName().contains("APC")) {
- midiControllers.add(new APC40MidiInput(device).setEnabled(true));
+ midiControllers.add(new APC40MidiInput(this, device).setEnabled(true));
} else if (device.getName().contains("SLIDER/KNOB KORG")) {
- midiControllers.add(new KorgNanoKontrolMidiInput(device).setEnabled(true));
+ midiControllers.add(new KorgNanoKontrolMidiInput(this, device).setEnabled(true));
} else {
boolean enabled = device.getName().contains("KEYBOARD KORG") || device.getName().contains("Bus 1 Apple");
- midiControllers.add(new SCMidiInput(device).setEnabled(enabled));
+ midiControllers.add(new SCMidiInput(this, device).setEnabled(enabled));
}
}
for (MidiOutputDevice device : RWMidi.getOutputDevices()) {
return this.midiControllers;
}
+ public Engine.Deck getFocusedDeck() {
+ return lx.engine.getDeck(activeDeckIndex);
+ }
+
+ public SCPattern getFocusedPattern() {
+ return (SCPattern) getFocusedDeck().getActivePattern();
+ }
+
public MidiEngine setFocusedDeck(int deckIndex) {
if (this.activeDeckIndex != deckIndex) {
this.activeDeckIndex = deckIndex;
return this;
}
- public Engine.Deck getFocusedDeck() {
- return lx.engine.getDeck(activeDeckIndex);
- }
-
public boolean isQwertyEnabled() {
return midiQwertyKeys.isEnabled() || midiQwertyAPC.isEnabled();
}
private final int mode;
private int octaveShift = 0;
+ protected final MidiEngine midiEngine;
+
class NoteMeta {
int channel;
int number;
return this;
}
- SCMidiInput(MidiInputDevice d) {
+ SCMidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+ this.midiEngine = midiEngine;
mode = MIDI;
d.createInput(this);
name = d.getName().replace("Unknown vendor","");
}
- SCMidiInput(int mode) {
+ SCMidiInput(MidiEngine midiEngine, int mode) {
+ this.midiEngine = midiEngine;
this.mode = mode;
switch (mode) {
case APC:
return this;
}
- protected SCPattern getFocusedPattern() {
- return (SCPattern) midiEngine.getFocusedDeck().getActivePattern();
- }
-
private boolean logMidi() {
return (uiMidi != null) && uiMidi.logMidi();
}
return;
}
if (logMidi()) {
- println(getLabel() + " :: Controller :: " + cc.getCC() + ":" + cc.getValue());
+ println(getLabel() + " :: Controller :: " + cc.getChannel() + " :: " + cc.getCC() + ":" + cc.getValue());
}
- if (!getFocusedPattern().controllerChangeReceived(cc)) {
- handleControllerChange(cc);
+ if (!handleGridControllerChange(cc)) {
+ if (!midiEngine.getFocusedPattern().controllerChange(cc)) {
+ handleControllerChange(cc);
+ }
}
}
if (logMidi()) {
println(getLabel() + " :: Note On :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
}
- if (!getFocusedPattern().noteOnReceived(note)) {
- handleNoteOn(note);
+ if (!handleGridNoteOn(note)) {
+ if (!midiEngine.getFocusedPattern().noteOn(note)) {
+ handleNoteOn(note);
+ }
}
}
if (logMidi()) {
println(getLabel() + " :: Note Off :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
}
- if (!getFocusedPattern().noteOffReceived(note)) {
- handleNoteOff(note);
+ if (!handleGridNoteOff(note)) {
+ if (!midiEngine.getFocusedPattern().noteOff(note)) {
+ handleNoteOff(note);
+ }
}
}
// Subclasses may implement these to map top-level functionality
- protected void handleProgramChange(ProgramChange pc) {
- }
- protected void handleControllerChange(rwmidi.Controller cc) {
- }
- protected void handleNoteOn(Note note) {
- }
- protected void handleNoteOff(Note note) {
- }
+ protected boolean handleGridNoteOn(Note note) { return false; }
+ protected boolean handleGridNoteOff(Note note) { return false; }
+ protected boolean handleGridControllerChange(rwmidi.Controller cc) { return false; }
+ protected void handleProgramChange(ProgramChange pc) {}
+ protected void handleControllerChange(rwmidi.Controller cc) {}
+ protected void handleNoteOn(Note note) {}
+ protected void handleNoteOff(Note note) {}
}
public class APC40MidiInput extends SCMidiInput {
private boolean shiftOn = false;
private LXEffect releaseEffect = null;
- APC40MidiInput(MidiInputDevice d) {
- super(d);
+ APC40MidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+ super(midiEngine, d);
+ }
+
+ private class GridPosition {
+ public final int row, col;
+ GridPosition(int r, int c) {
+ row = r;
+ col = c;
+ }
+ }
+
+ private GridPosition getGridPosition(Note note) {
+ int channel = note.getChannel();
+ int pitch = note.getPitch();
+ if (channel < 8) {
+ if (pitch >= 53 && pitch <=57) return new GridPosition(pitch-53, channel);
+ else if (pitch == 52) return new GridPosition(5, channel);
+ }
+ return null;
+ }
+
+ protected boolean handleGridNoteOn(Note note) {
+ GridPosition p = getGridPosition(note);
+ if (p != null) {
+ return midiEngine.grid.gridPressed(p.row, p.col);
+ }
+ return false;
+ }
+
+ protected boolean handleGridNoteOff(Note note) {
+ GridPosition p = getGridPosition(note);
+ if (p != null) {
+ return midiEngine.grid.gridReleased(p.row, p.col);
+ }
+ return false;
}
protected void handleControllerChange(rwmidi.Controller cc) {
parameterIndex = 8 + (number-16);
}
if (parameterIndex >= 0) {
- List<LXParameter> parameters = getFocusedPattern().getParameters();
+ List<LXParameter> parameters = midiEngine.getFocusedPattern().getParameters();
if (parameterIndex < parameters.size()) {
parameters.get(parameterIndex).setValue(cc.getValue() / 127.);
}
class KorgNanoKontrolMidiInput extends SCMidiInput {
- KorgNanoKontrolMidiInput(MidiInputDevice d) {
- super(d);
+ KorgNanoKontrolMidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+ super(midiEngine, d);
}
protected void handleControllerChange(rwmidi.Controller cc) {
int number = cc.getCC();
if (number >= 16 && number <= 23) {
int parameterIndex = number - 16;
- List<LXParameter> parameters = getFocusedPattern().getParameters();
+ List<LXParameter> parameters = midiEngine.getFocusedPattern().getParameters();
if (parameterIndex < parameters.size()) {
parameters.get(parameterIndex).setValue(cc.getValue() / 127.);
}
}
}
-class APC40MidiOutput implements LXParameter.Listener {
+class APC40MidiOutput implements LXParameter.Listener, GridOutput {
private final MidiEngine midiEngine;
private final MidiOutput output;
d.addListener(deckListener);
}
resetParameters();
+ midiEngine.grid.addOutput(this);
}
private void resetParameters() {
while (i < 12) {
sendKnob(i++, 0);
}
+ for (int row = 0; row < 7; ++row) {
+ for (int col = 0; col < 8; ++col) {
+ setGridState(row, col, 0);
+ }
+ }
}
private void resetEffectParameters() {
++i;
}
}
+
+ public void setGridState(int row, int col, int state) {
+ if (col < 8) {
+ if (row < 5) output.sendNoteOn(col, 53+row, state);
+ else if (row == 6) output.sendNoteOn(col, 52, state);
+ }
+ }
+}
+
+interface GridOutput {
+ public static final int OFF = 0;
+ public static final int GREEN = 1;
+ public static final int GREEN_BLINK = 2;
+ public static final int RED = 3;
+ public static final int RED_BLINK = 4;
+ public static final int YELLOW = 5;
+ public static final int YELLOW_BLINK = 6;
+ public static final int ON = 127;
+
+ public void setGridState(int row, int col, int state);
}
+
+class GridController {
+ private final List<GridOutput> outputs = new ArrayList<GridOutput>();
+
+ private final MidiEngine midiEngine;
+
+ GridController(MidiEngine midiEngine) {
+ this.midiEngine = midiEngine;
+ }
+
+ public void addOutput(GridOutput output) {
+ outputs.add(output);
+ }
+
+ public boolean gridPressed(int row, int col) {
+ return midiEngine.getFocusedPattern().gridPressed(row, col);
+ }
+
+ public boolean gridReleased(int row, int col) {
+ return midiEngine.getFocusedPattern().gridReleased(row, col);
+ }
+
+ public void setState(int row, int col, int state) {
+ for (GridOutput g : outputs) {
+ g.setGridState(row, col, state);
+ }
+ }
+}
+