changeset 1:b5bcad8e7803

renamed teensy files added DeviceManageJack.cpp
author Fiore Martin <f.martin@qmul.ac.uk>
date Fri, 08 Jul 2016 11:39:18 +0200
parents 02467299402e
children dd889fff8423
files CollidoscopeTeensy/CollidoscopeTeensy_new.ino CollidoscopeTeensy/CollidoscopeTeensy_original.ino JackDevice/ContextJack.cpp JackDevice/ContextJack.h JackDevice/DeviceManagerJack.cpp JackDevice/DeviceManagerJack.h TeensyCode/collidoscope_double_knob.ino TeensyCode/collidoscope_single_knob.ino
diffstat 8 files changed, 1231 insertions(+), 1085 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CollidoscopeTeensy/CollidoscopeTeensy_new.ino	Fri Jul 08 11:39:18 2016 +0200
@@ -0,0 +1,323 @@
+
+/******************************************************************************
+
+ *  Ben Bengler
+ *  mail@benbengler.com
+ *  02.05.2016
+ *
+ *  Collidoscope 
+ *  
+ *  Teensy 2 ++ pinout: https://www.pjrc.com/teensy/card4b.pdf
+ *  
+ *  ANALOG INPUTS:
+ *  Wavejet   -> F0 (38) [Horizontal rail 1]
+ *  Wavejet   -> F1 (39) [Horizontal rail 2]
+ *  Filter 1  -> F2 (40) [Vertical rail 1]
+ *  Filter 2  -> F4 (42) [Vertical rail 2] 
+ *
+ *  DIGITAL INPUTS [INTERRUPTS]:
+ *  Sel. length 1  -> INT0/INT1 (0, 1)  [Encoder 1]
+ *  Sel. length 2  -> INT2/INT3 (2, 3)  [Encoder 2]
+ *  Duration 1     -> INT4/INT5 (36, 37)[Encoder 3] 
+ *  Duration 2     -> INT6/INT7 (18, 19)[Encoder 4] 
+ *
+ *  DIGITAL INPUTS:
+ *  Play1 toggle  -> B0 (20)
+ *  Record1       -> B1 (21)
+ *  Play2 toggle  -> B3 (22)
+ *  Record2       -> B4 (24)
+ *  
+ *  DIGITAL OUTPUTS:
+ *  Record Button 1 Led -> D4 (4)
+ *  Record Button 2 Led -> D5 (5)
+
+ ******************************************************************************/ 
+
+
+#include <Encoder.h>
+#include <Bounce.h>
+
+///////////////////////////////////////////////////
+//MIDI settings
+const int midi_chan_inst1 = 1; // MIDI channel for Instrument 1
+const int midi_chan_inst2 = 2; // MIDI channel for Instrument 2
+
+const int cc_length = 1;    // MIDI cc controlling selection length
+const int cc_duration = 2;  // MIDI cc controlling duration
+const int cc_filter = 7;    // MIDI cc controlling LP filter
+const int cc_play = 4;      // MIDI cc controlling PLAY
+const int cc_record = 5;    // MIDI cc controlling RECORD
+//const int cc_reset = 100; // MIDI cc controlling instrument RESET
+
+///////////////////////////////////////////////////
+//Default Values:
+const int  Enc_def = 64; //default selection length  
+int MIDI_led_state = LOW;
+//boolean reset1 = true;
+//boolean reset2 = true;
+
+///////////////////////////////////////////////////
+// Interface Inputs
+
+//Buttons:
+
+const int Pin_play1 = 20;       //B0    
+const int Pin_record1 = 21;     //B1
+const int Pin_play2 = 23;       //B3
+const int Pin_record2 = 24;     //B4
+const int Pin_record1_led =  4; //D4
+const int Pin_record2_led =  5; //D5
+const int Pin_MIDIled =  6;
+
+//const int Pin_reset1 = 22;    //B2, not in use
+//const int Pin_reset2 = 25;    //B5, not in use
+
+Bounce button1 = Bounce(Pin_play1, 5); 
+Bounce button2 = Bounce(Pin_record1, 5); 
+Bounce button3 = Bounce(Pin_play2, 5); 
+Bounce button4 = Bounce(Pin_record2, 5); 
+
+ 
+//Encoder
+Encoder Enc1 (0, 1);  //Encoder for section length on Wavejet 1
+Encoder Enc2 (2, 3);  //Encoder for section length on Wavejet 2
+Encoder Enc3 (36, 37);  //Encoder for duration of Wavejet 1 [granularisation effect]
+Encoder Enc4 (18, 19);  //Encoder for duration of Wavejet 2 [granularisation effect]
+
+// Variables
+const int jitter_thresh = 10; //7threshold value for analog INs to suppress sending MIDI due to input jitter 
+const int jitter_thresh_short = 5;
+
+void setup() {  
+
+pinMode(Pin_play1, INPUT_PULLUP); 
+pinMode(Pin_record1, INPUT_PULLUP);
+pinMode(Pin_play2, INPUT_PULLUP);
+pinMode(Pin_record2, INPUT_PULLUP);
+
+
+pinMode(Pin_MIDIled, OUTPUT); 
+pinMode(Pin_record1_led, OUTPUT);
+pinMode(Pin_record2_led, OUTPUT);
+}
+
+//Store recent values to detect parameter change
+long Enc1_old = -999;
+long Enc2_old = -999;
+long Enc3_old = -999;
+long Enc4_old = -999;
+
+uint16_t Jet1_old = 0;
+int16_t Jet1_old_MIDI = -1;
+uint16_t Jet2_old = 0;
+int16_t Jet2_old_MIDI = -1;
+uint16_t filter1_old = 0;
+int16_t filter1_old_MIDI = -1;
+uint16_t filter2_old = 0;
+int16_t filter2_old_MIDI = -1;
+
+void loop() {
+
+  digitalWrite(Pin_MIDIled, LOW);
+  digitalWrite(Pin_record1_led, HIGH);
+  digitalWrite(Pin_record2_led, HIGH);
+  button1.update();
+  button2.update();
+  button3.update();
+  button4.update();
+
+  
+  uint16_t Jet1_new = analogRead(0); //read Wavejet/Rail 1
+  uint16_t Jet2_new = analogRead(1); //read Wavejet/Rail 2
+  uint16_t filter1_new = analogRead(2);   //read filter Instrument 1; ADJUST INPUT RANGE ACCORDING TO SENSOR    
+  uint16_t filter2_new = analogRead(4);   //read filter Instrument 2; ADJUST INPUT RANGE ACCORDING TO SENSOR  
+
+
+  
+  //Encoder 1 [Controls selection length of wave 1]
+  long Enc1_new = Enc1.read();
+  Enc1_new = constrain(Enc1_new, 0, 127); //constrain to 7-bit MIDI range
+  
+  //Dynamic reset of counter to MIDI range 
+  if (Enc1_new <= 0){
+    Enc1.write(0); 
+  }
+  else if (Enc1_new >= 127){
+    Enc1.write(127); 
+  }
+     
+  //Encoder 2 [Controls selection length of wave 2]
+  long Enc2_new = Enc2.read();
+  Enc2_new = constrain(Enc2_new, 0, 127); //constrain to 7-bit MIDI range
+  
+  //Dynamic reset of counter to MIDI range 
+  if (Enc2_new <= 0){
+    Enc2.write(0); 
+  }
+  else if (Enc2_new >= 127){
+    Enc2.write(127); 
+  }
+
+  //Encoder 3 [Controls duration of wave 1]
+  long Enc3_new = Enc3.read();
+  Enc3_new = constrain(Enc3_new, 0, 127); //constrain to 7-bit MIDI range
+  
+  //Dynamic reset of counter to MIDI range 
+  if (Enc3_new <= 0){
+    Enc3.write(0); 
+  }
+  else if (Enc3_new >= 127){
+    Enc3.write(127); 
+  }
+
+  //Encoder 4 [Controls duration of wave 2]
+  long Enc4_new = Enc4.read();
+  Enc4_new = constrain(Enc4_new, 0, 127); //constrain to 7-bit MIDI range
+  
+  //Dynamic reset of counter to MIDI range 
+  if (Enc4_new <= 0){
+    Enc4.write(0); 
+  }
+  else if (Enc4_new >= 127){
+    Enc4.write(127); 
+  }
+
+ 
+ //Instrument 1 Controls//////////////////////////////////////  
+ 
+ //Loop/Keymode Switch Instrument 1 
+   
+ if (button1.risingEdge()) {   
+   //Serial.println("Loop mode");
+   usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst1);
+ }
+   
+ if (button1.fallingEdge()) {   
+   //Serial.println("Keyboardmode mode");
+   usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst1);
+ }
+     
+   
+ //Record Instrument 1
+ if (button2.fallingEdge()) {   
+   //Serial.println("RECORD! Instrument 1");
+   usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst1);
+ }
+
+ //send MIDI Wavejet 1 [Position Instrument 1]
+ if (Jet1_new > Jet1_old+jitter_thresh || Jet1_new < Jet1_old-jitter_thresh) {
+    
+    int16_t midiVal = constrain( map(Jet1_new, 988, 121, 0, 149), 0, 149 );
+    // int16_t midiVal = constrain( map( Jet1_new, 23, 928, 0, 149 ), 0, 149 ); old collidoscope 
+    if( midiVal != Jet1_old_MIDI ){
+      Jet1_old_MIDI = midiVal;
+      usbMIDI.sendPitchBend( midiVal, midi_chan_inst1 );
+    }
+
+    Jet1_old = Jet1_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+ }
+
+
+ //send MIDI Filter 1 [Filter Instrument 1]
+
+ if ( filter1_new > filter1_old+jitter_thresh_short || filter1_new < filter1_old-jitter_thresh_short ) {         // maybe adding jitter threshold needed, see Jet1_new  
+ 
+    int16_t midiVal = constrain( map(filter1_new, 145, 756, 0, 127), 0, 127 );
+    if( midiVal != filter1_old_MIDI){
+      //Serial.println( midiVal );
+      filter1_old_MIDI = midiVal;
+      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst1);
+    }
+    
+    filter1_old = filter1_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+
+  //send MIDI Encoder 1 [Selection length Instrument 1]
+  if (Enc1_new != Enc1_old) {
+    Enc1_old = Enc1_new;
+    //Serial.println("Encoder 1: ");
+    //Serial.println(Enc1_new);
+    usbMIDI.sendControlChange(cc_length, Enc1_new, midi_chan_inst1);
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+
+  //send MIDI Encoder 3 [Duration Instrument 1]
+  if (Enc3_new != Enc3_old) {
+    Enc3_old = Enc3_new;
+    //Serial.println("Encoder 3: ");
+    //Serial.println(Enc3_new);
+    usbMIDI.sendControlChange(cc_duration, Enc3_new, midi_chan_inst1);
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+  
+  
+  //Instrument 2 Controls//////////////////////////////////////  
+  
+  //Loop/Keymode Switch Instrument 2
+   
+  if (button3.risingEdge()) {   
+    //Serial.println("Loop mode");
+    usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst2);
+  }
+  
+  if (button3.fallingEdge()) {   
+    //Serial.println("Keyboardmode mode");
+    usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst2);
+  }
+  
+  //Record Instrument 2
+  if (button4.fallingEdge()) {   
+    //Serial.println("RECORD! Instrument 2");
+    usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst2);
+  }
+
+  //send MIDI Wavejet 2 [Position Instrument 2]
+  
+  if (Jet2_new > Jet2_old+jitter_thresh || Jet2_new < Jet2_old-jitter_thresh) {
+    //Serial.println("RECORD! Instrument 2");
+    int16_t midiVal = constrain( map( Jet2_new, 109, 992, 149, 0 ), 0, 149 );
+    if( midiVal != Jet2_old_MIDI ){
+      Jet2_old_MIDI = midiVal;
+      usbMIDI.sendPitchBend( midiVal, midi_chan_inst2 );
+    }
+
+    Jet2_old = Jet2_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+  
+ //Serial.println(filter2_new);
+   if ( filter2_new > filter2_old+jitter_thresh_short || filter2_new < filter2_old-jitter_thresh_short ) {         // maybe adding jitter threshold needed, see Jet1_new  
+    int16_t midiVal = constrain( map(filter2_new, 132, 700, 0, 127), 0, 127 );
+    if( midiVal != filter2_old_MIDI){
+      //Serial.println( midiVal );
+      filter2_old_MIDI = midiVal;
+      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst2);
+    }
+    
+    filter2_old = filter2_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+   
+  
+  //send MIDI Encoder 2 [Selection length Instrument 2]
+  if (Enc2_new != Enc2_old) {
+    Enc2_old = Enc2_new;
+    //Serial.println("Encoder 2: ");
+    //Serial.println(Enc2_new);
+    usbMIDI.sendControlChange(cc_length, Enc2_new, midi_chan_inst2);
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+
+  //send MIDI Encoder 4 [Duration Instrument 2]
+  if (Enc4_new != Enc4_old) {
+    Enc4_old = Enc4_new;
+    //Serial.println("Encoder 4: ");
+    //Serial.println(Enc4_new);
+    usbMIDI.sendControlChange(cc_duration, Enc4_new, midi_chan_inst2);
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CollidoscopeTeensy/CollidoscopeTeensy_original.ino	Fri Jul 08 11:39:18 2016 +0200
@@ -0,0 +1,310 @@
+
+/******************************************************************************
+
+ *  Ben Bengler
+ *  mail@benbengler.com
+ *  02.05.2016
+ *
+ *  Collidoscope 
+ *  
+ *  Teensy 2 ++ pinout: https://www.pjrc.com/teensy/card4b.pdf
+ *  
+ *  ANALOG INPUTS:
+ *  Wavejet   -> F0 (38) [Horizontal rail 1]
+ *  Wavejet   -> F1 (39) [Horizontal rail 2]
+ *  Filter 1  -> F2 (40) [Vertical rail 1]
+ *  Filter 2  -> F4 (42) [Vertical rail 2] 
+ *
+ *  DIGITAL INPUTS [INTERRUPTS]:
+ *  Sel. length 1  -> INT0/INT1 (0, 1)  [Encoder 1]
+ *  Sel. length 2  -> INT2/INT3 (2, 3)  [Encoder 2]
+ *  Duration 1     -> INT4/INT5 (36, 37)[Encoder 3] 
+ *  Duration 2     -> INT6/INT7 (18, 19)[Encoder 4] 
+ *
+ *  DIGITAL INPUTS:
+ *  Play1 toggle  -> B0 (20)
+ *  Record1       -> B1 (21)
+ *  Play2 toggle  -> B3 (22)
+ *  Record2       -> B4 (24)
+ *  
+ *  DIGITAL OUTPUTS:
+ *  Record Button 1 Led -> D4 (4)
+ *  Record Button 2 Led -> D5 (5)
+
+ ******************************************************************************/ 
+
+
+#include <Encoder.h>
+#include <Bounce.h>
+
+///////////////////////////////////////////////////
+//MIDI settings
+const int midi_chan_inst1 = 1; // MIDI channel for Instrument 1
+const int midi_chan_inst2 = 2; // MIDI channel for Instrument 2
+
+const int cc_length = 1;    // MIDI cc controlling selection length
+const int cc_duration = 2;  // MIDI cc controlling duration
+const int cc_filter = 7;    // MIDI cc controlling LP filter
+const int cc_play = 4;      // MIDI cc controlling PLAY
+const int cc_record = 5;    // MIDI cc controlling RECORD
+//const int cc_reset = 100; // MIDI cc controlling instrument RESET
+
+///////////////////////////////////////////////////
+//Default Values:
+const int  Enc_def = 64; //default selection length  
+int MIDI_led_state = LOW;
+//boolean reset1 = true;
+//boolean reset2 = true;
+
+///////////////////////////////////////////////////
+// Interface Inputs
+
+//Buttons:
+
+const int Pin_play1 = 20;       //B0    
+const int Pin_record1 = 21;     //B1
+const int Pin_play2 = 23;       //B3
+const int Pin_record2 = 24;     //B4
+const int Pin_record1_led =  4; //D4
+const int Pin_record2_led =  5; //D5
+const int Pin_MIDIled =  6;
+
+//const int Pin_reset1 = 22;    //B2, not in use
+//const int Pin_reset2 = 25;    //B5, not in use
+
+Bounce button1 = Bounce(Pin_play1, 5); 
+Bounce button2 = Bounce(Pin_record1, 5); 
+Bounce button3 = Bounce(Pin_play2, 5); 
+Bounce button4 = Bounce(Pin_record2, 5); 
+
+ 
+//Encoder
+Encoder Enc1 (0, 1);  //Encoder for section length on Wavejet 1
+Encoder Enc2 (2, 3);  //Encoder for section length on Wavejet 2
+
+
+// Variables
+const int jitter_thresh = 10; //7threshold value for analog INs to suppress sending MIDI due to input jitter 
+
+void setup() {  
+
+pinMode(Pin_play1, INPUT_PULLUP); 
+pinMode(Pin_record1, INPUT_PULLUP);
+pinMode(Pin_play2, INPUT_PULLUP);
+pinMode(Pin_record2, INPUT_PULLUP);
+
+
+pinMode(Pin_MIDIled, OUTPUT); 
+pinMode(Pin_record1_led, OUTPUT);
+pinMode(Pin_record2_led, OUTPUT);
+}
+
+//Store recent values to detect parameter change
+long Enc1_old = -999;
+long Enc2_old = -999;
+
+uint16_t Jet1_old = 0;
+int16_t Jet1_old_MIDI = -1;
+uint16_t Jet2_old = 0;
+int16_t Jet2_old_MIDI = -1;
+
+uint16_t filter1_old = 0;
+int16_t filter1_old_MIDI = -1;
+uint16_t filter2_old = 0;
+int16_t filter2_old_MIDI = -1;
+
+uint16_t dur1_old = 0;
+int16_t dur1_old_MIDI = -1;
+uint16_t dur2_old = 0;
+int16_t dur2_old_MIDI = -1;
+
+void loop() {
+
+  digitalWrite(Pin_MIDIled, LOW);
+  digitalWrite(Pin_record1_led, HIGH);
+  digitalWrite(Pin_record2_led, HIGH);
+  button1.update();
+  button2.update();
+  button3.update();
+  button4.update();
+
+  
+  uint16_t Jet1_new = analogRead(0); //read Wavejet/Rail 1
+  uint16_t Jet2_new = analogRead(1); //read Wavejet/Rail 2
+  uint16_t filter1_new = analogRead(2);   //read filter Instrument 1; ADJUST INPUT RANGE ACCORDING TO SENSOR    
+  uint16_t filter2_new = analogRead(4);   //read filter Instrument 2; ADJUST INPUT RANGE ACCORDING TO SENSOR  
+  uint16_t dur1_new = analogRead(3); 
+  uint16_t dur2_new = analogRead(5);
+
+  
+  //Encoder 1 [Controls selection length of wave 1]
+  long Enc1_new = Enc1.read();
+  Enc1_new = constrain(Enc1_new, 0, 127); //constrain to 7-bit MIDI range
+  
+  //Dynamic reset of counter to MIDI range 
+  if (Enc1_new <= 0){
+    Enc1.write(0); 
+  }
+  else if (Enc1_new >= 127){
+    Enc1.write(127); 
+  }
+     
+  //Encoder 2 [Controls selection length of wave 2]
+  long Enc2_new = Enc2.read();
+  Enc2_new = constrain(Enc2_new, 0, 127); //constrain to 7-bit MIDI range
+  
+  //Dynamic reset of counter to MIDI range 
+  if (Enc2_new <= 0){
+    Enc2.write(0); 
+  }
+  else if (Enc2_new >= 127){
+    Enc2.write(127); 
+  }
+
+ //Instrument 1 Controls//////////////////////////////////////  
+ 
+ //Loop/Keymode Switch Instrument 1 
+   
+ if (button1.risingEdge()) {   
+   //Serial.println("Loop mode");
+   usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst1);
+ }
+   
+ if (button1.fallingEdge()) {   
+   //Serial.println("Keyboardmode mode");
+   usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst1);
+ }
+     
+   
+ //Record Instrument 1
+ if (button2.fallingEdge()) {   
+   //Serial.println("RECORD! Instrument 1");
+   usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst1);
+ }
+
+ //send MIDI Wavejet 1 [Position Instrument 1]
+ 
+ if (Jet1_new > Jet1_old+jitter_thresh || Jet1_new < Jet1_old-jitter_thresh) {
+    
+    int16_t midiVal = constrain( map(Jet1_new, 24, 926, 0, 149), 0, 149 );
+    // int16_t midiVal = constrain( map( Jet1_new, 23, 928, 0, 149 ), 0, 149 ); old collidoscope 
+    if( midiVal != Jet1_old_MIDI ){
+      Jet1_old_MIDI = midiVal;
+      usbMIDI.sendPitchBend( midiVal, midi_chan_inst1 );
+    }
+
+    Jet1_old = Jet1_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+ }
+
+
+ //send MIDI Filter 1 [Filter Instrument 1]
+
+ if ( filter1_new != filter1_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
+
+    int16_t midiVal = constrain( map(filter1_new, 0, 1024, 0, 127), 0, 127 );
+    if( midiVal != filter1_old_MIDI){
+      //Serial.println( midiVal );
+      filter1_old_MIDI = midiVal;
+      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst1);
+    }
+    
+    filter1_old = filter1_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+
+  if ( dur1_new != dur1_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
+ 
+    int16_t midiVal = constrain( map(dur1_new, 0, 1024, 0, 127), 0, 127 );
+    if( midiVal != dur1_old_MIDI){
+      //Serial.println( midiVal );
+      dur1_old_MIDI = midiVal;
+      usbMIDI.sendControlChange(cc_duration, midiVal, midi_chan_inst1);
+    }
+    
+    dur1_old = dur1_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+
+  //send MIDI Encoder 1 [Selection length Instrument 1]
+  if (Enc1_new != Enc1_old) {
+    Enc1_old = Enc1_new;
+    //Serial.println("Encoder 1: ");
+    //Serial.println(Enc1_new);
+    usbMIDI.sendControlChange(cc_length, Enc1_new, midi_chan_inst1);
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+
+  
+  
+  //Instrument 2 Controls//////////////////////////////////////  
+  
+  //Loop/Keymode Switch Instrument 2
+   
+  if (button3.risingEdge()) {   
+    //Serial.println("Loop mode");
+    usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst2);
+  }
+  
+  if (button3.fallingEdge()) {   
+    //Serial.println("Keyboardmode mode");
+    usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst2);
+  }
+  
+  //Record Instrument 2
+  if (button4.fallingEdge()) {   
+    //Serial.println("RECORD! Instrument 2");
+    usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst2);
+  }
+
+  //send MIDI Wavejet 2 [Position Instrument 2]
+  
+  if (Jet2_new > Jet2_old+jitter_thresh || Jet2_new < Jet2_old-jitter_thresh) {
+    //Serial.println("RECORD! Instrument 2");
+    int16_t midiVal = constrain( map( Jet2_new, 925, 18, 149, 0 ), 0, 149 );
+    if( midiVal != Jet2_old_MIDI ){
+      Jet2_old_MIDI = midiVal;
+      usbMIDI.sendPitchBend( midiVal, midi_chan_inst2 );
+    }
+
+    Jet2_old = Jet2_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+  
+ //Serial.println(filter2_new);
+   if ( filter2_new != filter2_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
+    int16_t midiVal = constrain( map(filter2_new, 0, 1024, 0, 127), 0, 127 );
+    if( midiVal != filter2_old_MIDI){
+      //Serial.println( midiVal );
+      filter2_old_MIDI = midiVal;
+      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst2);
+    }
+    
+    filter2_old = filter2_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+   }
+
+   if ( dur2_new != dur2_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
+    int16_t midiVal = constrain( map(dur2_new, 0, 1024, 0, 127), 0, 127 );
+    if( midiVal != dur2_old_MIDI){
+      //Serial.println( midiVal );
+      dur2_old_MIDI = midiVal;
+      usbMIDI.sendControlChange(cc_duration, midiVal, midi_chan_inst2);
+    }
+    
+    dur2_old = dur2_new;
+    digitalWrite(Pin_MIDIled, HIGH);
+   }
+   
+  
+  //send MIDI Encoder 2 [Selection length Instrument 2]
+  if (Enc2_new != Enc2_old) {
+    Enc2_old = Enc2_new;
+    //Serial.println("Encoder 2: ");
+    //Serial.println(Enc2_new);
+    usbMIDI.sendControlChange(cc_length, Enc2_new, midi_chan_inst2);
+    digitalWrite(Pin_MIDIled, HIGH);
+  }
+    
+}
+
--- a/JackDevice/ContextJack.cpp	Thu Jun 30 14:50:06 2016 +0200
+++ b/JackDevice/ContextJack.cpp	Fri Jul 08 11:39:18 2016 +0200
@@ -1,301 +1,301 @@
-/*
- Copyright (c) 2015, The Cinder Project
-
- This code is intended to be used with the Cinder C++ library, http://libcinder.org
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that
- the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice, this list of conditions and
-	the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-	the following disclaimer in the documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "cinder/audio/linux/ContextJack.h"
-#include "cinder/audio/Exception.h"
-
-namespace cinder { namespace audio { namespace linux {
-
-inline void zeroJackPort( jack_port_t *port, jack_nframes_t nframes )
-{   
-  // memset(port, 0, sizeof(jack_default_audio_sample_t) * nframes); 
-}
-
-inline void copyToJackPort(jack_port_t *port, float *source, jack_nframes_t nframes )
-{
-    // dest, source, n 
-    jack_default_audio_sample_t *out;
-    out = (jack_default_audio_sample_t *) jack_port_get_buffer( port, nframes );
-
-    memcpy( out, source, sizeof(jack_default_audio_sample_t) * nframes ) ;
-}
-
-inline void copyFromJackPort(jack_port_t *port, float *dest, jack_nframes_t nframes )
-{
-    // dest, source, n 
-    jack_default_audio_sample_t *in;
-    in = (jack_default_audio_sample_t *) jack_port_get_buffer( port, nframes );
-
-    memcpy( dest, in, sizeof(jack_default_audio_sample_t) * nframes ) ;
-}
-
-
-int OutputDeviceNodeJack::jackCallback(jack_nframes_t nframes, void* userData)
-{
-	RenderData *renderData = static_cast<RenderData *>( userData );
-
-	OutputDeviceNodeJack *outputDeviceNode = static_cast<OutputDeviceNodeJack *>( renderData->outputNode );
-
-	auto ctx = renderData->outputNode->getContext();
-	if( ! ctx ) {
-        for( size_t chan = 0; chan < 2; chan++)
-            // FIXME segfault at shutdown 
-		    zeroJackPort( outputDeviceNode->mOutputPorts[chan], nframes );
-
-		return 0;
-	}
-
-	std::lock_guard<std::mutex> lock( ctx->getMutex() );
-    
-	// verify associated context still exists, which may not be true if we blocked in ~Context() and were then deallocated.
-	ctx = renderData->outputNode->getContext();
-	if( ! ctx ) {
-
-        for( size_t chan = 0; chan < 2; chan++)
-		    zeroJackPort( outputDeviceNode->mOutputPorts[chan], nframes );
-
-		return 0;
-	}
-
-
-	Buffer *internalBuffer = outputDeviceNode->getInternalBuffer();
-	internalBuffer->zero();
-
-	ctx->preProcess();
-	outputDeviceNode->pullInputs( internalBuffer );
-    
-	// if clip detection is enabled and buffer clipped, silence it
-	if( false && outputDeviceNode->checkNotClipping() ){
-        for( size_t chan = 0; chan < 2; chan++)
-		    zeroJackPort( outputDeviceNode->mOutputPorts[chan], nframes );
-	} 
-    else {
-        for( size_t chan = 0; chan < 2; chan++)
-            copyToJackPort( outputDeviceNode->mOutputPorts[chan], internalBuffer->getChannel( chan ), nframes  );
-    }
-
-	ctx->postProcess();
-
-    return 0;
-}
-
-inline void OutputDeviceNodeJack::setInput( InputDeviceNodeRef inputDeviceNode) 
-{
-    mInputDeviceNode = std::static_pointer_cast<InputDeviceNodeJack>(inputDeviceNode);
-}
-
-ContextJack::ContextJack()
-{
-
-}
-
-ContextJack::~ContextJack()
-{
-
-}
-
-
-OutputDeviceNodeRef	ContextJack::createOutputDeviceNode( const DeviceRef &device, const Node::Format &format )
-{
-	
-    if( mOutputDeviceNode  == nullptr ) {
-        auto thisRef = std::static_pointer_cast<ContextJack>( shared_from_this() );
-
-        mOutputDeviceNode = makeNode( new OutputDeviceNodeJack( device, Node::Format().channels(2), thisRef ) ) ;
-
-        if( mInputDeviceNode != nullptr){
-            auto castedOutputDeviceNode = std::static_pointer_cast<OutputDeviceNodeJack>( mOutputDeviceNode );
-            castedOutputDeviceNode->setInput( mInputDeviceNode );   
-        }
-    }
-
-	return mOutputDeviceNode;
-}
-
-InputDeviceNodeRef ContextJack::createInputDeviceNode( const DeviceRef &device, const Node::Format &format  )
-{
-    if( mInputDeviceNode  == nullptr ) {
-        auto thisRef = std::static_pointer_cast<ContextJack>( shared_from_this() );
-
-        mInputDeviceNode = makeNode( new InputDeviceNodeJack( device, Node::Format().channels(2), thisRef ) ) ;
-
-        if( mOutputDeviceNode != nullptr){
-            auto castedOutputDeviceNode = std::static_pointer_cast<OutputDeviceNodeJack>( mOutputDeviceNode );
-            castedOutputDeviceNode->setInput( mInputDeviceNode );   
-        }
-    }
-
-	return mInputDeviceNode;
-}
-
-
-// OutputDeviceNodeJack 
-
-OutputDeviceNodeJack::OutputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context ):
-    OutputDeviceNode( device, format),
-    mCinderContext( context )
-{
-}
-
-void OutputDeviceNodeJack::initialize()
-{
-
-    const char *client_name = "Collidoscope";
-    const char *server_name = NULL;
-    jack_options_t options = JackNullOption;
-    jack_status_t status;
-
-    // connect to JAck server 
-    mClient = jack_client_open (client_name, options, &status, server_name);
-    if( mClient == NULL){
-
-        std::string msg = "jack_client_open() failed. "; 
-        if(status & JackServerFailed) 
-            msg += "Unable to connect to Jack server";
-
-        throw cinder::audio::AudioContextExc(msg);
-    }
-
-    
-    mRenderData.outputNode = this;
-    mRenderData.inputNode = mInputDeviceNode.get();
-    CI_ASSERT(mInputDeviceNode != nullptr);
-    mRenderData.context = static_cast<ContextJack *>( getContext().get() );
-
-    // install callback
-    jack_set_process_callback (mClient, jackCallback, &mRenderData );
-
-    // jack shutdown ? 
-    
-
-    // setup output ports 
-    mOutputPorts[0] = jack_port_register (mClient, "output1",
-                       JACK_DEFAULT_AUDIO_TYPE,
-                       JackPortIsOutput, 0);
-    
-    mOutputPorts[1] = jack_port_register (mClient, "output2",
-                       JACK_DEFAULT_AUDIO_TYPE,
-                       JackPortIsOutput, 0);
-    
-     if ((mOutputPorts[0] == NULL) || (mOutputPorts[0] == NULL)) {
-        throw cinder::audio::AudioContextExc("no more JACK ports available");
-     }
-
-    // setup input ports 
-    mInputDeviceNode->mInputPorts[0] = jack_port_register (mClient, "input1",
-                       JACK_DEFAULT_AUDIO_TYPE,
-                       JackPortIsInput, 0);
-
-    mInputDeviceNode->mInputPorts[1] = jack_port_register (mClient, "input2",
-                       JACK_DEFAULT_AUDIO_TYPE,
-                       JackPortIsInput, 0);
-
-
-    /* Tell the JACK server that we are ready to roll.  Our callback will start running now. */
-    if (jack_activate (mClient)) {
-        throw cinder::audio::AudioContextExc("cannot activate client");
-    }
-
-    // connect input ports to physical device (microphones)
-    const char **mikePorts = jack_get_ports (mClient, NULL, NULL,
-		JackPortIsPhysical|JackPortIsOutput);
-
-	if (mikePorts == NULL) {
-        throw cinder::audio::AudioContextExc("no physical input ports available");
-	}
-
-	if (jack_connect (mClient,  mikePorts[0], jack_port_name (mInputDeviceNode->mInputPorts[0]))) {
-        throw cinder::audio::AudioContextExc("cannot connect input port 0");
-	}
-
-	if (jack_connect (mClient, mikePorts[1], jack_port_name( mInputDeviceNode->mInputPorts[1]) )) {
-        throw cinder::audio::AudioContextExc("cannot connect input port 1");
-	}
-
-    // connect output ports to physical device (audio out )
-    const char **speakerPorts = jack_get_ports (mClient, NULL, NULL,
-				JackPortIsPhysical|JackPortIsInput);
-
-	if (speakerPorts == NULL) {
-        throw cinder::audio::AudioContextExc("no physical output ports available");
-	}
-
-	if (jack_connect (mClient, jack_port_name (mOutputPorts[0]), speakerPorts[0])) {
-        throw cinder::audio::AudioContextExc("cannot connect output port 0");
-	}
-
-	if (jack_connect (mClient, jack_port_name (mOutputPorts[1]), speakerPorts[1])) {
-        throw cinder::audio::AudioContextExc("cannot connect output port 1");
-	}
-
-	jack_free( mikePorts );
-	jack_free( speakerPorts );
-}
-
-
-void OutputDeviceNodeJack::uninitialize()
-{
-    jack_client_close( mClient );
-}
-
-void OutputDeviceNodeJack::enableProcessing()
-{
-}
-
-void OutputDeviceNodeJack::disableProcessing()
-{
-}
-
-
-//-------------------------- InputDeviceNodeJack -------------------------------
-
-
-InputDeviceNodeJack::InputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context ):
-    InputDeviceNode( device, format)
-{
-}
-
-void InputDeviceNodeJack::initialize() 
-{
-}
-
-void InputDeviceNodeJack::uninitialize()
-{
-}
-
-void InputDeviceNodeJack::enableProcessing()
-{
-}
-
-void InputDeviceNodeJack::disableProcessing()
-{
-}
-
-void InputDeviceNodeJack::process( Buffer *buffer )
-{
-    for( size_t chan = 0; chan < 2; chan++){
-       copyFromJackPort(mInputPorts[chan], buffer->getChannel( chan ), buffer->getNumFrames() ); 
-    }
-}
-
-} } } // namespace cinder::audio::linux
+/*
+ Copyright (c) 2015, The Cinder Project
+
+ This code is intended to be used with the Cinder C++ library, http://libcinder.org
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that
+ the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and
+	the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+	the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "cinder/audio/linux/ContextJack.h"
+#include "cinder/audio/Exception.h"
+
+namespace cinder { namespace audio { namespace linux {
+
+inline void zeroJackPort( jack_port_t *port, jack_nframes_t nframes )
+{   
+  // memset(port, 0, sizeof(jack_default_audio_sample_t) * nframes); 
+}
+
+inline void copyToJackPort(jack_port_t *port, float *source, jack_nframes_t nframes )
+{
+    // dest, source, n 
+    jack_default_audio_sample_t *out;
+    out = (jack_default_audio_sample_t *) jack_port_get_buffer( port, nframes );
+
+    memcpy( out, source, sizeof(jack_default_audio_sample_t) * nframes ) ;
+}
+
+inline void copyFromJackPort(jack_port_t *port, float *dest, jack_nframes_t nframes )
+{
+    // dest, source, n 
+    jack_default_audio_sample_t *in;
+    in = (jack_default_audio_sample_t *) jack_port_get_buffer( port, nframes );
+
+    memcpy( dest, in, sizeof(jack_default_audio_sample_t) * nframes ) ;
+}
+
+
+int OutputDeviceNodeJack::jackCallback(jack_nframes_t nframes, void* userData)
+{
+	RenderData *renderData = static_cast<RenderData *>( userData );
+
+	OutputDeviceNodeJack *outputDeviceNode = static_cast<OutputDeviceNodeJack *>( renderData->outputNode );
+
+	auto ctx = renderData->outputNode->getContext();
+	if( ! ctx ) {
+        for( size_t chan = 0; chan < 2; chan++)
+            // FIXME segfault at shutdown 
+		    zeroJackPort( outputDeviceNode->mOutputPorts[chan], nframes );
+
+		return 0;
+	}
+
+	std::lock_guard<std::mutex> lock( ctx->getMutex() );
+    
+	// verify associated context still exists, which may not be true if we blocked in ~Context() and were then deallocated.
+	ctx = renderData->outputNode->getContext();
+	if( ! ctx ) {
+
+        for( size_t chan = 0; chan < 2; chan++)
+		    zeroJackPort( outputDeviceNode->mOutputPorts[chan], nframes );
+
+		return 0;
+	}
+
+
+	Buffer *internalBuffer = outputDeviceNode->getInternalBuffer();
+	internalBuffer->zero();
+
+	ctx->preProcess();
+	outputDeviceNode->pullInputs( internalBuffer );
+    
+	// if clip detection is enabled and buffer clipped, silence it
+	if( false && outputDeviceNode->checkNotClipping() ){
+        for( size_t chan = 0; chan < 2; chan++)
+		    zeroJackPort( outputDeviceNode->mOutputPorts[chan], nframes );
+	} 
+    else {
+        for( size_t chan = 0; chan < 2; chan++)
+            copyToJackPort( outputDeviceNode->mOutputPorts[chan], internalBuffer->getChannel( chan ), nframes  );
+    }
+
+	ctx->postProcess();
+
+    return 0;
+}
+
+inline void OutputDeviceNodeJack::setInput( InputDeviceNodeRef inputDeviceNode) 
+{
+    mInputDeviceNode = std::static_pointer_cast<InputDeviceNodeJack>(inputDeviceNode);
+}
+
+ContextJack::ContextJack()
+{
+
+}
+
+ContextJack::~ContextJack()
+{
+
+}
+
+
+OutputDeviceNodeRef	ContextJack::createOutputDeviceNode( const DeviceRef &device, const Node::Format &format )
+{
+	
+    if( mOutputDeviceNode  == nullptr ) {
+        auto thisRef = std::static_pointer_cast<ContextJack>( shared_from_this() );
+
+        mOutputDeviceNode = makeNode( new OutputDeviceNodeJack( device, Node::Format().channels(2), thisRef ) ) ;
+
+        if( mInputDeviceNode != nullptr){
+            auto castedOutputDeviceNode = std::static_pointer_cast<OutputDeviceNodeJack>( mOutputDeviceNode );
+            castedOutputDeviceNode->setInput( mInputDeviceNode );   
+        }
+    }
+
+	return mOutputDeviceNode;
+}
+
+InputDeviceNodeRef ContextJack::createInputDeviceNode( const DeviceRef &device, const Node::Format &format  )
+{
+    if( mInputDeviceNode  == nullptr ) {
+        auto thisRef = std::static_pointer_cast<ContextJack>( shared_from_this() );
+
+        mInputDeviceNode = makeNode( new InputDeviceNodeJack( device, Node::Format().channels(2), thisRef ) ) ;
+
+        if( mOutputDeviceNode != nullptr){
+            auto castedOutputDeviceNode = std::static_pointer_cast<OutputDeviceNodeJack>( mOutputDeviceNode );
+            castedOutputDeviceNode->setInput( mInputDeviceNode );   
+        }
+    }
+
+	return mInputDeviceNode;
+}
+
+
+// OutputDeviceNodeJack 
+
+OutputDeviceNodeJack::OutputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context ):
+    OutputDeviceNode( device, format),
+    mCinderContext( context )
+{
+}
+
+void OutputDeviceNodeJack::initialize()
+{
+
+    const char *client_name = "Collidoscope";
+    const char *server_name = NULL;
+    jack_options_t options = JackNullOption;
+    jack_status_t status;
+
+    // connect to JAck server 
+    mClient = jack_client_open (client_name, options, &status, server_name);
+    if( mClient == NULL){
+
+        std::string msg = "jack_client_open() failed. "; 
+        if(status & JackServerFailed) 
+            msg += "Unable to connect to Jack server";
+
+        throw cinder::audio::AudioContextExc(msg);
+    }
+
+    
+    mRenderData.outputNode = this;
+    mRenderData.inputNode = mInputDeviceNode.get();
+    CI_ASSERT(mInputDeviceNode != nullptr);
+    mRenderData.context = static_cast<ContextJack *>( getContext().get() );
+
+    // install callback
+    jack_set_process_callback (mClient, jackCallback, &mRenderData );
+
+    // jack shutdown ? 
+    
+
+    // setup output ports 
+    mOutputPorts[0] = jack_port_register (mClient, "output1",
+                       JACK_DEFAULT_AUDIO_TYPE,
+                       JackPortIsOutput, 0);
+    
+    mOutputPorts[1] = jack_port_register (mClient, "output2",
+                       JACK_DEFAULT_AUDIO_TYPE,
+                       JackPortIsOutput, 0);
+    
+     if ((mOutputPorts[0] == NULL) || (mOutputPorts[0] == NULL)) {
+        throw cinder::audio::AudioContextExc("no more JACK ports available");
+     }
+
+    // setup input ports 
+    mInputDeviceNode->mInputPorts[0] = jack_port_register (mClient, "input1",
+                       JACK_DEFAULT_AUDIO_TYPE,
+                       JackPortIsInput, 0);
+
+    mInputDeviceNode->mInputPorts[1] = jack_port_register (mClient, "input2",
+                       JACK_DEFAULT_AUDIO_TYPE,
+                       JackPortIsInput, 0);
+
+
+    /* Tell the JACK server that we are ready to roll.  Our callback will start running now. */
+    if (jack_activate (mClient)) {
+        throw cinder::audio::AudioContextExc("cannot activate client");
+    }
+
+    // connect input ports to physical device (microphones)
+    const char **mikePorts = jack_get_ports (mClient, NULL, NULL,
+		JackPortIsPhysical|JackPortIsOutput);
+
+	if (mikePorts == NULL) {
+        throw cinder::audio::AudioContextExc("no physical input ports available");
+	}
+
+	if (jack_connect (mClient,  mikePorts[0], jack_port_name (mInputDeviceNode->mInputPorts[0]))) {
+        throw cinder::audio::AudioContextExc("cannot connect input port 0");
+	}
+
+	if (jack_connect (mClient, mikePorts[1], jack_port_name( mInputDeviceNode->mInputPorts[1]) )) {
+        throw cinder::audio::AudioContextExc("cannot connect input port 1");
+	}
+
+    // connect output ports to physical device (audio out )
+    const char **speakerPorts = jack_get_ports (mClient, NULL, NULL,
+				JackPortIsPhysical|JackPortIsInput);
+
+	if (speakerPorts == NULL) {
+        throw cinder::audio::AudioContextExc("no physical output ports available");
+	}
+
+	if (jack_connect (mClient, jack_port_name (mOutputPorts[0]), speakerPorts[0])) {
+        throw cinder::audio::AudioContextExc("cannot connect output port 0");
+	}
+
+	if (jack_connect (mClient, jack_port_name (mOutputPorts[1]), speakerPorts[1])) {
+        throw cinder::audio::AudioContextExc("cannot connect output port 1");
+	}
+
+	jack_free( mikePorts );
+	jack_free( speakerPorts );
+}
+
+
+void OutputDeviceNodeJack::uninitialize()
+{
+    jack_client_close( mClient );
+}
+
+void OutputDeviceNodeJack::enableProcessing()
+{
+}
+
+void OutputDeviceNodeJack::disableProcessing()
+{
+}
+
+
+//-------------------------- InputDeviceNodeJack -------------------------------
+
+
+InputDeviceNodeJack::InputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context ):
+    InputDeviceNode( device, format)
+{
+}
+
+void InputDeviceNodeJack::initialize() 
+{
+}
+
+void InputDeviceNodeJack::uninitialize()
+{
+}
+
+void InputDeviceNodeJack::enableProcessing()
+{
+}
+
+void InputDeviceNodeJack::disableProcessing()
+{
+}
+
+void InputDeviceNodeJack::process( Buffer *buffer )
+{
+    for( size_t chan = 0; chan < 2; chan++){
+       copyFromJackPort(mInputPorts[chan], buffer->getChannel( chan ), buffer->getNumFrames() ); 
+    }
+}
+
+} } } // namespace cinder::audio::linux
--- a/JackDevice/ContextJack.h	Thu Jun 30 14:50:06 2016 +0200
+++ b/JackDevice/ContextJack.h	Fri Jul 08 11:39:18 2016 +0200
@@ -1,103 +1,103 @@
-/*
- Copyright (c) 2015, The Cinder Project
-
- This code is intended to be used with the Cinder C++ library, http://libcinder.org
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that
- the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice, this list of conditions and
-	the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-	the following disclaimer in the documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#pragma once
-
-#include "cinder/audio/Context.h" 
-#include <jack/jack.h>
-
-namespace cinder { namespace audio { namespace linux {
-
-class ContextJack;
-class InputDeviceNodeJack;
-
-class OutputDeviceNodeJack : public OutputDeviceNode {
-  public:
-	OutputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context );
-
-    void setInput(InputDeviceNodeRef inputDeviceNode);
-
-  protected:
-	void initialize()				override;
-	void uninitialize()				override;
-	void enableProcessing()			override;
-	void disableProcessing()		override;
-	bool supportsProcessInPlace() const	override	{ return false; }
-
-  private:
-    static int jackCallback(jack_nframes_t nframes, void* userData);
-
-
-	void renderToBufferFromInputs();
-
-    struct RenderData{
-        RenderData() : inputNode(nullptr), outputNode(nullptr), context(nullptr){}
-        ~RenderData() { inputNode = nullptr; outputNode = nullptr;  context = nullptr; }
-        Node* outputNode;
-        Node* inputNode;
-        ContextJack* context;
-    } mRenderData;
-
-    std::weak_ptr<ContextJack>  mCinderContext;
-
-	jack_client_t *mClient;
-
-    std::array< jack_port_t*, 2 > mOutputPorts;
-
-    std::shared_ptr<InputDeviceNodeJack> mInputDeviceNode;
-};
-
-class InputDeviceNodeJack : public InputDeviceNode {
-  friend OutputDeviceNodeJack;
-
-  public:
-	InputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context );
-
-  protected:
-	void initialize()				override;
-	void uninitialize()				override;
-	void enableProcessing()			override;
-	void disableProcessing()		override;
-	void process( Buffer *buffer )	override;
-
-  private:
-    std::array< jack_port_t*, 2 > mInputPorts;
-};
-
-class ContextJack : public Context {
-  public:
-	ContextJack();
-	virtual ~ContextJack();
-    
-
-	OutputDeviceNodeRef	createOutputDeviceNode( const DeviceRef &device, const Node::Format &format = Node::Format() ) override;
-	InputDeviceNodeRef	createInputDeviceNode( const DeviceRef &device, const Node::Format &format = Node::Format()  ) override;
-
-    OutputDeviceNodeRef	mOutputDeviceNode;
-    InputDeviceNodeRef	mInputDeviceNode;
-
-
-  private:
-};	
-
-} } } // namespace cinder::audio::linux
+/*
+ Copyright (c) 2015, The Cinder Project
+
+ This code is intended to be used with the Cinder C++ library, http://libcinder.org
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that
+ the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and
+	the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+	the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+
+#include "cinder/audio/Context.h" 
+#include <jack/jack.h>
+
+namespace cinder { namespace audio { namespace linux {
+
+class ContextJack;
+class InputDeviceNodeJack;
+
+class OutputDeviceNodeJack : public OutputDeviceNode {
+  public:
+	OutputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context );
+
+    void setInput(InputDeviceNodeRef inputDeviceNode);
+
+  protected:
+	void initialize()				override;
+	void uninitialize()				override;
+	void enableProcessing()			override;
+	void disableProcessing()		override;
+	bool supportsProcessInPlace() const	override	{ return false; }
+
+  private:
+    static int jackCallback(jack_nframes_t nframes, void* userData);
+
+
+	void renderToBufferFromInputs();
+
+    struct RenderData{
+        RenderData() : inputNode(nullptr), outputNode(nullptr), context(nullptr){}
+        ~RenderData() { inputNode = nullptr; outputNode = nullptr;  context = nullptr; }
+        Node* outputNode;
+        Node* inputNode;
+        ContextJack* context;
+    } mRenderData;
+
+    std::weak_ptr<ContextJack>  mCinderContext;
+
+	jack_client_t *mClient;
+
+    std::array< jack_port_t*, 2 > mOutputPorts;
+
+    std::shared_ptr<InputDeviceNodeJack> mInputDeviceNode;
+};
+
+class InputDeviceNodeJack : public InputDeviceNode {
+  friend OutputDeviceNodeJack;
+
+  public:
+	InputDeviceNodeJack( const DeviceRef &device, const Format &format, const std::shared_ptr<ContextJack> &context );
+
+  protected:
+	void initialize()				override;
+	void uninitialize()				override;
+	void enableProcessing()			override;
+	void disableProcessing()		override;
+	void process( Buffer *buffer )	override;
+
+  private:
+    std::array< jack_port_t*, 2 > mInputPorts;
+};
+
+class ContextJack : public Context {
+  public:
+	ContextJack();
+	virtual ~ContextJack();
+    
+
+	OutputDeviceNodeRef	createOutputDeviceNode( const DeviceRef &device, const Node::Format &format = Node::Format() ) override;
+	InputDeviceNodeRef	createInputDeviceNode( const DeviceRef &device, const Node::Format &format = Node::Format()  ) override;
+
+    OutputDeviceNodeRef	mOutputDeviceNode;
+    InputDeviceNodeRef	mInputDeviceNode;
+
+
+  private:
+};	
+
+} } } // namespace cinder::audio::linux
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/JackDevice/DeviceManagerJack.cpp	Fri Jul 08 11:39:18 2016 +0200
@@ -0,0 +1,133 @@
+/*
+ Copyright (c) 2015, The Cinder Project
+
+ This code is intended to be used with the Cinder C++ library, http://libcinder.org
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that
+ the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and
+	
+    the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+	the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "cinder/audio/linux/DeviceManagerJack.h"
+#include "cinder/audio/Exception.h"
+#include <jack/jack.h>
+
+
+namespace cinder { namespace audio { namespace linux {
+
+DeviceManagerJack::DeviceManagerJack() 
+{
+
+    mDevices.push_back( addDevice("JackIn") );
+    mDevices.push_back( addDevice("JackOut") );
+
+    jack_status_t status;
+    
+	jack_client_t *client = jack_client_open ("device info", JackNullOption, &status, NULL);
+    if( client == NULL){
+
+        std::string msg = "jack_client_open() failed. "; 
+        if(status & JackServerFailed) 
+            msg += "Unable to connect to Jack server";
+
+        throw cinder::audio::AudioContextExc(msg);
+    }
+
+    mSampleRate = jack_get_sample_rate( client );
+    mBufferSize = jack_get_buffer_size( client );
+
+    jack_client_close( client );
+}
+
+DeviceManagerJack::~DeviceManagerJack()
+{
+	
+}
+
+const std::vector<DeviceRef>& DeviceManagerJack::getDevices()
+{
+   return mDevices;
+}
+
+DeviceRef DeviceManagerJack::getDefaultOutput()
+{
+    return mDevices[1];
+}
+
+DeviceRef DeviceManagerJack::getDefaultInput()
+{
+    return mDevices[0];
+}
+
+std::string DeviceManagerJack::getName( const DeviceRef &device )
+{
+    return device->getKey();
+}
+
+size_t DeviceManagerJack::getNumInputChannels( const DeviceRef &device )
+{
+    if( device->getKey() == mDevices[0]->getKey() )
+        return 2;
+    else
+        return 0;
+}
+
+size_t DeviceManagerJack::getNumOutputChannels( const DeviceRef &device )
+{
+    if( device->getKey() == mDevices[1]->getKey() )
+        return 2;
+    else
+        return 0;
+}
+
+size_t DeviceManagerJack::getSampleRate( const DeviceRef &device )
+{
+    return mSampleRate;
+}
+
+size_t DeviceManagerJack::getFramesPerBlock( const DeviceRef &device )
+{
+    return mBufferSize;
+}
+
+
+void DeviceManagerJack::setSampleRate( const DeviceRef &device, size_t sampleRate )
+{
+    throw "setSampleRate not supported";
+}
+
+void DeviceManagerJack::setFramesPerBlock( const DeviceRef &device, size_t framesPerBlock )
+{
+    throw "setFramesPerBlock not supported";
+}
+
+
+//! Returns the hardware's actual frames per block, which might not be a power of two.
+//        size_t getFramesPerBlockHardware( const DeviceRef &device );
+//
+
+size_t DeviceManagerJack::getFramesPerBlockHardware( const DeviceRef &device )
+{
+    return mBufferSize;
+}
+
+
+
+
+
+
+} } } // namespace cinder::audio::linux
--- a/JackDevice/DeviceManagerJack.h	Thu Jun 30 14:50:06 2016 +0200
+++ b/JackDevice/DeviceManagerJack.h	Fri Jul 08 11:39:18 2016 +0200
@@ -1,61 +1,61 @@
-/*
- Copyright (c) 2015, The Cinder Project
-
- This code is intended to be used with the Cinder C++ library, http://libcinder.org
-
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that
- the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice, this list of conditions and
-	the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
-	the following disclaimer in the documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#pragma once
-
-#include "cinder/audio/Device.h"
-
-namespace cinder { namespace audio { namespace linux {
-
-class DeviceManagerJack : public DeviceManager {
-  public:
-
-	DeviceManagerJack();
-	virtual ~DeviceManagerJack();
-
-	const std::vector<DeviceRef>& getDevices()		override;
-	DeviceRef getDefaultOutput()				override;
-	DeviceRef getDefaultInput()				override;
-
-	std::string getName( const DeviceRef &device ) 		override;
-	size_t getNumInputChannels( const DeviceRef &device )	override;
-	size_t getNumOutputChannels( const DeviceRef &device )	override;
-	size_t getSampleRate( const DeviceRef &device )		override;
-	size_t getFramesPerBlock( const DeviceRef &device )	override;
-
-	void setSampleRate( const DeviceRef &device, size_t sampleRate )		override;
-	void setFramesPerBlock( const DeviceRef &device, size_t framesPerBlock )	override;
-
-	//! Returns the hardware's actual frames per block, which might not be a power of two.
-	size_t getFramesPerBlockHardware( const DeviceRef &device );
-
-private:
-
-	std::vector<DeviceRef> mDevices;
-	DeviceRef   mDefaultOutDevice;
-	DeviceRef   mDefaultInDevice;
-    size_t mSampleRate;
-    size_t mBufferSize;
-};	
-
-} } } // namespace cinder::audio::linux 	
+/*
+ Copyright (c) 2015, The Cinder Project
+
+ This code is intended to be used with the Cinder C++ library, http://libcinder.org
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that
+ the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and
+	the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+	the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+
+#include "cinder/audio/Device.h"
+
+namespace cinder { namespace audio { namespace linux {
+
+class DeviceManagerJack : public DeviceManager {
+  public:
+
+	DeviceManagerJack();
+	virtual ~DeviceManagerJack();
+
+	const std::vector<DeviceRef>& getDevices()		override;
+	DeviceRef getDefaultOutput()				override;
+	DeviceRef getDefaultInput()				override;
+
+	std::string getName( const DeviceRef &device ) 		override;
+	size_t getNumInputChannels( const DeviceRef &device )	override;
+	size_t getNumOutputChannels( const DeviceRef &device )	override;
+	size_t getSampleRate( const DeviceRef &device )		override;
+	size_t getFramesPerBlock( const DeviceRef &device )	override;
+
+	void setSampleRate( const DeviceRef &device, size_t sampleRate )		override;
+	void setFramesPerBlock( const DeviceRef &device, size_t framesPerBlock )	override;
+
+	//! Returns the hardware's actual frames per block, which might not be a power of two.
+	size_t getFramesPerBlockHardware( const DeviceRef &device );
+
+private:
+
+	std::vector<DeviceRef> mDevices;
+	DeviceRef   mDefaultOutDevice;
+	DeviceRef   mDefaultInDevice;
+    size_t mSampleRate;
+    size_t mBufferSize;
+};	
+
+} } } // namespace cinder::audio::linux 	
--- a/TeensyCode/collidoscope_double_knob.ino	Thu Jun 30 14:50:06 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-
-/******************************************************************************
-
- *  Ben Bengler
- *  mail@benbengler.com
- *  02.05.2016
- *
- *  Collidoscope 
- *  
- *  Teensy 2 ++ pinout: https://www.pjrc.com/teensy/card4b.pdf
- *  
- *  ANALOG INPUTS:
- *  Wavejet   -> F0 (38) [Horizontal rail 1]
- *  Wavejet   -> F1 (39) [Horizontal rail 2]
- *  Filter 1  -> F2 (40) [Vertical rail 1]
- *  Filter 2  -> F4 (42) [Vertical rail 2] 
- *
- *  DIGITAL INPUTS [INTERRUPTS]:
- *  Sel. length 1  -> INT0/INT1 (0, 1)  [Encoder 1]
- *  Sel. length 2  -> INT2/INT3 (2, 3)  [Encoder 2]
- *  Duration 1     -> INT4/INT5 (36, 37)[Encoder 3] 
- *  Duration 2     -> INT6/INT7 (18, 19)[Encoder 4] 
- *
- *  DIGITAL INPUTS:
- *  Play1 toggle  -> B0 (20)
- *  Record1       -> B1 (21)
- *  Play2 toggle  -> B3 (22)
- *  Record2       -> B4 (24)
- *  
- *  DIGITAL OUTPUTS:
- *  Record Button 1 Led -> D4 (4)
- *  Record Button 2 Led -> D5 (5)
-
- ******************************************************************************/ 
-
-
-#include <Encoder.h>
-#include <Bounce.h>
-
-///////////////////////////////////////////////////
-//MIDI settings
-const int midi_chan_inst1 = 1; // MIDI channel for Instrument 1
-const int midi_chan_inst2 = 2; // MIDI channel for Instrument 2
-
-const int cc_length = 1;    // MIDI cc controlling selection length
-const int cc_duration = 2;  // MIDI cc controlling duration
-const int cc_filter = 7;    // MIDI cc controlling LP filter
-const int cc_play = 4;      // MIDI cc controlling PLAY
-const int cc_record = 5;    // MIDI cc controlling RECORD
-//const int cc_reset = 100; // MIDI cc controlling instrument RESET
-
-///////////////////////////////////////////////////
-//Default Values:
-const int  Enc_def = 64; //default selection length  
-int MIDI_led_state = LOW;
-//boolean reset1 = true;
-//boolean reset2 = true;
-
-///////////////////////////////////////////////////
-// Interface Inputs
-
-//Buttons:
-
-const int Pin_play1 = 20;       //B0    
-const int Pin_record1 = 21;     //B1
-const int Pin_play2 = 23;       //B3
-const int Pin_record2 = 24;     //B4
-const int Pin_record1_led =  4; //D4
-const int Pin_record2_led =  5; //D5
-const int Pin_MIDIled =  6;
-
-//const int Pin_reset1 = 22;    //B2, not in use
-//const int Pin_reset2 = 25;    //B5, not in use
-
-Bounce button1 = Bounce(Pin_play1, 5); 
-Bounce button2 = Bounce(Pin_record1, 5); 
-Bounce button3 = Bounce(Pin_play2, 5); 
-Bounce button4 = Bounce(Pin_record2, 5); 
-
- 
-//Encoder
-Encoder Enc1 (0, 1);  //Encoder for section length on Wavejet 1
-Encoder Enc2 (2, 3);  //Encoder for section length on Wavejet 2
-
-
-// Variables
-const int jitter_thresh = 10; //7threshold value for analog INs to suppress sending MIDI due to input jitter 
-
-void setup() {  
-
-pinMode(Pin_play1, INPUT_PULLUP); 
-pinMode(Pin_record1, INPUT_PULLUP);
-pinMode(Pin_play2, INPUT_PULLUP);
-pinMode(Pin_record2, INPUT_PULLUP);
-
-
-pinMode(Pin_MIDIled, OUTPUT); 
-pinMode(Pin_record1_led, OUTPUT);
-pinMode(Pin_record2_led, OUTPUT);
-}
-
-//Store recent values to detect parameter change
-long Enc1_old = -999;
-long Enc2_old = -999;
-
-uint16_t Jet1_old = 0;
-int16_t Jet1_old_MIDI = -1;
-uint16_t Jet2_old = 0;
-int16_t Jet2_old_MIDI = -1;
-
-uint16_t filter1_old = 0;
-int16_t filter1_old_MIDI = -1;
-uint16_t filter2_old = 0;
-int16_t filter2_old_MIDI = -1;
-
-uint16_t dur1_old = 0;
-int16_t dur1_old_MIDI = -1;
-uint16_t dur2_old = 0;
-int16_t dur2_old_MIDI = -1;
-
-void loop() {
-
-  digitalWrite(Pin_MIDIled, LOW);
-  digitalWrite(Pin_record1_led, HIGH);
-  digitalWrite(Pin_record2_led, HIGH);
-  button1.update();
-  button2.update();
-  button3.update();
-  button4.update();
-
-  
-  uint16_t Jet1_new = analogRead(0); //read Wavejet/Rail 1
-  uint16_t Jet2_new = analogRead(1); //read Wavejet/Rail 2
-  uint16_t filter1_new = analogRead(2);   //read filter Instrument 1; ADJUST INPUT RANGE ACCORDING TO SENSOR    
-  uint16_t filter2_new = analogRead(4);   //read filter Instrument 2; ADJUST INPUT RANGE ACCORDING TO SENSOR  
-  uint16_t dur1_new = analogRead(3); 
-  uint16_t dur2_new = analogRead(5);
-
-  
-  //Encoder 1 [Controls selection length of wave 1]
-  long Enc1_new = Enc1.read();
-  Enc1_new = constrain(Enc1_new, 0, 127); //constrain to 7-bit MIDI range
-  
-  //Dynamic reset of counter to MIDI range 
-  if (Enc1_new <= 0){
-    Enc1.write(0); 
-  }
-  else if (Enc1_new >= 127){
-    Enc1.write(127); 
-  }
-     
-  //Encoder 2 [Controls selection length of wave 2]
-  long Enc2_new = Enc2.read();
-  Enc2_new = constrain(Enc2_new, 0, 127); //constrain to 7-bit MIDI range
-  
-  //Dynamic reset of counter to MIDI range 
-  if (Enc2_new <= 0){
-    Enc2.write(0); 
-  }
-  else if (Enc2_new >= 127){
-    Enc2.write(127); 
-  }
-
- //Instrument 1 Controls//////////////////////////////////////  
- 
- //Loop/Keymode Switch Instrument 1 
-   
- if (button1.risingEdge()) {   
-   //Serial.println("Loop mode");
-   usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst1);
- }
-   
- if (button1.fallingEdge()) {   
-   //Serial.println("Keyboardmode mode");
-   usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst1);
- }
-     
-   
- //Record Instrument 1
- if (button2.fallingEdge()) {   
-   //Serial.println("RECORD! Instrument 1");
-   usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst1);
- }
-
- //send MIDI Wavejet 1 [Position Instrument 1]
- 
- if (Jet1_new > Jet1_old+jitter_thresh || Jet1_new < Jet1_old-jitter_thresh) {
-    
-    int16_t midiVal = constrain( map(Jet1_new, 24, 926, 0, 149), 0, 149 );
-    // int16_t midiVal = constrain( map( Jet1_new, 23, 928, 0, 149 ), 0, 149 ); old collidoscope 
-    if( midiVal != Jet1_old_MIDI ){
-      Jet1_old_MIDI = midiVal;
-      usbMIDI.sendPitchBend( midiVal, midi_chan_inst1 );
-    }
-
-    Jet1_old = Jet1_new;
-    digitalWrite(Pin_MIDIled, HIGH);
- }
-
-
- //send MIDI Filter 1 [Filter Instrument 1]
-
- if ( filter1_new != filter1_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
-
-    int16_t midiVal = constrain( map(filter1_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != filter1_old_MIDI){
-      //Serial.println( midiVal );
-      filter1_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst1);
-    }
-    
-    filter1_old = filter1_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-
-  if ( dur1_new != dur1_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
- 
-    int16_t midiVal = constrain( map(dur1_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != dur1_old_MIDI){
-      //Serial.println( midiVal );
-      dur1_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_duration, midiVal, midi_chan_inst1);
-    }
-    
-    dur1_old = dur1_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-
-  //send MIDI Encoder 1 [Selection length Instrument 1]
-  if (Enc1_new != Enc1_old) {
-    Enc1_old = Enc1_new;
-    //Serial.println("Encoder 1: ");
-    //Serial.println(Enc1_new);
-    usbMIDI.sendControlChange(cc_length, Enc1_new, midi_chan_inst1);
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-
-  
-  
-  //Instrument 2 Controls//////////////////////////////////////  
-  
-  //Loop/Keymode Switch Instrument 2
-   
-  if (button3.risingEdge()) {   
-    //Serial.println("Loop mode");
-    usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst2);
-  }
-  
-  if (button3.fallingEdge()) {   
-    //Serial.println("Keyboardmode mode");
-    usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst2);
-  }
-  
-  //Record Instrument 2
-  if (button4.fallingEdge()) {   
-    //Serial.println("RECORD! Instrument 2");
-    usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst2);
-  }
-
-  //send MIDI Wavejet 2 [Position Instrument 2]
-  
-  if (Jet2_new > Jet2_old+jitter_thresh || Jet2_new < Jet2_old-jitter_thresh) {
-    //Serial.println("RECORD! Instrument 2");
-    int16_t midiVal = constrain( map( Jet2_new, 925, 18, 149, 0 ), 0, 149 );
-    if( midiVal != Jet2_old_MIDI ){
-      Jet2_old_MIDI = midiVal;
-      usbMIDI.sendPitchBend( midiVal, midi_chan_inst2 );
-    }
-
-    Jet2_old = Jet2_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-  
- //Serial.println(filter2_new);
-   if ( filter2_new != filter2_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
-    int16_t midiVal = constrain( map(filter2_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != filter2_old_MIDI){
-      //Serial.println( midiVal );
-      filter2_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst2);
-    }
-    
-    filter2_old = filter2_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-   }
-
-   if ( dur2_new != dur2_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
-    int16_t midiVal = constrain( map(dur2_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != dur2_old_MIDI){
-      //Serial.println( midiVal );
-      dur2_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_duration, midiVal, midi_chan_inst2);
-    }
-    
-    dur2_old = dur2_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-   }
-   
-  
-  //send MIDI Encoder 2 [Selection length Instrument 2]
-  if (Enc2_new != Enc2_old) {
-    Enc2_old = Enc2_new;
-    //Serial.println("Encoder 2: ");
-    //Serial.println(Enc2_new);
-    usbMIDI.sendControlChange(cc_length, Enc2_new, midi_chan_inst2);
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-    
-}
-
--- a/TeensyCode/collidoscope_single_knob.ino	Thu Jun 30 14:50:06 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-
-/******************************************************************************
-
- *  Ben Bengler
- *  mail@benbengler.com
- *  02.05.2016
- *
- *  Collidoscope 
- *  
- *  Teensy 2 ++ pinout: https://www.pjrc.com/teensy/card4b.pdf
- *  
- *  ANALOG INPUTS:
- *  Wavejet   -> F0 (38) [Horizontal rail 1]
- *  Wavejet   -> F1 (39) [Horizontal rail 2]
- *  Filter 1  -> F2 (40) [Vertical rail 1]
- *  Filter 2  -> F4 (42) [Vertical rail 2] 
- *
- *  DIGITAL INPUTS [INTERRUPTS]:
- *  Sel. length 1  -> INT0/INT1 (0, 1)  [Encoder 1]
- *  Sel. length 2  -> INT2/INT3 (2, 3)  [Encoder 2]
- *  Duration 1     -> INT4/INT5 (36, 37)[Encoder 3] 
- *  Duration 2     -> INT6/INT7 (18, 19)[Encoder 4] 
- *
- *  DIGITAL INPUTS:
- *  Play1 toggle  -> B0 (20)
- *  Record1       -> B1 (21)
- *  Play2 toggle  -> B3 (22)
- *  Record2       -> B4 (24)
- *  
- *  DIGITAL OUTPUTS:
- *  Record Button 1 Led -> D4 (4)
- *  Record Button 2 Led -> D5 (5)
-
- ******************************************************************************/ 
-
-
-#include <Encoder.h>
-#include <Bounce.h>
-
-///////////////////////////////////////////////////
-//MIDI settings
-const int midi_chan_inst1 = 1; // MIDI channel for Instrument 1
-const int midi_chan_inst2 = 2; // MIDI channel for Instrument 2
-
-const int cc_length = 1;    // MIDI cc controlling selection length
-const int cc_duration = 2;  // MIDI cc controlling duration
-const int cc_filter = 7;    // MIDI cc controlling LP filter
-const int cc_play = 4;      // MIDI cc controlling PLAY
-const int cc_record = 5;    // MIDI cc controlling RECORD
-//const int cc_reset = 100; // MIDI cc controlling instrument RESET
-
-///////////////////////////////////////////////////
-//Default Values:
-const int  Enc_def = 64; //default selection length  
-int MIDI_led_state = LOW;
-//boolean reset1 = true;
-//boolean reset2 = true;
-
-///////////////////////////////////////////////////
-// Interface Inputs
-
-//Buttons:
-
-const int Pin_play1 = 20;       //B0    
-const int Pin_record1 = 21;     //B1
-const int Pin_play2 = 23;       //B3
-const int Pin_record2 = 24;     //B4
-const int Pin_record1_led =  4; //D4
-const int Pin_record2_led =  5; //D5
-const int Pin_MIDIled =  6;
-
-//const int Pin_reset1 = 22;    //B2, not in use
-//const int Pin_reset2 = 25;    //B5, not in use
-
-Bounce button1 = Bounce(Pin_play1, 5); 
-Bounce button2 = Bounce(Pin_record1, 5); 
-Bounce button3 = Bounce(Pin_play2, 5); 
-Bounce button4 = Bounce(Pin_record2, 5); 
-
- 
-//Encoder
-Encoder Enc1 (0, 1);  //Encoder for section length on Wavejet 1
-Encoder Enc2 (2, 3);  //Encoder for section length on Wavejet 2
-
-
-// Variables
-const int jitter_thresh = 10; //7threshold value for analog INs to suppress sending MIDI due to input jitter 
-
-void setup() {  
-
-pinMode(Pin_play1, INPUT_PULLUP); 
-pinMode(Pin_record1, INPUT_PULLUP);
-pinMode(Pin_play2, INPUT_PULLUP);
-pinMode(Pin_record2, INPUT_PULLUP);
-
-
-pinMode(Pin_MIDIled, OUTPUT); 
-pinMode(Pin_record1_led, OUTPUT);
-pinMode(Pin_record2_led, OUTPUT);
-}
-
-//Store recent values to detect parameter change
-long Enc1_old = -999;
-long Enc2_old = -999;
-
-uint16_t Jet1_old = 0;
-int16_t Jet1_old_MIDI = -1;
-uint16_t Jet2_old = 0;
-int16_t Jet2_old_MIDI = -1;
-
-uint16_t filter1_old = 0;
-int16_t filter1_old_MIDI = -1;
-uint16_t filter2_old = 0;
-int16_t filter2_old_MIDI = -1;
-
-uint16_t dur1_old = 0;
-int16_t dur1_old_MIDI = -1;
-uint16_t dur2_old = 0;
-int16_t dur2_old_MIDI = -1;
-
-void loop() {
-
-  digitalWrite(Pin_MIDIled, LOW);
-  digitalWrite(Pin_record1_led, HIGH);
-  digitalWrite(Pin_record2_led, HIGH);
-  button1.update();
-  button2.update();
-  button3.update();
-  button4.update();
-
-  
-  uint16_t Jet1_new = analogRead(0); //read Wavejet/Rail 1
-  uint16_t Jet2_new = analogRead(1); //read Wavejet/Rail 2
-  uint16_t filter1_new = analogRead(2);   //read filter Instrument 1; ADJUST INPUT RANGE ACCORDING TO SENSOR    
-  uint16_t filter2_new = analogRead(4);   //read filter Instrument 2; ADJUST INPUT RANGE ACCORDING TO SENSOR  
-  uint16_t dur1_new = analogRead(3); 
-  uint16_t dur2_new = analogRead(5);
-
-  
-  //Encoder 1 [Controls selection length of wave 1]
-  long Enc1_new = Enc1.read();
-  Enc1_new = constrain(Enc1_new, 0, 127); //constrain to 7-bit MIDI range
-  
-  //Dynamic reset of counter to MIDI range 
-  if (Enc1_new <= 0){
-    Enc1.write(0); 
-  }
-  else if (Enc1_new >= 127){
-    Enc1.write(127); 
-  }
-     
-  //Encoder 2 [Controls selection length of wave 2]
-  long Enc2_new = Enc2.read();
-  Enc2_new = constrain(Enc2_new, 0, 127); //constrain to 7-bit MIDI range
-  
-  //Dynamic reset of counter to MIDI range 
-  if (Enc2_new <= 0){
-    Enc2.write(0); 
-  }
-  else if (Enc2_new >= 127){
-    Enc2.write(127); 
-  }
-
- //Instrument 1 Controls//////////////////////////////////////  
- 
- //Loop/Keymode Switch Instrument 1 
-   
- if (button1.risingEdge()) {   
-   //Serial.println("Loop mode");
-   usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst1);
- }
-   
- if (button1.fallingEdge()) {   
-   //Serial.println("Keyboardmode mode");
-   usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst1);
- }
-     
-   
- //Record Instrument 1
- if (button2.fallingEdge()) {   
-   //Serial.println("RECORD! Instrument 1");
-   usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst1);
- }
-
- //send MIDI Wavejet 1 [Position Instrument 1]
- 
- if (Jet1_new > Jet1_old+jitter_thresh || Jet1_new < Jet1_old-jitter_thresh) {
-    
-    int16_t midiVal = constrain( map(Jet1_new, 24, 926, 0, 149), 0, 149 );
-    // int16_t midiVal = constrain( map( Jet1_new, 23, 928, 0, 149 ), 0, 149 ); old collidoscope 
-    if( midiVal != Jet1_old_MIDI ){
-      Jet1_old_MIDI = midiVal;
-      usbMIDI.sendPitchBend( midiVal, midi_chan_inst1 );
-    }
-
-    Jet1_old = Jet1_new;
-    digitalWrite(Pin_MIDIled, HIGH);
- }
-
-
- //send MIDI Filter 1 [Filter Instrument 1]
-
- if ( filter1_new != filter1_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
-
-    int16_t midiVal = constrain( map(filter1_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != filter1_old_MIDI){
-      //Serial.println( midiVal );
-      filter1_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst1);
-    }
-    
-    filter1_old = filter1_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-
-  if ( dur1_new != dur1_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
- 
-    int16_t midiVal = constrain( map(dur1_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != dur1_old_MIDI){
-      //Serial.println( midiVal );
-      dur1_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_duration, midiVal, midi_chan_inst1);
-    }
-    
-    dur1_old = dur1_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-
-  //send MIDI Encoder 1 [Selection length Instrument 1]
-  if (Enc1_new != Enc1_old) {
-    Enc1_old = Enc1_new;
-    //Serial.println("Encoder 1: ");
-    //Serial.println(Enc1_new);
-    usbMIDI.sendControlChange(cc_length, Enc1_new, midi_chan_inst1);
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-
-  
-  
-  //Instrument 2 Controls//////////////////////////////////////  
-  
-  //Loop/Keymode Switch Instrument 2
-   
-  if (button3.risingEdge()) {   
-    //Serial.println("Loop mode");
-    usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst2);
-  }
-  
-  if (button3.fallingEdge()) {   
-    //Serial.println("Keyboardmode mode");
-    usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst2);
-  }
-  
-  //Record Instrument 2
-  if (button4.fallingEdge()) {   
-    //Serial.println("RECORD! Instrument 2");
-    usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst2);
-  }
-
-  //send MIDI Wavejet 2 [Position Instrument 2]
-  
-  if (Jet2_new > Jet2_old+jitter_thresh || Jet2_new < Jet2_old-jitter_thresh) {
-    //Serial.println("RECORD! Instrument 2");
-    int16_t midiVal = constrain( map( Jet2_new, 925, 18, 149, 0 ), 0, 149 );
-    if( midiVal != Jet2_old_MIDI ){
-      Jet2_old_MIDI = midiVal;
-      usbMIDI.sendPitchBend( midiVal, midi_chan_inst2 );
-    }
-
-    Jet2_old = Jet2_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-  
- //Serial.println(filter2_new);
-   if ( filter2_new != filter2_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
-    int16_t midiVal = constrain( map(filter2_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != filter2_old_MIDI){
-      //Serial.println( midiVal );
-      filter2_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst2);
-    }
-    
-    filter2_old = filter2_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-   }
-
-   if ( dur2_new != dur2_old ) {         // maybe adding jitter threshold needed, see Jet1_new  
-    int16_t midiVal = constrain( map(dur2_new, 0, 1024, 0, 127), 0, 127 );
-    if( midiVal != dur2_old_MIDI){
-      //Serial.println( midiVal );
-      dur2_old_MIDI = midiVal;
-      usbMIDI.sendControlChange(cc_duration, midiVal, midi_chan_inst2);
-    }
-    
-    dur2_old = dur2_new;
-    digitalWrite(Pin_MIDIled, HIGH);
-   }
-   
-  
-  //send MIDI Encoder 2 [Selection length Instrument 2]
-  if (Enc2_new != Enc2_old) {
-    Enc2_old = Enc2_new;
-    //Serial.println("Encoder 2: ");
-    //Serial.println(Enc2_new);
-    usbMIDI.sendControlChange(cc_length, Enc2_new, midi_chan_inst2);
-    digitalWrite(Pin_MIDIled, HIGH);
-  }
-    
-}
-