From e0794d3a20f8c2c301f6c7541925f3d403277fab Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Sat, 19 Oct 2013 12:54:11 -0700 Subject: [PATCH] Basic preset stuff and onTransitionEnd message --- _Internals.pde | 5 ++ _MIDI.pde | 16 ++++-- _Presets.pde | 133 +++++++++++++++++++++++++++++++++++++++++++++++ code/HeronLX.jar | Bin 67756 -> 67785 bytes 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 _Presets.pde diff --git a/_Internals.pde b/_Internals.pde index f1ebdc0..9d6b118 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -52,6 +52,7 @@ LXPattern[] patterns; MappingTool mappingTool; PandaDriver[] pandaBoards; MidiEngine midiEngine; +PresetManager presetManager; // Display configuration mode boolean mappingMode = false; @@ -136,6 +137,10 @@ void setup() { // MIDI devices midiEngine = new MidiEngine(); logTime("Setup MIDI devices"); + + // Preset manager + presetManager = new PresetManager(); + logTime("Loaded presets"); // Build output driver PandaMapping[] pandaMappings = buildPandaList(); diff --git a/_MIDI.pde b/_MIDI.pde index 9a27f8c..5f25dda 100644 --- a/_MIDI.pde +++ b/_MIDI.pde @@ -348,7 +348,6 @@ public class APC40MidiInput extends GenericDeviceMidiInput { 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; } @@ -453,6 +452,16 @@ public class APC40MidiInput extends GenericDeviceMidiInput { } break; + case 52: // CLIP STOP + if (nChan < PresetManager.NUM_PRESETS) { + if (shiftOn) { + presetManager.store(nChan); + } else { + presetManager.select(nChan); + } + } + break; + case 82: // scene 1 EFF_boom.trigger(); break; @@ -733,9 +742,8 @@ class APC40MidiOutput implements LXParameter.Listener, GridOutput { } 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); + if (col < 8 && row < 5) { + output.sendNoteOn(col, 53+row, state); } } } diff --git a/_Presets.pde b/_Presets.pde new file mode 100644 index 0000000..ada8bb1 --- /dev/null +++ b/_Presets.pde @@ -0,0 +1,133 @@ +interface PresetListener { + public void onPresetLoaded(Preset preset); + public void onPresetDirty(Preset preset); + public void onPresetStored(Preset preset); +} + +class PresetManager { + + public static final int NUM_PRESETS = 8; + public static final String FILENAME = "data/presets.txt"; + public static final String DELIMITER = "\t"; + + private final Preset[] presets = new Preset[NUM_PRESETS]; + private final List listeners = new ArrayList(); + + private LXPattern loadedPreset = null; + + PresetManager() { + for (int i = 0; i < presets.length; ++i) { + presets[i] = new Preset(this, i); + } + String[] values = loadStrings(FILENAME); + if (values == null) { + write(); + } else { + int i = 0; + for (String serialized : values) { + presets[i++].load(serialized); + if (i >= NUM_PRESETS) { + break; + } + } + } + } + + public void addListener(PresetListener listener) { + listeners.add(listener); + } + + public void select(int index) { + presets[index].select(); + } + + public void store(int index) { + presets[index].store(midiEngine.getFocusedPattern()); + } + + public void onPresetLoaded(Preset preset, LXPattern pattern) { + for (PresetListener listener : listeners) { + listener.onPresetLoaded(preset); + } + } + + public void write() { + String[] lines = new String[NUM_PRESETS]; + int i = 0; + for (Preset preset : presets) { + lines[i++] = preset.serialize(); + } + saveStrings(FILENAME, lines); + } +} + +class Preset { + + final PresetManager manager; + final int index; + + String className; + final Map parameters = new HashMap(); + + Preset(PresetManager manager, int index) { + this.manager = manager; + this.index = index; + } + + public void load(String serialized) { + className = null; + parameters.clear(); + try { + String[] parts = serialized.split(PresetManager.DELIMITER); + className = parts[0]; + int i = 1; + while (i < parts.length - 1) { + parameters.put(parts[i], Float.parseFloat(parts[i+1])); + i += 2; + } + } catch (Exception x) { + className = null; + parameters.clear(); + } + } + + public String serialize() { + if (className == null) { + return "null"; + } + String val = className + PresetManager.DELIMITER; + for (String pKey : parameters.keySet()) { + val += pKey + PresetManager.DELIMITER + parameters.get(pKey) + PresetManager.DELIMITER; + } + return val; + } + + public void store(LXPattern pattern) { + className = null; + parameters.clear(); + className = pattern.getClass().getName(); + for (LXParameter p : pattern.getParameters()) { + parameters.put(p.getLabel(), p.getValuef()); + } + manager.write(); + } + + public void select() { + Engine.Deck deck = midiEngine.getFocusedDeck(); + for (LXPattern pattern : deck.getPatterns()) { + if (pattern.getClass().getName().equals(className)) { + for (String pLabel : parameters.keySet()) { + for (LXParameter p : pattern.getParameters()) { + if (p.getLabel().equals(pLabel)) { + p.setValue(parameters.get(pLabel)); + } + } + } + deck.goPattern(pattern); + manager.onPresetLoaded(this, pattern); + break; + } + } + } +} + diff --git a/code/HeronLX.jar b/code/HeronLX.jar index d5352fca9013d71d09ec18427cfdb0e77c370b08..3a649062ed8d8286fee16bf7c905114baabe34a0 100755 GIT binary patch delta 7015 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 J=LM3@{{bq~niv28 delta 7056 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