} else if (device.getName().contains("SLIDER/KNOB KORG")) {
midiControllers.add(new KorgNanoKontrolMidiInput(device).setEnabled(true));
} else {
- boolean enabled = device.getName().contains("KEYBOARD KORG");
+ boolean enabled = device.getName().contains("KEYBOARD KORG") || device.getName().contains("Bus 1 Apple");
midiControllers.add(new SCMidiInput(device).setEnabled(enabled));
}
}
+ for (MidiOutputDevice device : RWMidi.getOutputDevices()) {
+ if (device.getName().contains("APC")) {
+ new APC40MidiOutput(this, device);
+ }
+ }
}
public List<SCMidiInput> getControllers() {
}
}
+ private long tap1 = 0;
+
+ private boolean lbtwn(long a, long b, long c) {
+ return a >= b && a <= c;
+ }
+
protected void handleNoteOn(Note note) {
- switch (note.getPitch()) {
- case 94: // right bank
- midiEngine.setFocusedDeck(1);
+ int nPitch = note.getPitch(), nChan = note.getChannel();
+ switch (nPitch) {
+
+ case 82: // scene 1
+ EFF_boom.trigger();
+ break;
+
+ case 83: // scene 2
+ EFF_flash.trigger();
+ break;
+
+ case 90:
+ // dan's dirty tapping mechanism
+ lx.tempo.trigger();
+ tap1 = millis();
break;
- case 95: // left bank
+
+ case 91: // play
+ case 97: // left bank
midiEngine.setFocusedDeck(0);
break;
- case 96: // up bank
+
+ case 93: // rec
+ case 96: // right bank
+ midiEngine.setFocusedDeck(1);
+ break;
+
+ case 94: // up bank
if (shiftOn) {
- glucose.incrementSelectedEffectBy(1);
+ glucose.incrementSelectedEffectBy(-1);
} else {
- midiEngine.getFocusedDeck().goNext();
+ midiEngine.getFocusedDeck().goPrev();
}
break;
- case 97: // down bank
+ case 95: // down bank
if (shiftOn) {
- glucose.incrementSelectedEffectBy(-1);
+ glucose.incrementSelectedEffectBy(1);
} else {
- midiEngine.getFocusedDeck().goPrev();
+ midiEngine.getFocusedDeck().goNext();
}
break;
lx.tempo.setBpm(lx.tempo.bpm() - (shiftOn ? 1 : .1));
break;
- case 91: // play
- case 93: // rec
+ case 62: // Detail View / red 5
releaseEffect = glucose.getSelectedEffect();
if (releaseEffect.isMomentary()) {
releaseEffect.enable();
}
break;
- case 92: // stop
+ case 63: // rec quantize / red 6
glucose.getSelectedEffect().disable();
break;
}
}
protected void handleNoteOff(Note note) {
- switch (note.getPitch()) {
- case 93: // rec
+ int nPitch = note.getPitch(), nChan = note.getChannel();
+ switch (nPitch) {
+ case 90: // SEND C
+ long tapDelta = millis() - tap1;
+ if (lbtwn(tapDelta,5000,300*1000)) { // hackish tapping mechanism
+ double bpm = 32.*60000./(tapDelta);
+ while (bpm < 20) bpm*=2;
+ while (bpm > 40) bpm/=2;
+ lx.tempo.setBpm(bpm);
+ lx.tempo.trigger();
+ tap1 = 0;
+ println("Tap Set - " + bpm + " bpm");
+ }
+ break;
+
+ case 63: // rec quantize / RED 6
if (releaseEffect != null) {
if (releaseEffect.isMomentary()) {
releaseEffect.disable();
}
}
break;
-
+
case 98: // shift
shiftOn = false;
- break;
+ break;
}
}
}
}
}
+class APC40MidiOutput implements LXParameter.Listener {
+
+ private final MidiEngine midiEngine;
+ private final MidiOutput output;
+ private LXPattern focusedPattern = null;
+ private LXEffect focusedEffect = null;
+
+ APC40MidiOutput(MidiEngine midiEngine, MidiOutputDevice device) {
+ this.midiEngine = midiEngine;
+ output = device.createOutput();
+ midiEngine.addListener(new MidiEngineListener() {
+ public void onFocusedDeck(int deckIndex) {
+ resetPatternParameters();
+ }
+ });
+ glucose.addEffectListener(new GLucose.EffectListener() {
+ public void effectSelected(LXEffect effect) {
+ resetEffectParameters();
+ }
+ });
+ Engine.Listener deckListener = new Engine.AbstractListener() {
+ public void patternDidChange(Engine.Deck deck, LXPattern pattern) {
+ resetPatternParameters();
+ }
+ };
+ for (Engine.Deck d : lx.engine.getDecks()) {
+ d.addListener(deckListener);
+ }
+ resetParameters();
+ }
+
+ private void resetParameters() {
+ resetPatternParameters();
+ resetEffectParameters();
+ }
+
+ private void resetPatternParameters() {
+ LXPattern newPattern = midiEngine.getFocusedDeck().getActivePattern();
+ if (newPattern == focusedPattern) {
+ return;
+ }
+ if (focusedPattern != null) {
+ for (LXParameter p : focusedPattern.getParameters()) {
+ ((LXListenableParameter) p).removeListener(this);
+ }
+ }
+ focusedPattern = newPattern;
+ int i = 0;
+ for (LXParameter p : focusedPattern.getParameters()) {
+ ((LXListenableParameter) p).addListener(this);
+ sendKnob(i++, p);
+ }
+ while (i < 12) {
+ sendKnob(i++, 0);
+ }
+ }
+
+ private void resetEffectParameters() {
+ LXEffect newEffect = glucose.getSelectedEffect();
+ if (newEffect == focusedEffect) {
+ return;
+ }
+ if (focusedEffect != null) {
+ for (LXParameter p : focusedPattern.getParameters()) {
+ ((LXListenableParameter) p).removeListener(this);
+ }
+ }
+ focusedEffect = newEffect;
+ int i = 0;
+ for (LXParameter p : focusedEffect.getParameters()) {
+ ((LXListenableParameter) p).addListener(this);
+ sendKnob(12 + i++, p);
+ }
+ while (i < 4) {
+ sendKnob(12 + i++, 0);
+ }
+ }
+
+ private void sendKnob(int i, LXParameter p) {
+ sendKnob(i, (int) (p.getValuef() * 127.));
+ }
+
+ private void sendKnob(int i, int value) {
+ if (i < 8) {
+ output.sendController(0, 48+i, value);
+ } else if (i < 16) {
+ output.sendController(0, 8+i, value);
+ }
+ }
+
+ public void onParameterChanged(LXParameter parameter) {
+ int i = 0;
+ for (LXParameter p : focusedPattern.getParameters()) {
+ if (p == parameter) {
+ sendKnob(i, p);
+ break;
+ }
+ ++i;
+ }
+ i = 12;
+ for (LXParameter p : focusedEffect.getParameters()) {
+ if (p == parameter) {
+ sendKnob(i, p);
+ break;
+ }
+ ++i;
+ }
+ }
+}