Add preset saving and deck focus
authorMark Slee <mcslee@Mark-Slees-MacBook-Pro.local>
Sat, 19 Oct 2013 20:39:04 +0000 (13:39 -0700)
committerMark Slee <mcslee@Mark-Slees-MacBook-Pro.local>
Sat, 19 Oct 2013 20:39:25 +0000 (13:39 -0700)
_Internals.pde
_MIDI.pde
_Presets.pde

index 9d6b11889bd413b34ef8f8c9097ef720edbfea68..2e3af44def2500ec9c9a811261a70fd052603349 100644 (file)
@@ -51,8 +51,8 @@ HeronLX lx;
 LXPattern[] patterns;
 MappingTool mappingTool;
 PandaDriver[] pandaBoards;
-MidiEngine midiEngine;
 PresetManager presetManager;
+MidiEngine midiEngine;
 
 // Display configuration mode
 boolean mappingMode = false;
@@ -134,14 +134,15 @@ void setup() {
   glucose.lx.addEffects(effects(glucose));
   logTime("Built effects");
 
-  // MIDI devices
-  midiEngine = new MidiEngine();
-  logTime("Setup MIDI devices");
-  
   // Preset manager
   presetManager = new PresetManager();
   logTime("Loaded presets");
 
+  // MIDI devices
+  midiEngine = new MidiEngine();
+  presetManager.setMidiEngine(midiEngine);
+  logTime("Setup MIDI devices");
+
   // Build output driver
   PandaMapping[] pandaMappings = buildPandaList();
   pandaBoards = new PandaDriver[pandaMappings.length];
index 5f25ddad62327f0f10ce797447b8371ae9ba5170..9a3ce5cb29f21266e69247ab6d9a2e087084f6af 100644 (file)
--- a/_MIDI.pde
+++ b/_MIDI.pde
@@ -451,17 +451,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput {
           break;
       }
       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;
@@ -549,7 +539,17 @@ public class APC40MidiInput extends GenericDeviceMidiInput {
           break;
       }
       break;
-      
+
+    case 52: // CLIP STOP
+      if (nChan < PresetManager.NUM_PRESETS) {
+        if (shiftOn) {
+          presetManager.store(nChan);
+        } else {
+          presetManager.select(nChan);
+        }
+      }
+      break;
+
     case 90: // SEND C
       long tapDelta = millis() - tap1;
       if (lbtwn(tapDelta,5000,300*1000)) {     // hackish tapping mechanism
@@ -645,16 +645,37 @@ class APC40MidiOutput implements LXParameter.Listener, GridOutput {
     for (Engine.Deck d : lx.engine.getDecks()) {
       d.addListener(deckListener);
     }
+    presetManager.addListener(new PresetListener() {
+      public void onPresetLoaded(Preset preset) {
+        for (int i = 0; i < 8; ++i) {
+          output.sendNoteOn(i, 52, (preset.index == i) ? 1 : 0);
+        }
+      }
+      public void onPresetDirty(Preset preset) {
+        output.sendNoteOn(preset.index, 52, 2);
+      }
+      public void onPresetStored(Preset preset) {
+        onPresetLoaded(preset);
+      }
+      public void onPresetUnloaded() {
+        for (int i = 0; i < 8; ++i) {
+          output.sendNoteOn(i, 52, 0);
+        }
+      }
+    });
     resetParameters();
     midiEngine.grid.addOutput(this);
 
     lx.cycleBaseHue(60000);
     output.sendNoteOn(6, 49, 127);
     
-    // Turn off the track selection lights
+    // Turn off the track selection lights and preset selectors
     for (int i = 0; i < 8; ++i) {
       output.sendNoteOn(i, 51, 0);
+      output.sendNoteOn(i, 52, 0);
     }
+    
+    // Turn off the MASTER selector
     output.sendNoteOn(0, 80, 0);
   }
 
index 7743cbf3aa7c652f851938145b1595822e2bb612..f1855c63aa4f2c4c57eaba9f2030cc9b802ca108 100644 (file)
@@ -2,6 +2,7 @@ interface PresetListener {
   public void onPresetLoaded(Preset preset);
   public void onPresetDirty(Preset preset);
   public void onPresetStored(Preset preset);
+  public void onPresetUnloaded();
 }
 
 class PresetManager implements LXParameter.Listener {
@@ -32,6 +33,28 @@ class PresetManager implements LXParameter.Listener {
         }
       }
     }
+    for (Engine.Deck deck : lx.engine.getDecks()) {
+      deck.addListener(new Engine.AbstractListener() {
+        public void patternDidChange(Engine.Deck deck, LXPattern pattern) {
+          if (midiEngine.getFocusedDeck() == deck) {
+            if (pattern != loadedPattern) {
+              onPresetDirty();
+            }
+          }
+        }
+      });
+    }
+  }
+  
+  public void setMidiEngine(MidiEngine midiEngine) {
+    midiEngine.addListener(new MidiEngineListener() {
+      public void onFocusedDeck(int deckIndex) {
+        loadedPreset = null;
+        for (PresetListener listener : listeners) {
+          listener.onPresetUnloaded();
+        }
+      }
+    });
   }
   
   public void addListener(PresetListener listener) {
@@ -44,6 +67,9 @@ class PresetManager implements LXParameter.Listener {
 
   public void store(int index) {
     presets[index].store(midiEngine.getFocusedPattern());
+    for (PresetListener listener : listeners) {
+      listener.onPresetStored(presets[index]);
+    }
     select(index);
   }
   
@@ -65,12 +91,16 @@ class PresetManager implements LXParameter.Listener {
     }
   }
   
-  public void onParameterChanged(LXParameter p) {
+  private void onPresetDirty() {
     for (PresetListener listener : listeners) {
       listener.onPresetDirty(loadedPreset);
     }
   }
   
+  public void onParameterChanged(LXParameter p) {
+    onPresetDirty();
+  }
+  
   public void write() {
     String[] lines = new String[NUM_PRESETS];
     int i = 0;