Full Code of trash80/Arduinoboy for AI

master 5bb05a905f70 cached
18 files
291.8 KB
105.2k tokens
1 requests
Download .txt
Showing preview only (302K chars total). Download the full file or copy to clipboard to get everything.
Repository: trash80/Arduinoboy
Branch: master
Commit: 5bb05a905f70
Files: 18
Total size: 291.8 KB

Directory structure:
gitextract_yht0xf5z/

├── Arduinoboy/
│   ├── Arduinoboy.ino
│   ├── Led_Functions.ino
│   ├── Memory_Functions.ino
│   ├── Mode.ino
│   ├── Mode_LSDJ_Keyboard.ino
│   ├── Mode_LSDJ_Map.ino
│   ├── Mode_LSDJ_MasterSync.ino
│   ├── Mode_LSDJ_Midiout.ino
│   ├── Mode_LSDJ_SlaveSync.ino
│   ├── Mode_MidiGb.ino
│   ├── Mode_Nanoloop.ino
│   ├── Mode_Programmer.ino
│   └── UsbMidi.ino
├── Changelog.md
├── Editor/
│   └── ArduinoBoyEditor-Midi.maxpat
├── LICENSE
├── README.md
└── platformio.ini

================================================
FILE CONTENTS
================================================

================================================
FILE: Arduinoboy/Arduinoboy.ino
================================================
/***************************************************************************
 ***************************************************************************
 *                         __      _             __                        *
 *         ____ __________/ /_  __(_)___  ____  / /_  ____  __  __         *
 *        / __ `/ ___/ __  / / / / / __ \/ __ \/ __ \/ __ \/ / / /         *
 *       / /_/ / /  / /_/ / /_/ / / / / / /_/ / /_/ / /_/ / /_/ /          *
 *       \__,_/_/   \__,_/\__,_/_/_/ /_/\____/_.___/\____/\__, /           *
 *                                                       /____/            *
 *                                                                         *
 ***************************************************************************
 ***************************************************************************
 *                                                                         *
 * Version: 1.3.4                                                          *
 * Date:    May 19 2020                                                    *
 * Name:    Timothy Lamb                                                   *
 * Email:   trash80@gmail.com                                              *
 *                                                                         *
 ***************************************************************************
 ***************************************************************************
 *                                                                         *
 * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   *
 *                                                                         *
 *  https://github.com/trash80/Arduinoboy                                  *
 *                                                                         *
 *   Arduino pin settings:  (Layout is final)                              *
 *     - 6 LEDS on pins 8 to 13                                            *
 *     - Push button on pin 3 (for selecting mode)                         *
 *     - MIDI Opto-isolator power on pin 4                                 *
 *     - Gameboy Clock line on analog in pin 0                             *
 *     - Gameboy Serial Data input on analog in pin 1                      *
 *     - Serial Data from gameboy on analog in pin 2                       *
 *                                                                         *
 *   Teensy pin settings:                                                  *
 *     - 6 LEDS on pins 23,22,21,20,4,13                                   *
 *     - Push button on pin 2 (for selecting mode)                         *
 *     - MIDI Opto-isolator power connected to +3v                         *
 *     - Gameboy Clock line on pin 16                                      *
 *     - Gameboy Serial Data input on analog in pin 17                     *
 *     - Serial Data from gameboy on analog in pin 18                      *
 *                                                                         *
 *   Teensy USB MIDI is supported                                          *
 *   Teensy LC should work but untested                                    *
 *                                                                         *
 * Program Information:                                                    *
 *    LSDJ Slave Mode Midi Note Effects:                                   *
 *      48 - C-2 Sends a Sequencer Start Command                           *
 *      49 - C#2 Sends a Sequencer Stop Command                            *
 *      50 - D-2 Toggles Normal Tempo                                      *
 *      51 - D#2 Toggles 1/2 Tempo                                         *
 *      52 - E-2 Toggles 1/4 Tempo                                         *
 *      53 - F-2 Toggles 1/8 Tempo                                         *
 *                                                                         *
 *    LSDJ Keyboard Mode:                                                  *
 *      48 - C-2 Mute Pu1 Off/On                                           *
 *      49 - C#2 Mute Pu2 Off/On                                           *
 *      50 - D-2 Mute Wav Off/On                                           *
 *      51 - D#2 Mute Noi Off/On                                           *
 *      52 - E-2 Livemode Cue Sequence                                     *
 *      53 - F-2 Livemode Cursor Up                                        *
 *      54 - F#2 Livemode Cursor Down                                      *
 *      55 - G-2 Livemode Cursor Left                                      *
 *      56 - G#2 Livemode Cursor Right                                     *
 *      57 - A-2 Table Up                                                  *
 *      58 - A#2 Table Down                                                *
 *      59 - B-2 Cue Table                                                 *
 *      60 - C-3 to C-8 Notes!                                             *
 *      Prgram Change to select from instrument table                      *
 *                                                                         *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#define MEM_MAX 65
#define NUMBER_OF_MODES 7    //Right now there are 7 modes, Might be more in the future

//!!! do not edit these, they are the position in EEPROM memory that contain the value of each stored setting
#define MEM_CHECK 0
#define MEM_VERSION_FIRST 1
#define MEM_VERSION_SECOND 2
#define MEM_MODE 5
#define MEM_FORCE_MODE 4

#define MEM_LSDJSLAVE_MIDI_CH 6

#define MEM_LSDJMASTER_MIDI_CH 7
#define MEM_KEYBD_CH 8

#define MEM_KEYBD_COMPAT_MODE 9
#define MEM_KEYBD_CH_TO_INST 10

#define MEM_MIDIOUT_NOTE_CH 11
#define MEM_MIDIOUT_CC_CH 15
#define MEM_MIDIOUT_CC_MODE 19
#define MEM_MIDIOUT_CC_SCALING 23
#define MEM_MIDIOUT_CC_NUMBERS 27

#define MEM_MGB_CH 55
#define MEM_LIVEMAP_CH 60

#define MEM_MIDIOUT_BIT_DELAY 61
#define MEM_MIDIOUT_BYTE_DELAY 63

/***************************************************************************
* User Settings
***************************************************************************/

boolean usbMode                  = false; //to use usb for serial communication as oppose to MIDI - sets baud rate to 38400

byte defaultMemoryMap[MEM_MAX] = {
  0x7F,0x01,0x03,0x7F, //memory init check
  0x00, //force mode (forces lsdj to be sl)
  0x00, //mode

  15, //sync effects midi channel (0-15 = 1-16)
  15, //masterNotePositionMidiChannel - LSDJ in master mode will send its song position on the start button via midi note. (0-15 = 1-16)

  15, //keyboardInstrumentMidiChannel - midi channel for keyboard instruments in lsdj. (0-15 = 1-16)
  1, //Keyboard Compatability Mode
  1, //Set to true if you want to have midi channel set the instrument number / doesnt do anything anymore

  0,1,2,3, //midiOutNoteMessageChannels - midi channels for lsdj midi out note messages Default: channels 1,2,3,4
  0,1,2,3, //midiOutCCMessageChannels - midi channels for lsdj midi out CC messages Default: channels 1,2,3,4
  1,1,1,1, //midiOutCCMode - CC Mode, 0=use 1 midi CC, with the range of 00-6F, 1=uses 7 midi CCs with the
                       //range of 0-F (the command's first digit would be the CC#), either way the value is scaled to 0-127 on output
  1,1,1,1, //midiOutCCScaling - CC Scaling- Setting to 1 scales the CC value range to 0-127 as oppose to lsdj's incomming 00-6F (0-112) or 0-F (0-15)
  1,2,3,7,10,11,12, //pu1: midiOutCCMessageNumbers - CC numbers for lsdj midi out, if CCMode is 1, all 7 ccs are used per channel at the cost of a limited resolution of 0-F
  1,2,3,7,10,11,12, //pu2
  1,2,3,7,10,11,12, //wav
  1,2,3,7,10,11,12, //noi

  0, 1, 2, 3, 4, //mGB midi channels (0-15 = 1-16)
  0, //sync map midi channel start (0-15 = 1-16) (for song rows 0x80 to 0xFF it's this channel plus 1)
  80,1,  //midiout bit check delay & bit check delay multiplier
  0,0//midiout byte received delay & byte received delay multiplier
};
byte memory[MEM_MAX];

/***************************************************************************
* Lets Assign our Arduino Pins .....
***************************************************************************/


/***************************************************************************
* Teensy 3.2, Teensy LC
*
* Notes on Teensy: Pins are not the same as in the schematic, the mapping is below.
* Feel free to change, all related config in is this block.
* Be sure to compile
***************************************************************************/
#if defined (__MK20DX256__) || defined (__MK20DX128__) || defined (__MKL26Z64__)
#define USE_TEENSY 1
#define USE_USB 1
#include <MIDI.h>

#if defined (__MKL26Z64__)
#define GB_SET(bit_cl,bit_out,bit_in) GPIOB_PDOR = ((bit_in<<3) | (bit_out<<1) | bit_cl)
#else
#define GB_SET(bit_cl,bit_out,bit_in) GPIOB_PDOR = (GPIOB_PDIR & 0xfffffff4) | ((bit_in<<3) | (bit_out<<1) | bit_cl)
#endif

int pinGBClock     = 16;    // Analog In 0 - clock out to gameboy
int pinGBSerialOut = 17;    // Analog In 1 - serial data to gameboy
int pinGBSerialIn  = 18;    // Analog In 2 - serial data from gameboy
int pinMidiInputPower = 0; // Not used!
int pinStatusLed = 13; // Status LED
int pinLeds[] = {23,22,21,20,4,13}; // LED Pins
int pinButtonMode = 2; //toggle button for selecting the mode

HardwareSerial *serial = &Serial1;

/***************************************************************************
* Arduino Leonardo/Yún/Micro (ATmega32U4)
***************************************************************************/
#elif defined (__AVR_ATmega32U4__)
#define USE_LEONARDO
#include <MIDIUSB.h>

#define GB_SET(bit_cl, bit_out, bit_in) PORTF = (PINF & B00011111) | ((bit_cl<<7) | ((bit_out)<<6) | ((bit_in)<<5))
// ^ The reason for not using digitalWrite is to allign clock and data pins for the GB shift reg.
// Pin distribution comes from official Arduino Leonardo documentation

int pinGBClock     = A0;    // Analog In 0 - clock out to gameboy
int pinGBSerialOut = A1;    // Analog In 1 - serial data to gameboy
int pinGBSerialIn  = A2;    // Analog In 2 - serial data from gameboy
int pinMidiInputPower = 4; // power pin for midi input opto-isolator
int pinStatusLed = 13; // Status LED
int pinLeds[] = {12,11,10,9,8,13}; // LED Pins
int pinButtonMode = 3; //toggle button for selecting the mode

HardwareSerial *serial = &Serial1;


/***************************************************************************
* Arduino Due (ATmSAM3X8E)
***************************************************************************/
#elif defined (__SAM3X8E__)
#define USE_DUE

#define USE_LEONARDO
#include <MIDIUSB.h>
#include <digitalWriteFast.h>


#define GB_SET(bit_cl, bit_out, bit_in) digitalWriteFast(A0, bit_cl); digitalWriteFast(A1, bit_out); digitalWriteFast(A2, bit_in);
// ^ The reason for not using digitalWrite is to allign clock and data pins for the GB shift reg.

int pinGBClock     = A0;    // Analog In 0 - clock out to gameboy
int pinGBSerialOut = A1;    // Analog In 1 - serial data to gameboy
int pinGBSerialIn  = A2;    // Analog In 2 - serial data from gameboy
int pinMidiInputPower = 4; // power pin for midi input opto-isolator
int pinStatusLed = 13; // Status LED
int pinLeds[] = {12,11,10,9,8,13}; // LED Pins
int pinButtonMode = 3; //toggle button for selecting the mode

HardwareSerial *serial = &Serial;


/***************************************************************************
* Arduino UNO/Ethernet/Nano (ATmega328), Arduino UNO Wifi (ATmega4809) or Mega 2560 (ATmega2560/ATmega1280) (assumed)
***************************************************************************/
#else

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define GB_SET(bit_cl,bit_out,bit_in) PORTF = (PINF & B11111000) | ((bit_in<<2) | ((bit_out)<<1) | bit_cl)
#elif defined(__AVR_ATmega4809__)
#define GB_SET(bit_cl,bit_out,bit_in) PORTD = (PIND & B11111000) | ((bit_in<<2) | ((bit_out)<<1) | bit_cl)
#else
#define GB_SET(bit_cl,bit_out,bit_in) PORTC = (PINC & B11111000) | ((bit_in<<2) | ((bit_out)<<1) | bit_cl)
#endif
// ^ The reason for not using digitalWrite is to allign clock and data pins for the GB shift reg.

int pinGBClock     = A0;    // Analog In 0 - clock out to gameboy
int pinGBSerialOut = A1;    // Analog In 1 - serial data to gameboy
int pinGBSerialIn  = A2;    // Analog In 2 - serial data from gameboy
int pinMidiInputPower = 4; // power pin for midi input opto-isolator
int pinStatusLed = 13; // Status LED
int pinLeds[] = {12,11,10,9,8,13}; // LED Pins
int pinButtonMode = 3; //toggle button for selecting the mode

HardwareSerial *serial = &Serial;

#endif

/***************************************************************************
* Memory
***************************************************************************/
#ifndef USE_DUE
    #include <EEPROM.h>
    boolean alwaysUseDefaultSettings = false; //set to true to always use the settings below, else they are pulled from memory for the software editor
#else
    boolean alwaysUseDefaultSettings = true; //set to true to always use the default settings, in Due board is necessary as it doesn't have EEPROM
#endif

int eepromMemoryByte = 0; //Location of where to store settings from mem

/***************************************************************************
* Sysex Settings & vars
***************************************************************************/

boolean sysexReceiveMode = 0;
boolean sysexProgrammingMode = 0;
boolean sysexProgrammingWaiting = 0;
boolean sysexProgrammingConnected = 0;

unsigned long sysexProgrammerWaitTime = 2000; //2 seconds
unsigned long sysexProgrammerCallTime = 1000; //1 second
unsigned long sysexProgrammerLastResponse = 0;
unsigned long sysexProgrammerLastSent = 0;

byte sysexManufacturerId = 0x69; //har har harrrrr :)
int sysexPosition;
byte sysexData[128];
byte longestSysexMessage = 128;

int midioutBitDelay = 0;
int midioutByteDelay = 0;

/***************************************************************************
* Switches and states
***************************************************************************/
boolean sequencerStarted = false;        //Sequencer has Started
boolean midiSyncEffectsTime = false;
boolean midiNoteOnMode   =false;
boolean midiNoteOffMode  =false;
boolean midiProgramChange=false;
boolean midiAddressMode  =false;
boolean midiValueMode    =false;

int midiOutLastNote[4] = {-1,-1,-1,-1};

boolean statusLedIsOn    =false;
boolean statusLedBlink   =false;

boolean nanoState        =false;
boolean nanoSkipSync     =false;

int buttonDepressed;
int buttonState;
unsigned long int buttonProgrammerWaitTime = 2000; //2 whole seconds
unsigned long int buttonTime;


boolean blinkSwitch[6];
unsigned long int blinkSwitchTime[6];
uint8_t switchLight = 0;

uint16_t blinkMaxCount = 1000;

unsigned long midioutNoteTimer[4];
byte midioutNoteHold[4][4];
byte midioutNoteHoldCounter[4];
int midioutNoteTimerThreshold = 10;

/***************************************************************************
* Counter vars
***************************************************************************/
int countLSDJTicks = 0;            //for loop int (we need to cycle 8 pulses)
int countSyncTime  = 0;
int countSyncLightTime=0;
int countSyncSteps = 0;
int countSyncPulse = 0;
int countGbClockTicks =0;
int countClockPause =0;
int countIncommingMidiByte =0;
int countStatusLedOn =0;
unsigned int waitClock =0;


int miscLastLed;
unsigned long int miscLedTime;
unsigned long int miscLedMaxTime;

/***************************************************************************
* Inbound Data Placeholders
***************************************************************************/
byte incomingMidiByte;  //incomming midi message
byte readgbClockLine;
byte readGbSerialIn;
byte bit;
byte midiData[] = {0, 0, 0};
byte lastMidiData[] = {0, 0, 0};

int incomingMidiNote = 0;
int incomingMidiVel = 0;
byte readToggleMode;
byte serialWriteBuffer[256];
byte midiDefaultStartOffset;
int  writePosition=0;
int  readPosition=0;
int lastMode=0; //Stores the last selected mode for leds.

byte midiSyncByte;
byte midiSyncByteLast;

byte midiStatusType;
byte midiStatusChannel;

/***************************************************************************
* LSDJ Keyboard mode settings
***************************************************************************/
byte keyboardNotes[] = {0x1A,0x1B,0x22,0x23,0x21,0x2A,0x34,0x32,0x33,0x31,0x3B,0x3A,
                         0x15,0x1E,0x1D,0x26,0x24,0x2D,0x2E,0x2C,0x36,0x35,0x3D,0x3C};
byte keyboardOctDn = 0x05;
byte keyboardOctUp = 0x06;

byte keyboardInsDn = 0x04;
byte keyboardInsUp = 0x0C;

byte keyboardTblDn = 0x03;
byte keyboardTblUp = 0x0B;

byte keyboardTblCue= 0x29;

byte keyboardMut1 = 0x01;
byte keyboardMut2 = 0x09;
byte keyboardMut3 = 0x78;
byte keyboardMut4 = 0x07;

byte keyboardCurL = 0x6B;
byte keyboardCurR = 0x74;
byte keyboardCurU = 0x75;
byte keyboardCurD = 0x72;
byte keyboardPgUp = 0x7D;
byte keyboardPgDn = 0x7A;
byte keyboardEntr = 0x5A;

int keyboardCurrentOct = 0;
int keyboardCurrentIns = 0;
int keyboardCurrentTbl = 0;

int keyboardLastOct = 0;
int keyboardLastIns = 0;
int keyboardLastTbl = 0;

int keyboardDiff = 0;
int keyboardCount = 0;
byte keyboardStartOctave = 0x24;
byte keyboardNoteStart = 0;
byte keyboardNoteOffset = 0;
byte keyboardCommands[12];

/***************************************************************************
* LSDJ Midi Map mode vars
***************************************************************************/
int  mapCurrentRow = -1;
int  mapQueueMessage = -1;
unsigned long mapQueueTime;
// mapQueueWait is used for delaying a sync byte
// if it is called right before a note on message on sequencer start
// (Note value is also a clock tick)
uint8_t mapQueueWaitSerial = 2; //2ms
uint8_t mapQueueWaitUsb = 5; //5ms - Needs to be longer because message packet is processed all at once

/***************************************************************************
* mGB Settings
***************************************************************************/
#define GB_MIDI_DELAY 500 //Microseconds to delay the sending of a byte to gb

void setup() {
/*
  Init Memory
*/
  initMemory(0);
/*
  Init Pins
*/
  for(int led=0;led<=5;led++) pinMode(pinLeds[led],OUTPUT);
  pinMode(pinStatusLed,OUTPUT);
  pinMode(pinButtonMode,INPUT);

  pinMode(pinGBClock,OUTPUT);
  pinMode(pinGBSerialIn,INPUT);
  pinMode(pinGBSerialOut,OUTPUT);

/*
  Set MIDI Serial Rate
*/

#ifdef USE_USB
  serial->begin(31250); //31250
#else
  if(usbMode == true) {
    serial->begin(38400);
  } else {
    pinMode(pinMidiInputPower,OUTPUT);
    digitalWrite(pinMidiInputPower,HIGH); // turn on the optoisolator
    #ifdef USE_LEONARDO
      Serial1.begin(31250); //31250
    #else
      Serial.begin(31250); //31250
    #endif
  }
#endif

/*
  Set Pin States
*/
  digitalWrite(pinGBClock,HIGH);    // gameboy wants a HIGH line
  digitalWrite(pinGBSerialOut,LOW);    // no data to send
/*
  Misc Startup
*/
  keyboardNoteStart = keyboardStartOctave + 12; // Set the octave where the actual notes start (the octave below is for the mutes, cursor, etc)
/*
  Assign the keyboard mode command array for the first octave
*/
  keyboardCommands[0] = keyboardMut1;
  keyboardCommands[1] = keyboardMut2;
  keyboardCommands[2] = keyboardMut3;
  keyboardCommands[3] = keyboardMut4;
  keyboardCommands[4] = keyboardCurL;
  keyboardCommands[5] = keyboardCurR;
  keyboardCommands[6] = keyboardCurU;
  keyboardCommands[7] = keyboardCurD;
  keyboardCommands[8] = keyboardEntr;
  keyboardCommands[9] = keyboardTblDn;
  keyboardCommands[10] = keyboardTblUp;
  keyboardCommands[11] = keyboardTblCue;
/*
  Load Settings from EEPROM
*/
  #ifndef USE_DUE
  if(!memory[MEM_FORCE_MODE]) memory[MEM_MODE] = EEPROM.read(MEM_MODE);
  #endif
  lastMode = memory[MEM_MODE];

/*
  usbMidi sysex support
*/
  usbMidiInit();

  startupSequence();

  showSelectedMode(); //Light up the LED that shows which mode we are in.
}

/*
  Main Loop, which we don't use to be able to isolate each mode into its own setup and loop functions
*/
void loop () {
  setMode();
  switchMode();
}


================================================
FILE: Arduinoboy/Led_Functions.ino
================================================

 /*
   showSelectedMode1 turns off the last mode led, turns on the new mode led
   and delays for a period of time to reduce jitter behavior from the mode
   changing too fast.
 */
void showSelectedMode()
{
  digitalWrite(pinStatusLed,LOW);

  for(int m=0;m<3;m++) {
    switch(memory[MEM_MODE]) {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
        digitalWrite(pinLeds[memory[MEM_MODE]],HIGH);
        break;
      case 5:
        digitalWrite(pinStatusLed,HIGH);
        digitalWrite(pinLeds[0],HIGH);
        digitalWrite(pinLeds[1],HIGH);
        break;
      case 6:
        digitalWrite(pinLeds[0],HIGH);
        digitalWrite(pinLeds[1],HIGH);
        digitalWrite(pinLeds[2],HIGH);
        digitalWrite(pinLeds[3],HIGH);
        digitalWrite(pinLeds[4],HIGH);
        digitalWrite(pinLeds[5],HIGH);
        break;

    }
  delay(100);
  digitalWrite(pinLeds[0],LOW);
  digitalWrite(pinLeds[1],LOW);
  digitalWrite(pinLeds[2],LOW);
  digitalWrite(pinLeds[3],LOW);
  digitalWrite(pinLeds[4],LOW);
  digitalWrite(pinLeds[5],LOW);
  delay(100);
  }
  lastMode = memory[MEM_MODE];
  delay(300);
}

void updateVisualSync()
{
    if(!countSyncTime) {
      if(!blinkSwitch[5]) digitalWrite(pinStatusLed,HIGH);
      digitalWrite(pinLeds[0],LOW);
      digitalWrite(pinLeds[1],LOW);
      digitalWrite(pinLeds[2],LOW);
      digitalWrite(pinLeds[3],LOW);
      digitalWrite(pinLeds[switchLight],HIGH);
      blinkSwitch[5]=1;
      blinkSwitchTime[5]=0;
      countSyncLightTime = 0;
      switchLight++;
      if(switchLight==4) switchLight=0;
    }
    countSyncTime++;
    if(countSyncTime == 24) countSyncTime=0;
}



void updateBlinkLights()
{
  updateBlinkLight(0);
  updateBlinkLight(1);
  updateBlinkLight(2);
  updateBlinkLight(3);
  updateBlinkLight(4);
  updateBlinkLight(5);
}

void updateBlinkLight(uint8_t light)
{
  if(blinkSwitch[light]) {
    blinkSwitchTime[light]++;
    if(blinkSwitchTime[light] == blinkMaxCount) {
      blinkSwitch[light]=0;
      blinkSwitchTime[light]=0;
      digitalWrite(pinLeds[light],LOW);
    }
  }
}

void updateStatusLight()
{
  if(blinkSwitch[5]) {
    blinkSwitchTime[5]++;
    if(blinkSwitchTime[5] == blinkMaxCount) {
      blinkSwitch[5]=0;
      blinkSwitchTime[5]=0;
      digitalWrite(pinStatusLed,LOW);
    }
  }
}

void blinkLight(byte midiMessage, byte midiValue)
{
  if(midiValue) {
  switch(midiMessage) {
    case 0x90:
      if(!blinkSwitch[0]) digitalWrite(pinLeds[0],HIGH);
      blinkSwitch[0]=1;
      blinkSwitchTime[0]=0;
      break;
    case 0x95:
      if(!blinkSwitch[0]) digitalWrite(pinLeds[0],HIGH);
      blinkSwitch[0]=1;
      blinkSwitchTime[0]=0;
      break;
    case 0x9A:
      if(!blinkSwitch[0]) digitalWrite(pinLeds[0],HIGH);
      blinkSwitch[0]=1;
      blinkSwitchTime[0]=0;
      break;
    case 0x91:
      if(!blinkSwitch[1]) digitalWrite(pinLeds[1],HIGH);
      blinkSwitch[1]=1;
      blinkSwitchTime[1]=0;
      break;
    case 0x96:
      if(!blinkSwitch[1]) digitalWrite(pinLeds[1],HIGH);
      blinkSwitch[1]=1;
      blinkSwitchTime[1]=0;
      break;
    case 0x9B:
      if(!blinkSwitch[1]) digitalWrite(pinLeds[1],HIGH);
      blinkSwitch[1]=1;
      blinkSwitchTime[1]=0;
      break;
    case 0x92:
      if(!blinkSwitch[2]) digitalWrite(pinLeds[2],HIGH);
      blinkSwitch[2]=1;
      blinkSwitchTime[2]=0;
      break;
    case 0x97:
      if(!blinkSwitch[2]) digitalWrite(pinLeds[2],HIGH);
      blinkSwitch[2]=1;
      blinkSwitchTime[2]=0;
      break;
    case 0x9C:
      if(!blinkSwitch[2]) digitalWrite(pinLeds[2],HIGH);
      blinkSwitch[2]=1;
      blinkSwitchTime[2]=0;
      break;
    case 0x93:
      if(!blinkSwitch[3]) digitalWrite(pinLeds[3],HIGH);
      blinkSwitch[3]=1;
      blinkSwitchTime[3]=0;
      break;
    case 0x98:
      if(!blinkSwitch[3]) digitalWrite(pinLeds[3],HIGH);
      blinkSwitch[3]=1;
      blinkSwitchTime[3]=0;
      break;
    case 0x9D:
      if(!blinkSwitch[3]) digitalWrite(pinLeds[3],HIGH);
      blinkSwitch[3]=1;
      blinkSwitchTime[3]=0;
      break;
    case 0x94:
      if(!blinkSwitch[0])  digitalWrite(pinLeds[0],HIGH);
      blinkSwitch[0]=1;
      blinkSwitchTime[0]=0;
      if(!blinkSwitch[1]) digitalWrite(pinLeds[1],HIGH);
      blinkSwitch[1]=1;
      blinkSwitchTime[1]=0;
      if(!blinkSwitch[2]) digitalWrite(pinLeds[2],HIGH);
      blinkSwitch[2]=1;
      blinkSwitchTime[2]=0;
      break;
    case 0x99:
      if(!blinkSwitch[0])  digitalWrite(pinLeds[0],HIGH);
      blinkSwitch[0]=1;
      blinkSwitchTime[0]=0;
      if(!blinkSwitch[1]) digitalWrite(pinLeds[1],HIGH);
      blinkSwitch[1]=1;
      blinkSwitchTime[1]=0;
      if(!blinkSwitch[2]) digitalWrite(pinLeds[2],HIGH);
      blinkSwitch[2]=1;
      blinkSwitchTime[2]=0;
      break;
    case 0x9E:
      if(!blinkSwitch[0])  digitalWrite(pinLeds[0],HIGH);
      blinkSwitch[0]=1;
      blinkSwitchTime[0]=0;
      if(!blinkSwitch[1]) digitalWrite(pinLeds[1],HIGH);
      blinkSwitch[1]=1;
      blinkSwitchTime[1]=0;
      if(!blinkSwitch[2]) digitalWrite(pinLeds[2],HIGH);
      blinkSwitch[2]=1;
      blinkSwitchTime[2]=0;
      break;
  }
  }
  switch(midiMessage) {
    case 0xE0:
    case 0xE1:
    case 0xE2:
    case 0xE3:
    case 0xE4:
    case 0xB0:
    case 0xB1:
    case 0xB2:
    case 0xB3:
    case 0xB4:
      if(!blinkSwitch[5]) digitalWrite(pinStatusLed,HIGH);
      blinkSwitch[5]=1;
      blinkSwitchTime[5]=0;
      break;
    default:
      break;
  }
}

void updateProgrammerLeds()
{
  if(miscLedTime == miscLedMaxTime) {
    if(sysexProgrammingConnected) {
      miscLedMaxTime = 400;
      blinkSelectedLight(miscLastLed);
      miscLastLed++;
      if(miscLastLed == 5) miscLastLed = 0;
    } else {
      blinkSelectedLight(5);
      miscLedMaxTime = 3000;
    }
    miscLedTime=0;
  }
  miscLedTime++;
  updateBlinkLights();
}
 /*
   updateStatusLed should be placed inside of the main loop cycle of a mode function. It counts to a
   certain number to delay the action of turning off the status led, so the blink is visible to the human eye. ;)>
   I guess this could be called the blinking routine.
 */
void updateStatusLed()
{
  if(statusLedIsOn) {                  //is the led on?
    countStatusLedOn++;                //then increment the counter by 1
    if(countStatusLedOn > 3000) {      //if the counter is pretty high
      countStatusLedOn = 0;            //then reset it to zero.
       digitalWrite(pinStatusLed,LOW); //and turn off the status led
       statusLedIsOn  = false;         //and set our "is it on?" to false, cause its off now. ;p

    } else if (statusLedBlink && countStatusLedOn == 1) {  //someone told me to blink, because i was already on
       digitalWrite(pinStatusLed,LOW);                     //so I'll turn off and turn back on later..

    } else if (statusLedBlink && countStatusLedOn > 1000) {//Now that I've waited long enough I'll finish my blink.
       statusLedBlink = false;                             //Turn off the issued blink
       digitalWrite(pinStatusLed,HIGH);                    //... and finally turn back on.
    }
  }
}

 /*
   statusLedOn is the function to call when we want the status led to blink for us.
   all it does is check if its been already asked to turn on, if it has it will set a flag
   to make it blink. Either way it will reset the blink timer and turn on the LED
 */
void statusLedOn()
{
  if(statusLedIsOn) {
    statusLedBlink = true;   //Make it blink even though its already on
  }
  statusLedIsOn  = true;     //This is the flag the updator function looks for to know if its ok to increment the timer and wait to turn off the led
  countStatusLedOn = 0;      //Reset the timer
  digitalWrite(pinStatusLed,HIGH); //Turn on the led
}

/* cute startup sequence */
void startupSequence()
{
  int ledFxA;
  int ledFxB;

  for(ledFxB=0;ledFxB<2;ledFxB++) {
  for(ledFxA=0;ledFxA<6;ledFxA++) {
    digitalWrite(pinLeds[ledFxA], HIGH);
    delay(25);
    digitalWrite(pinLeds[ledFxA], LOW);
  }
  for(ledFxA=4;ledFxA>=0;ledFxA--) {
    digitalWrite(pinLeds[ledFxA], HIGH);
    delay(25);
    digitalWrite(pinLeds[ledFxA], LOW);
  }
  }
  delay(50);

  for(ledFxA=0;ledFxA<6;ledFxA++) digitalWrite(pinLeds[ledFxA], HIGH);   // sets the LED on
  delay(100);
  for(ledFxA=0;ledFxA<6;ledFxA++) digitalWrite(pinLeds[ledFxA], LOW);      // sets the digital pin as output
  delay(100);
  for(ledFxA=0;ledFxA<6;ledFxA++) digitalWrite(pinLeds[ledFxA], HIGH);   // sets the LED on
  delay(100);
  for(ledFxA=0;ledFxA<6;ledFxA++) digitalWrite(pinLeds[ledFxA], LOW);      // sets the digital pin as output
  delay(500);

}


================================================
FILE: Arduinoboy/Memory_Functions.ino
================================================

boolean checkMemory()
{
  byte chk;
  #ifndef USE_DUE
  for(int m=0;m<4;m++){
    chk =  EEPROM.read(MEM_CHECK+m);
    if(chk != defaultMemoryMap[MEM_CHECK+m]) {
      return false;
    }
  }
  #endif
  return true;
}

void initMemory(boolean reinit)
{
  if(!alwaysUseDefaultSettings) {
    #ifndef USE_DUE
    if(reinit || !checkMemory()) {
      for(int m=(MEM_MAX);m>=0;m--){
        EEPROM.write(m,defaultMemoryMap[m]);
      }
    }
    #endif
    loadMemory();
  } else {
    for(int m=0;m<=MEM_MAX;m++){
      memory[m] = defaultMemoryMap[m];
    }
  }
  changeTasks();
}


void loadMemory()
{
  #ifndef USE_DUE
  for(int m=(MEM_MAX);m>=0;m--){
     memory[m] = EEPROM.read(m);
  }
  #endif
  changeTasks();
}

void printMemory()
{
  for(int m=0;m<=MEM_MAX;m++){
    serial->println(memory[m],HEX);
  }
}

void saveMemory()
{
  #ifndef USE_DUE
  for(int m=(MEM_MAX-1);m>=0;m--){
    EEPROM.write(m,memory[m]);
  }
  changeTasks();
  #endif
}

void changeTasks()
{
  midioutByteDelay = memory[MEM_MIDIOUT_BYTE_DELAY] * memory[MEM_MIDIOUT_BYTE_DELAY+1];
  midioutBitDelay = memory[MEM_MIDIOUT_BIT_DELAY] * memory[MEM_MIDIOUT_BIT_DELAY+1];
}


================================================
FILE: Arduinoboy/Mode.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
 
/* ***************************************************************************/
/* "Mode" Functions. Deals with changing the setup of arduino.              */
/* ***************************************************************************/

 /*
   setMode will check if the push button is depressed, If it is it will 
   increment the mode number and make sure its in the 
   range 0 to 4 by mod (%). It will then write the mode to memory,
   set the leds to display the mode, and switch the code over to the
   right function.
 */
 

void setMode()
{
  buttonDepressed = digitalRead(pinButtonMode);
  if(!memory[MEM_FORCE_MODE] && buttonDepressed) { //if the button is pressed
    memory[MEM_MODE]++;                           //increment the mode number
    if(memory[MEM_MODE] > (NUMBER_OF_MODES - 1)) memory[MEM_MODE]=0;  //if the mode is greater then 4 it will wrap back to 0
    #ifndef USE_DUE
    if(!memory[MEM_FORCE_MODE]) EEPROM.write(MEM_MODE, memory[MEM_MODE]); //write mode to eeprom if we arnt forcing a mode in the config
    #endif
    showSelectedMode();            //set the LEDS
    switchMode();
  }
}


 /*
   switchMode is only called from setMode. its responsible for
   linking the mode number to its corrisponding function, 
   and then calling that function. function. function.
 */
void switchMode()
{
  switch(memory[MEM_MODE])
  {
    case 0:
      modeLSDJSlaveSyncSetup();
      break;
    case 1:
      modeLSDJMasterSyncSetup();
      break;
    case 2:
      modeLSDJKeyboardSetup();
      break;
    case 3:
      modeNanoloopSetup();
      break;
    case 4:
      modeMidiGbSetup();
      break;
    case 5:
      modeLSDJMapSetup();
      break;
    case 6:
      modeLSDJMidioutSetup();
      break;
  }
}


/* ***************************************************************************/
/* General Global Functions Used in more then one of the modes               */
/* ***************************************************************************/

 /*
   sequencerStart is called when either LSDJ has started to play in master mode, 
   or when a MIDI Start or continue command is received in lsdj slave mode.
   Basically it just resets some counters we use and sets a "start" flag.
 */
 
void sequencerStart()
{
  sequencerStarted = true; //Sequencer has started?
  countSyncPulse = 0;      //Used for status LED, counts 24 ticks (quarter notes)
  countSyncTime = 0;       //Used to count a custom amount of clock ticks (2/4/8) for sync effects
  countSyncLightTime=0;
  switchLight=0;
}

 /*
   sequencerStop is called when either LSDJ has stopped sending sync commands for
   some time in LSDJ Master mode, or when a MIDI Stop command is received in
   lsdj slave mode.
   Basically it just resets some counters we use and sets the "start" flag to false.
 */
void sequencerStop()
{
  midiSyncEffectsTime = false;//Turn off MIDI sync effects in LSDJ slave mode
  sequencerStarted = false;   //Sequencer has started?
  countSyncPulse = 0;         //Used for status LED, counts 24 ticks (quarter notes)
  countSyncTime = 0;          //Used to count a custom amount of clock ticks (2/4/8) for sync effects
  countSyncLightTime=0;
  switchLight=0;
  digitalWrite(pinLeds[0],LOW);
  digitalWrite(pinLeds[1],LOW);
  digitalWrite(pinLeds[2],LOW);
  digitalWrite(pinLeds[3],LOW);
  digitalWrite(pinLeds[memory[MEM_MODE]],HIGH);
}


================================================
FILE: Arduinoboy/Mode_LSDJ_Keyboard.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

void modeLSDJKeyboardSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,OUTPUT);
  digitalWrite(pinGBClock,HIGH);
 #ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(NULL);
 #endif
  blinkMaxCount=1000;

  /* The stuff below makes sure the code is in the same state as LSDJ on reset / restart, mode switched, etc. */

  for(int rst=0;rst<5;rst++) sendKeyboardByteToGameboy(keyboardOctDn);   //Return lsdj to the first octave
  for(int rst=0;rst<41;rst++) sendKeyboardByteToGameboy(keyboardInsDn);  //Return lsdj to the first instrument

  keyboardCurrentOct = 0;  //Set our current octave to 0.
  keyboardLastOct    = 0;  //Set our last octave to 0.
  keyboardCurrentIns = 0;  //Set out current instrument to 0.
  keyboardLastIns    = 0;  //Set out last used instrument to 0.


  modeLSDJKeyboard();      //.... And start the fun
}


void modeLSDJKeyboard()
{
  while(1){                              //Loop foreverrrr
  modeLSDJKeyboardMidiReceive();
  if (serial->available()) {          //If MIDI is sending
    incomingMidiByte = serial->read();    //Get the byte sent from MIDI
    if(!checkForProgrammerSysex(incomingMidiByte) && !usbMode) serial->write(incomingMidiByte);//Echo the Byte to MIDI Output


    /***************************************************************************
     * Midi to LSDJ Keyboard Handling                                          *
     ***************************************************************************/
    //If the byte is a Status Message
    if(incomingMidiByte & 0x80) {
      /* Status message Information (# = midi channel 0 to F [1-16] )
          0x8# = Note Off
          0x9# = Note On
          0xA# = AfterTouch (ie, key pressure)
          0xB# = Control Change
          0xC# = Program (patch) change
          0xD# = Channel Pressure
          0xE# = Pitch Wheel
          0xF0 - 0xF7 = System Common Messages
          0xF8 - 0xFF = System Realtime Messages
      */

      //Weee hello world bitwise and. ... make the second hex digit zero so we can have a simple case statement
      // - the second digit is usually the midi channel 0 to F (1-16) unless its a 0xF0 message...
      switch (incomingMidiByte & 0xF0) {
        case 0x90:
          //Note-On Status Message (Note: we have to treat this carefully because note status isnt sent on every note-on, damn it)
          //There are 3 bytes total we need: Channel, Note, and velocity, these wil be assigned to a array until we have the velocity,
          //at that point we can then call our note out function to LSDJ
          midiNoteOnMode = true;                    //Set our stupid "Note on mode" on
          midiData[0] = incomingMidiByte;   //Assign the byte to the first position of a data array. (this is the midi channel)
          midiData[1] = false;              //Force the second position to false (this will hold the note number)
          break;
        case 0xC0:
          //Program change message
          midiProgramChange = true;                   //Set our silly "Program Change mode" ... we need to get the next byte later
          midiNoteOnMode = false;                     //Turn Note-on mode off
          midiData[0] = incomingMidiByte - 48;//Set the number to a "note on" message so we can use the same "channel" variable as note on messages
          break;
        case 0xF0:
           //Do nothing, these dont interfear with our note-on mode
          break;
        default:
          //Turn Note-On mode off
          midiNoteOnMode = false;
          break;
      }
    } else if(midiNoteOnMode) {
      //It wasnt a status bit, so lets assume it was a note message if the last status message was note-on.
      if(!midiData[1]) {
         //If we dont have a note number, we assume this byte is the note number, get it...
         midiData[1] = incomingMidiByte;
      } else {
         //We have our note and channel, so call our note function...

         playLSDJNote(midiData[0], midiData[1], incomingMidiByte);
         midiData[1] = false; //Set the note to false, forcing to capture the next note
      }
    } else if (midiProgramChange) {
        changeLSDJInstrument(midiData[0], incomingMidiByte);
        midiProgramChange = false;
        midiData[0] = false;
    }
  }

  updateStatusLed();        // Update our status blinker
  setMode();                // Check if mode button was depressed
  }
}


 /*
  changeLSDJInstrument does what it does via magic (rtfm, realize the fucking magic)
 */
void changeLSDJInstrument(byte channel,byte message)
{
  keyboardCurrentIns = message; //set the current instrument number

  if(channel == (0x90+memory[MEM_KEYBD_CH]) && keyboardCurrentIns != keyboardLastIns) {
  //if its on our midi channel and the instrument isnt the same as our currrent
    if(!memory[MEM_KEYBD_COMPAT_MODE]) {
      sendKeyboardByteToGameboy(0x80 | message); // <- this is suppose to work but doesn't :/
    } else {
      //We will find out which is greater, the current instrument or the last instrument. then
      //cycle up or down to that instrument
      if(keyboardCurrentIns > keyboardLastIns) {
        keyboardDiff = keyboardCurrentIns - keyboardLastIns;
        for(keyboardCount=0;keyboardCount<keyboardDiff;keyboardCount++) {
          sendKeyboardByteToGameboy(keyboardInsUp);  //send the instrument up command to go up to the requested instrument
        }
      } else {
        keyboardDiff = keyboardLastIns - keyboardCurrentIns;
        for(keyboardCount=0;keyboardCount<keyboardDiff;keyboardCount++) {
          sendKeyboardByteToGameboy(keyboardInsDn);  //send the instrument down command to down to the requested instrument
        }
      }
    }
    keyboardLastIns = keyboardCurrentIns; //assign our instrument for future reference to this function
  }
}


 /*
  w00t...
 */
void playLSDJNote(byte channel,byte note, byte velocity)
{
  if(channel == (0x90+memory[MEM_KEYBD_CH])
     && velocity > 0x00) { //If midi channel = ours and the velocity is greater then 0
    if(note >= keyboardNoteStart) {
      keyboardNoteOffset = 0;
      note = note - keyboardNoteStart;  //subtract the octave offset to get a value ranging from 0 to 48 for comparison

      keyboardCurrentOct = note / 0x0C;  //get a octave value from 0 to 4 by deviding the current note by 12
      changeLSDJOctave();

      if(note >= 0x3C) keyboardNoteOffset = 0x0C; //if the note really high we need to use the second row of keyboard keys
      note = (note % 12) + keyboardNoteOffset;    //get a 0 to 11 range of notes and add the offset
      sendKeyboardByteToGameboy(keyboardNotes[note]);        // and finally send the note

    } else if (note >= keyboardStartOctave) { //If we are at the octave below notes
      keyboardDiff = note - keyboardStartOctave; //Get a value between 0 and 11
      if(keyboardDiff < 8 && keyboardDiff > 3) sendKeyboardByteToGameboy(0xE0); //if we are sending cursor values we have to send a 0xE0 byte for "extended" pc keyboard mode
      sendKeyboardByteToGameboy(keyboardCommands[note - keyboardStartOctave]); //send the byte corrisponding to the note number in the keyboard command array
    }
  }
}


 /*
  changeLSDJOctave compares the last octave with the current one and then sends a byte
  to shift the octave to match if need be. its pretty much the same as the changeLSDJInstrument function.
 */
void changeLSDJOctave()
{
  if(keyboardCurrentOct != keyboardLastOct) {
    if(!memory[MEM_KEYBD_COMPAT_MODE]) { // This new mode doesnt work yet. :/
      keyboardCurrentOct = 0xB3 + keyboardCurrentOct;
      sendKeyboardByteToGameboy(keyboardCurrentOct);
    } else {
      ///We will find out which is greater, the current octave or the last. then
      //cycle up or down to that octave
      if(keyboardCurrentOct > keyboardLastOct) {
        keyboardDiff = keyboardCurrentOct - keyboardLastOct;
        for(keyboardCount=0;keyboardCount<keyboardDiff;keyboardCount++)
        {
           sendKeyboardByteToGameboy(keyboardOctUp);
        }
      } else {
        keyboardDiff = keyboardLastOct - keyboardCurrentOct;
        for(keyboardCount=0;keyboardCount<keyboardDiff;keyboardCount++)
        {
          sendKeyboardByteToGameboy(keyboardOctDn);
        }
      }
    }
    keyboardLastOct = keyboardCurrentOct;
  }
}


/*
  sendKeyboardByteToGameboy
*/
void sendKeyboardByteToGameboy(byte send_byte)
{
  GB_SET(0,0,0);
  delayMicroseconds(50);  //Delays are added to simulate PC keyboard rate
  GB_SET(1,0,0);
  delayMicroseconds(50);
  for(countLSDJTicks=0;countLSDJTicks<8;countLSDJTicks++) {  //we are going to send 8 bits, so do a loop 8 times
    if(send_byte & 0x01) {          //if the first bit is equal to 1
      GB_SET(0,1,0);
      delayMicroseconds(50);
      GB_SET(1,1,0);
      delayMicroseconds(50);
    } else {
      GB_SET(0,0,0);
      delayMicroseconds(50);
      GB_SET(1,0,0);
      delayMicroseconds(50);
    }
    send_byte >>= 1;                //bitshift right once for the next bit we are going to send
  }

  GB_SET(0,0,0);
  delayMicroseconds(50);
  GB_SET(1,0,0);
  delayMicroseconds(50);
  GB_SET(0,1,0);
  delayMicroseconds(50);
  GB_SET(1,1,0);
  delayMicroseconds(4000);
}

void modeLSDJKeyboardMidiReceive()
{
#ifdef USE_TEENSY

    while(usbMIDI.read(memory[MEM_KEYBD_CH]+1)) {
        switch(usbMIDI.getType()) {
            case 0x80: // note off
                playLSDJNote(0x90+memory[MEM_KEYBD_CH], usbMIDI.getData1(), 0);
            break;
            case 0x90: // note on
                playLSDJNote(0x90+memory[MEM_KEYBD_CH], usbMIDI.getData1(), usbMIDI.getData2());
            break;
            case 0xC0: // PG
                changeLSDJInstrument(0xC0+memory[MEM_KEYBD_CH], usbMIDI.getData1());
            break;
            /*
            case 3: // CC
            break;
            case 5: // AT
            break;
            case 6: // PB
            break;
            */
        }
    }
#endif
#ifdef USE_LEONARDO

    midiEventPacket_t rx;
    do {
      rx = MidiUSB.read();
      switch (rx.header)
        {
        case 0x08: // note off
          playLSDJNote(0x90+memory[MEM_KEYBD_CH], rx.byte2, 0);
          statusLedOn();
          break;
        case 0x09: // note on
          playLSDJNote(0x90+memory[MEM_KEYBD_CH], rx.byte2, rx.byte3);
          statusLedOn();
          break;
        case 0x0C: // PG
          changeLSDJInstrument(0xC0+memory[MEM_KEYBD_CH], rx.byte2);
          statusLedOn();
          break;
      }
    } while (rx.header != 0);
#endif
}


================================================
FILE: Arduinoboy/Mode_LSDJ_Map.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

void modeLSDJMapSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,OUTPUT);
  digitalWrite(pinGBClock, HIGH);
 #ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(usbMidiLSDJMapRealtimeMessage);
 #endif
  blinkMaxCount=1000;
  modeLSDJMap();
}

void modeLSDJMap()
{
  while(1){  //Loop forever

  modeLSDJMapUsbMidiReceive();
  checkMapQueue();
  if (serial->available()) {                 //If MIDI Byte Availaibleleleiel
    incomingMidiByte = serial->read();           //Read it

    checkForProgrammerSysex(incomingMidiByte);

    if(incomingMidiByte & 0x80) {                //If we have received a MIDI Status Byte
      switch (incomingMidiByte) {
        case 0xF8:
          setMapByte(0xFF, false);
          usbMidiSendRTMessage(incomingMidiByte);
          break;
        case 0xFA:                                // Case: Transport Start Message
        case 0xFB:                                // and Case: Transport Continue Message
          sequencerStart();                       // Start the sequencer
          usbMidiSendRTMessage(incomingMidiByte);
          break;
        case 0xFC:                                // Case: Transport Stop Message
          sequencerStop();
          setMapByte(0xFE, false);
          usbMidiSendRTMessage(incomingMidiByte);
          break;
        default:
          midiData[0] = incomingMidiByte;
          midiNoteOnMode = true;

          if(midiData[0] == (0x90+memory[MEM_LIVEMAP_CH])
             || midiData[0] == (0x90+(memory[MEM_LIVEMAP_CH]+1))) resetMapCue();
        }
    } else if(midiNoteOnMode) {   //if we've received a message thats not a status and our note capture mode is true

      midiNoteOnMode = false;
      midiData[1] = incomingMidiByte;

      usbMidiSendTwoByteMessage(midiData[0],midiData[1]);
      if(midiData[0] == (0x90+memory[MEM_LIVEMAP_CH])
         || midiData[0] == (0x90+(memory[MEM_LIVEMAP_CH]+1))) resetMapCue();

    } else {
      midiNoteOnMode = true;
      if(midiData[0] == (0x90+memory[MEM_LIVEMAP_CH])
        || midiData[0] == (0x90+(memory[MEM_LIVEMAP_CH]+1))) {
          if(incomingMidiByte) {
              if(midiData[0] == (0x90+(memory[MEM_LIVEMAP_CH]+1))) {
                  setMapByte(128+midiData[1], false);
              } else {
                  setMapByte(midiData[1], false);
              }
          } else {
              setMapByte(0xFE, false);
          }
      } else if (midiData[0] == (0x80+memory[MEM_LIVEMAP_CH])
                 || midiData[0] == (0x80+(memory[MEM_LIVEMAP_CH]+1))) {
          setMapByte(0xFE, false);
      }
      usbMidiSendThreeByteMessage(midiData[0], midiData[1], incomingMidiByte);
      checkMapQueue();
    }
  } else {
    setMode();         //Check if the mode button was depressed
    updateStatusLight();
    checkMapQueue();
    updateBlinkLights();
  }
  }
}

void setMapByte(uint8_t b, boolean usb)
{
    uint8_t wait = mapQueueWaitSerial;
    if(usb) {
        wait = mapQueueWaitUsb;
    }

    switch(b) {
      case 0xFF:
        setMapQueueMessage(0xFF, wait);
        break;
      case 0xFE:
        if(!sequencerStarted) {
            sendByteToGameboy(0xFE);
        } else if (mapCurrentRow >= 0) {
            setMapQueueMessage(mapCurrentRow, wait);
        }
        break;
      default:
        mapCurrentRow = b;
        sendByteToGameboy(b);
        resetMapCue();
    }
}

void setMapQueueMessage(uint8_t m, uint8_t wait)
{
    if(mapQueueMessage == -1 || mapQueueMessage == 0xFF) {
        mapQueueTime=millis()+wait;
        mapQueueMessage=m;
    }
}

void resetMapCue()
{
    mapQueueMessage=-1;
}

void checkMapQueue()
{
  if(mapQueueMessage >= 0 && millis()>mapQueueTime) {
      if(mapQueueMessage == 0xFF) {
          sendByteToGameboy(mapQueueMessage);
      } else {
          if(mapQueueMessage == 0xFE || mapCurrentRow == mapQueueMessage) {
              // Only kill playback if the row is the last one that's been played.
              mapCurrentRow = -1;
              sendByteToGameboy(0xFE);
          }
      }
      mapQueueMessage=-1;
      updateVisualSync();
  }
}


void usbMidiLSDJMapRealtimeMessage(uint8_t message)
{
    switch(message) {
      case 0xF8:
        setMapByte(0xFF, true);
      break;
      case 0xFA:                                // Case: Transport Start Message
      case 0xFB:                                // and Case: Transport Continue Message
        resetMapCue();
        sequencerStart();                     // Start the sequencer
      break;
      case 0xFC:                                // Case: Transport Stop Message
        sequencerStop();                        // Stop the sequencer
        setMapByte(0xFE, true);
      break;
    }
}

void modeLSDJMapUsbMidiReceive()
{
#ifdef USE_TEENSY

    while(usbMIDI.read()) {
        uint8_t ch = usbMIDI.getChannel() - 1;
        if(ch != memory[MEM_LIVEMAP_CH] && ch != (memory[MEM_LIVEMAP_CH] + 1)){
            continue;
        }

        switch(usbMIDI.getType()) {
            case 0x80: // note off
                setMapByte(0xFE, true);
            break;
            case 0x90: // note on
                if(ch == (memory[MEM_LIVEMAP_CH] + 1)) {
                    setMapByte(128+usbMIDI.getData1(), true);
                } else {
                    setMapByte(usbMIDI.getData1(), true);
                }
            break;
            /*
            case 3: // CC
            break;
            case 4: // PG
            break;
            case 5: // AT
            break;
            case 6: // PB
            break;
            */
        }
    }
#endif
#ifdef USE_LEONARDO
    midiEventPacket_t rx;
    do
    {
      rx = MidiUSB.read();
      usbMidiLSDJMapRealtimeMessage(rx.byte1);
      uint8_t ch = rx.byte1 & 0x0F;
      if (ch != memory[MEM_LIVEMAP_CH] && ch != (memory[MEM_LIVEMAP_CH] + 1))
      {
        continue;
      }
      switch (rx.header)
      {
      case 0x08: // note off
        setMapByte(0xFE, true);
        break;
      case 0x09: // note on
        if (ch == (memory[MEM_LIVEMAP_CH] + 1))
        {
          setMapByte(128 + rx.byte2, true);
        }
        else
        {
          setMapByte(rx.byte2, true);
        }
        break;
      }
    } while (rx.header != 0);
#endif
}


================================================
FILE: Arduinoboy/Mode_LSDJ_MasterSync.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/


void modeLSDJMasterSyncSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,INPUT);

  #ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(NULL);
  #endif

  countSyncTime=0;
  blinkMaxCount=1000;
  modeLSDJMasterSync();
}

void modeLSDJMasterSync()
{
  while(1){

#ifdef USE_TEENSY
    while(usbMIDI.read()) ;
#endif

    if (serial->available()) {                  //If serial data was send to midi input
      incomingMidiByte = serial->read();            //Read it
      if(!checkForProgrammerSysex(incomingMidiByte) && !usbMode) serial->write(incomingMidiByte);        //Send it to the midi output
    }
    readgbClockLine = digitalRead(pinGBClock);    //Read gameboy's clock line
    if(readgbClockLine) {                         //If Gb's Clock is On
      while(readgbClockLine) {                    //Loop untill its off
        readgbClockLine = digitalRead(pinGBClock);//Read the clock again
        bit = digitalRead(pinGBSerialIn);         //Read the serial input for song position
        checkActions();
      }

      countClockPause= 0;                          //Reset our wait timer for detecting a sequencer stop

      readGbSerialIn = readGbSerialIn << 1;        //left shift the serial byte by one to append new bit from last loop
      readGbSerialIn = readGbSerialIn + bit;       //and then add the bit that was read

      sendMidiClockSlaveFromLSDJ();                //send the clock & start offset data to midi

    }
    setMode();
  }
}

void checkActions()
{
  checkLSDJStopped();                        //Check if LSDJ hit Stop
  setMode();
  updateStatusLight();
}

 /*
  checkLSDJStopped counts how long the clock was on, if its been on too long we assume
  LSDJ has stopped- Send a MIDI transport stop message and return true.
 */
boolean checkLSDJStopped()
{
  countClockPause++;                            //Increment the counter
  if(countClockPause > 16000) {                 //if we've reached our waiting period
    if(sequencerStarted) {
      readgbClockLine=false;
      countClockPause = 0;                      //reset our clock
      serial->write(0xFC);                      //send the transport stop message
#ifdef USE_TEENSY
      usbMIDI.sendRealTime(0xFC);
#endif
#ifdef USE_LEONARDO
      midiEventPacket_t event = {0x0F, 0xFC};
      MidiUSB.sendMIDI(event);
      MidiUSB.flush();
#endif
      sequencerStop();                          //call the global sequencer stop function
    }
    return true;
  }
  return false;
}

 /*
  sendMidiClockSlaveFromLSDJ waits for 8 clock bits from LSDJ,
  sends the transport start command if sequencer hasnt started yet,
  sends the midi clock tick, and sends a note value that corrisponds to
  LSDJ's row number on start (LSDJ only sends this once when it starts)
 */
void sendMidiClockSlaveFromLSDJ()
{
  if(!countGbClockTicks) {      //If we hit 8 bits
    if(!sequencerStarted) {         //If the sequencer hasnt started
      serial->write((0x90+memory[MEM_LSDJMASTER_MIDI_CH])); //Send the midi channel byte
      serial->write(readGbSerialIn);                //Send the row value as a note
      serial->write(0x7F);                          //Send a velocity 127
      serial->write(0xFA);     //send MIDI transport start message

#ifdef USE_TEENSY
      usbMIDI.sendNoteOn(memory[MEM_LSDJMASTER_MIDI_CH]+1,readGbSerialIn,0x7F);
      usbMIDI.sendRealTime(0xFA);
#endif
#ifdef USE_LEONARDO
      midiEventPacket_t event = {0x09, 0x90 | memory[MEM_LSDJMASTER_MIDI_CH] + 1, readGbSerialIn, 0x7F};
      MidiUSB.sendMIDI(event);
      MidiUSB.flush();
      event = {0x0F, 0xFA};
      MidiUSB.sendMIDI(event);
      MidiUSB.flush();
#endif
      sequencerStart();             //call the global sequencer start function
    }
    serial->write(0xF8);       //Send the MIDI Clock Tick

#ifdef USE_TEENSY
    usbMIDI.sendRealTime(0xF8);
#endif
#ifdef USE_LEONARDO
    midiEventPacket_t event = {0x0F, 0xF8};
    MidiUSB.sendMIDI(event);
    MidiUSB.flush();
#endif
    countGbClockTicks=0;            //Reset the bit counter
    readGbSerialIn = 0x00;                //Reset our serial read value

    updateVisualSync();
  }
  countGbClockTicks++;              //Increment the bit counter
 if(countGbClockTicks==8) countGbClockTicks=0;
}


================================================
FILE: Arduinoboy/Mode_LSDJ_Midiout.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

void modeLSDJMidioutSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,OUTPUT);
  digitalWrite(pinGBClock,HIGH);

 #ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(NULL);
 #endif

  countGbClockTicks=0;
  lastMidiData[0] = -1;
  lastMidiData[1] = -1;
  midiValueMode = false;
  blinkMaxCount=60;
  modeLSDJMidiout();
}

void modeLSDJMidiout()
{
#ifdef USE_LEONARDO
  midiEventPacket_t packet;
#endif
  while(1){
     if(getIncommingSlaveByte()) {
        if(incomingMidiByte > 0x6f) {
          switch(incomingMidiByte)
          {
           case 0x7F: //clock tick
             serial->write(0xF8);
#ifdef USE_TEENSY
             usbMIDI.sendRealTime((int)0xF8);
#endif
#ifdef USE_LEONARDO
             packet = {0x0F, 0xF8};
             MidiUSB.sendMIDI(packet);
             MidiUSB.flush();
#endif
                 break;
           case 0x7E: //seq stop
             serial->write(0xFC);
#ifdef USE_TEENSY
             usbMIDI.sendRealTime((int)0xFC);
#endif
#ifdef USE_LEONARDO
             packet = {0x0F, 0xFC};
             MidiUSB.sendMIDI(packet);
             MidiUSB.flush();
#endif
             stopAllNotes();
             break;
           case 0x7D: //seq start
             serial->write(0xFA);
#ifdef USE_TEENSY
             usbMIDI.sendRealTime((int)0xFA);
#endif
#ifdef USE_LEONARDO
             packet = {0x0F, 0xFA};
             MidiUSB.sendMIDI(packet);
             MidiUSB.flush();
#endif
             break;
           default:
             midiData[0] = (incomingMidiByte - 0x70);
             midiValueMode = true;
             break;
          }
        } else if (midiValueMode == true) {
          midiValueMode = false;
          midioutDoAction(midiData[0],incomingMidiByte);
        }

      } else {
        setMode();                // Check if mode button was depressed
        updateBlinkLights();
#ifdef USE_TEENSY
        while(usbMIDI.read()) ;
#endif
#ifdef USE_LEONARDO
        // while (MidiUSB.read()) ;
#endif
        if (serial->available()) {                  //If serial data was send to midi inp
          checkForProgrammerSysex(serial->read());
        }
      }
   }
}

void midioutDoAction(byte m, byte v)
{
  if(m < 4) {
    //note message
    if(v) {
      checkStopNote(m);
      playNote(m,v);
    } else if (midiOutLastNote[m]>=0) {
      stopNote(m);
    }
  } else if (m < 8) {
    m-=4;
    //cc message
    playCC(m,v);
  } else if(m < 0x0C) {
    m-=8;
    playPC(m,v);
  }
  blinkLight(0x90+m,v);
}

void checkStopNote(byte m)
{
  if((midioutNoteTimer[m]+midioutNoteTimerThreshold) < millis()) {
    stopNote(m);
  }
}

void stopNote(byte m)
{
  for(int x=0;x<midioutNoteHoldCounter[m];x++) {
    midiData[0] = (0x80 + (memory[MEM_MIDIOUT_NOTE_CH+m]));
    midiData[1] = midioutNoteHold[m][x];
    midiData[2] = 0x00;
    serial->write(midiData,3);
#ifdef USE_TEENSY
    usbMIDI.sendNoteOff(midioutNoteHold[m][x], 0, memory[MEM_MIDIOUT_NOTE_CH+m]+1);
#endif
#ifdef USE_LEONARDO
    midiEventPacket_t packet = { 0x08, 0x80 | memory[MEM_MIDIOUT_NOTE_CH + m], midioutNoteHold[m][x], 0 };
    MidiUSB.sendMIDI(packet);
    MidiUSB.flush();
#endif
  }
  midiOutLastNote[m] = -1;
  midioutNoteHoldCounter[m] = 0;
}

void playNote(byte m, byte n)
{
  midiData[0] = (0x90 + (memory[MEM_MIDIOUT_NOTE_CH+m]));
  midiData[1] = n;
  midiData[2] = 0x7F;
  serial->write(midiData,3);
#ifdef USE_TEENSY
  usbMIDI.sendNoteOn(n, 127, memory[MEM_MIDIOUT_NOTE_CH+m]+1);
#endif
#ifdef USE_LEONARDO
  midiEventPacket_t packet = { 0x09, 0x90 | memory[MEM_MIDIOUT_NOTE_CH + m], n, 127 };
  MidiUSB.sendMIDI(packet);
  MidiUSB.flush();
#endif

  midioutNoteHold[m][midioutNoteHoldCounter[m]] =n;
  midioutNoteHoldCounter[m]++;
  midioutNoteTimer[m] = millis();
  midiOutLastNote[m] =n;
}

void playCC(byte m, byte n)
{
  byte v = n;

  if(memory[MEM_MIDIOUT_CC_MODE+m]) {
    if(memory[MEM_MIDIOUT_CC_SCALING+m]) {
      v = (v & 0x0F)*8;
      //if(v) v --;
    }
    n=(m*7)+((n>>4) & 0x07);
    midiData[0] = (0xB0 + (memory[MEM_MIDIOUT_CC_CH+m]));
    midiData[1] = (memory[MEM_MIDIOUT_CC_NUMBERS+n]);
    midiData[2] = v;
    serial->write(midiData,3);
#ifdef USE_TEENSY
    usbMIDI.sendControlChange((memory[MEM_MIDIOUT_CC_NUMBERS+n]), v, memory[MEM_MIDIOUT_NOTE_CH+m]+1);
#endif
#ifdef USE_LEONARDO
    midiEventPacket_t packet = {0x0B, 0xB0 | (memory[MEM_MIDIOUT_NOTE_CH + m]+1), (memory[MEM_MIDIOUT_CC_NUMBERS + n]), v};
    MidiUSB.sendMIDI(packet);
    MidiUSB.flush();
#endif
  } else {
    if(memory[MEM_MIDIOUT_CC_SCALING+m]) {
      float s;
      s = n;
      v = ((s / 0x6f) * 0x7f);
    }
    n=(m*7);
    midiData[0] = (0xB0 + (memory[MEM_MIDIOUT_CC_CH+m]));
    midiData[1] = (memory[MEM_MIDIOUT_CC_NUMBERS+n]);
    midiData[2] = v;
    serial->write(midiData,3);
#ifdef USE_TEENSY
    usbMIDI.sendControlChange((memory[MEM_MIDIOUT_CC_NUMBERS+n]), v, memory[MEM_MIDIOUT_NOTE_CH+m]+1);
#endif
#ifdef USE_LEONARDO
    midiEventPacket_t packet = {0x0B, 0xB0 | (memory[MEM_MIDIOUT_NOTE_CH + m]+1), (memory[MEM_MIDIOUT_CC_NUMBERS + n]), v};
    MidiUSB.sendMIDI(packet);
    MidiUSB.flush();
#endif
  }
}

void playPC(byte m, byte n)
{
  midiData[0] = (0xC0 + (memory[MEM_MIDIOUT_NOTE_CH+m]));
  midiData[1] = n;
  serial->write(midiData,2);
#ifdef USE_TEENSY
  usbMIDI.sendProgramChange(n, memory[MEM_MIDIOUT_NOTE_CH+m]+1);
#endif
#ifdef USE_LEONARDO
  midiEventPacket_t packet = {0x0C, 0xC0 | (memory[MEM_MIDIOUT_NOTE_CH + m]+1), n};
  MidiUSB.sendMIDI(packet);
  MidiUSB.flush();
#endif
}

void stopAllNotes()
{
  for(int m=0;m<4;m++) {
    if(midiOutLastNote[m]>=0) {
      stopNote(m);
    }
    midiData[0] = (0xB0 + (memory[MEM_MIDIOUT_NOTE_CH+m]));
    midiData[1] = 123;
    midiData[2] = 0x7F;
    serial->write(midiData,3); //Send midi
#ifdef USE_TEENSY
    usbMIDI.sendControlChange(123, 127, memory[MEM_MIDIOUT_NOTE_CH+m]+1);
#endif
#ifdef USE_LEONARDO
    midiEventPacket_t packet = {0x0B, 0xB0 | memory[MEM_MIDIOUT_NOTE_CH + m], 123, 127};
    MidiUSB.sendMIDI(packet);
    MidiUSB.flush();
#endif
  }
}

boolean getIncommingSlaveByte()
{
  delayMicroseconds(midioutBitDelay);
  GB_SET(0,0,0);
  delayMicroseconds(midioutBitDelay);
  GB_SET(1,0,0);
  delayMicroseconds(2);
  if(digitalRead(pinGBSerialIn)) {
    incomingMidiByte = 0;
    for(countClockPause=0;countClockPause!=7;countClockPause++) {
      GB_SET(0,0,0);
      delayMicroseconds(2);
      GB_SET(1,0,0);
      incomingMidiByte = (incomingMidiByte << 1) + digitalRead(pinGBSerialIn);
    }
    return true;
  }
  return false;
}
























================================================
FILE: Arduinoboy/Mode_LSDJ_SlaveSync.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

void modeLSDJSlaveSyncSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,OUTPUT);
  digitalWrite(pinGBClock,HIGH);

#ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(usbMidiLSDJSlaveRealtimeMessage);
#endif

  blinkMaxCount=1000;
  modeLSDJSlaveSync();
}

void modeLSDJSlaveSync()
{
  while(1){  //Loop forever
  modeLSDJSlaveSyncUsbMidiReceive();
  if (serial->available()) {                 //If MIDI Byte Availaibleleleiel
    incomingMidiByte = serial->read();           //Read it

    if(!checkForProgrammerSysex(incomingMidiByte) && !usbMode) serial->write(incomingMidiByte);       //Send it back to the Midi out

    if(incomingMidiByte & 0x80) {               //If we have received a MIDI Status Byte
    switch (incomingMidiByte) {
      case 0xF8:                                //Case: Clock Message Recieved
        if((sequencerStarted && midiSyncEffectsTime && !countSyncTime)   //If the seq has started and our sync effect is on and at zero
          || (sequencerStarted && !midiSyncEffectsTime)) {               //or seq is started and there is no sync effects
              if(!countSyncPulse && midiDefaultStartOffset) {          //if we received a note for start offset
                //sendByteToGameboy(midiDefaultStartOffset);              //send the offset
              }
              sendClockTickToLSDJ();                                   //send the clock tick
              updateVisualSync();
        }
        if(midiSyncEffectsTime) {                                      //If sync effects are turned on
          countSyncTime++;                                             //increment our tick counter
          countSyncTime = countSyncTime % countSyncSteps;              //and mod it by the number of steps we want for the effect
        }
        break;
      case 0xFA:                                // Case: Transport Start Message
      case 0xFB:                                // and Case: Transport Continue Message
        sequencerStart();                       // Start the sequencer
        break;
      case 0xFC:                                // Case: Transport Stop Message
        sequencerStop();                        // Stop the sequencer
        break;
      default:
        if(incomingMidiByte == (0x90+memory[MEM_LSDJSLAVE_MIDI_CH])) { //if a midi note was received and its on the channel of the sync effects channel
           midiNoteOnMode = true;                        //turn on note capture
           midiData[0] = false;                  //and reset the captured note
        } else {
           midiNoteOnMode = false;                       //turn off note capture
        }
      }
    } else if(midiNoteOnMode) {   //if we've received a message thats not a status and our note capture mode is true
      if(!midiData[0]) {                  //if there is no note number yet
         midiData[0] = incomingMidiByte;  //then assume the byte is a note and assign it to a place holder
      } else {                                    //else assumed velocity
         if(incomingMidiByte > 0x00) {
           getSlaveSyncEffect(midiData[0]); //then call our sync effects function
         }
         midiData[0] = false;             //and reset the captured note
      }
    }
  }
  setMode();         //Check if the mode button was depressed
  updateStatusLight();
  }
}

/*
  sendClockTickToLSDJ is a lovely loving simple function I wish they where all this short
  Technicallyly we are sending nothing but a 8bit clock pulse
*/
void sendClockTickToLSDJ()
{
  for(countLSDJTicks=0;countLSDJTicks<8;countLSDJTicks++) {
    GB_SET(0,0,0);
    GB_SET(1,0,0);
  }
}


/*
  getSlaveSyncEffect receives a note, and assigns the propper effect of that note
*/
void getSlaveSyncEffect(byte note)
{
    switch(note) {
    case 48:                        //C-3ish, Transport Start
      sequencerStart();
      break;
    case 49:                        //C#3 Transport Stop
      sequencerStop();
      break;
    case 50:                        //D-3 Turn off sync effects
      midiSyncEffectsTime = false;
      break;
    case 51:                        //D#3 Sync effect, 1/2 time
      midiSyncEffectsTime = true;
      countSyncTime = 0;
      countSyncSteps = 2;
      break;
    case 52:                        //E-3 Sync Effect, 1/4 time
      midiSyncEffectsTime = true;
      countSyncTime = 0;
      countSyncSteps = 4;
      break;
    case 53:                        //F-3 Sync Effect, 1/8 time
      midiSyncEffectsTime = true;
      countSyncTime = 0;
      countSyncSteps = 8;
      break;
    default:                        //All other notes will make LSDJ Start at the row number thats the same as the note number.
      midiDefaultStartOffset = midiData[0];
      break;
    }
}

void usbMidiLSDJSlaveRealtimeMessage(uint8_t message)
{
    switch(message) {
      case 0xF8:
          if((sequencerStarted && midiSyncEffectsTime && !countSyncTime)   //If the seq has started and our sync effect is on and at zero
            || (sequencerStarted && !midiSyncEffectsTime)) {               //or seq is started and there is no sync effects
                if(!countSyncPulse && midiDefaultStartOffset) {          //if we received a note for start offset
                  //sendByteToGameboy(midiDefaultStartOffset);              //send the offset
                }
                sendClockTickToLSDJ();                                   //send the clock tick
                updateVisualSync();
          }
          if(midiSyncEffectsTime) {                                      //If sync effects are turned on
            countSyncTime++;                                             //increment our tick counter
            countSyncTime = countSyncTime % countSyncSteps;              //and mod it by the number of steps we want for the effect
          }
      break;
      case 0xFA:                                // Case: Transport Start Message
      case 0xFB:                                // and Case: Transport Continue Message
          sequencerStart();                       // Start the sequencer
      break;
      case 0xFC:                                // Case: Transport Stop Message
          sequencerStop();
      break;
    }
}


void modeLSDJSlaveSyncUsbMidiReceive()
{
#ifdef USE_TEENSY

    while(usbMIDI.read(memory[MEM_LSDJSLAVE_MIDI_CH]+1)) {
        switch(usbMIDI.getType()) {
            case 0x90: // note on
                getSlaveSyncEffect(usbMIDI.getData1());
            break;
            /*
            case 0: // note on
            break;
            case 3: // CC
            break;
            case 4: // PG
            break;
            case 5: // AT
            break;
            case 6: // PB
            break;
            */
        }
    }
#endif
#ifdef USE_LEONARDO

    midiEventPacket_t rx;
    do
    {
      rx = MidiUSB.read();
      uint8_t ch = rx.byte1 & 0x0F;
      if (ch == memory[MEM_LSDJSLAVE_MIDI_CH] && rx.header == 0x09)
      {
        getSlaveSyncEffect(rx.byte2);
      }
      switch (rx.byte1)
      {
      case 0xF8:
        if ((sequencerStarted && midiSyncEffectsTime && !countSyncTime) //If the seq has started and our sync effect is on and at zero
            || (sequencerStarted && !midiSyncEffectsTime))
        { //or seq is started and there is no sync effects
          if (!countSyncPulse && midiDefaultStartOffset)
          { //if we received a note for start offset
            //sendByteToGameboy(midiDefaultStartOffset);              //send the offset
          }
          sendClockTickToLSDJ(); //send the clock tick
          updateVisualSync();
        }
        if (midiSyncEffectsTime)
        {                                                 //If sync effects are turned on
          countSyncTime++;                                //increment our tick counter
          countSyncTime = countSyncTime % countSyncSteps; //and mod it by the number of steps we want for the effect
        }
        break;
      case 0xFA:          // Case: Transport Start Message
      case 0xFB:          // and Case: Transport Continue Message
        sequencerStart(); // Start the sequencer
        break;
      case 0xFC: // Case: Transport Stop Message
        sequencerStop();
        break;
      }
    } while (rx.header != 0);
#endif
}


================================================
FILE: Arduinoboy/Mode_MidiGb.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

void modeMidiGbSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,OUTPUT);
  digitalWrite(pinGBClock,HIGH);

#ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(NULL);
#endif

  blinkMaxCount=1000;
  modeMidiGb();
}

void modeMidiGb()
{
  boolean sendByte = false;
  while(1){                                //Loop foreverrrr
    modeMidiGbUsbMidiReceive();

    if (serial->available()) {          //If MIDI is sending
      incomingMidiByte = serial->read();    //Get the byte sent from MIDI

      if(!checkForProgrammerSysex(incomingMidiByte) && !usbMode) serial->write(incomingMidiByte); //Echo the Byte to MIDI Output

      if(incomingMidiByte & 0x80) {
        switch (incomingMidiByte & 0xF0) {
          case 0xF0:
            midiValueMode = false;
            break;
          default:
            sendByte = false;
            midiStatusChannel = incomingMidiByte&0x0F;
            midiStatusType    = incomingMidiByte&0xF0;
            if(midiStatusChannel == memory[MEM_MGB_CH]) {
               midiData[0] = midiStatusType;
               sendByte = true;
            } else if (midiStatusChannel == memory[MEM_MGB_CH+1]) {
               midiData[0] = midiStatusType+1;
               sendByte = true;
            } else if (midiStatusChannel == memory[MEM_MGB_CH+2]) {
               midiData[0] = midiStatusType+2;
               sendByte = true;
            } else if (midiStatusChannel == memory[MEM_MGB_CH+3]) {
               midiData[0] = midiStatusType+3;
               sendByte = true;
            } else if (midiStatusChannel == memory[MEM_MGB_CH+4]) {
               midiData[0] = midiStatusType+4;
               sendByte = true;
            } else {
              midiValueMode  =false;
              midiAddressMode=false;
            }
            if(sendByte) {
              statusLedOn();
              sendByteToGameboy(midiData[0]);
              delayMicroseconds(GB_MIDI_DELAY);
              midiValueMode  =false;
              midiAddressMode=true;
            }
           break;
        }
      } else if (midiAddressMode){
        midiAddressMode = false;
        midiValueMode = true;
        midiData[1] = incomingMidiByte;
        sendByteToGameboy(midiData[1]);
        delayMicroseconds(GB_MIDI_DELAY);
      } else if (midiValueMode) {
        midiData[2] = incomingMidiByte;
        midiAddressMode = true;
        midiValueMode = false;

        sendByteToGameboy(midiData[2]);
        delayMicroseconds(GB_MIDI_DELAY);
        statusLedOn();
        blinkLight(midiData[0],midiData[2]);
      }
    } else {
      setMode();                // Check if mode button was depressed
      updateBlinkLights();
      updateStatusLed();
    }
  }
}

 /*
 sendByteToGameboy does what it says. yay magic
 */
void sendByteToGameboy(byte send_byte)
{
 for(countLSDJTicks=0;countLSDJTicks!=8;countLSDJTicks++) {  //we are going to send 8 bits, so do a loop 8 times
   if(send_byte & 0x80) {
       GB_SET(0,1,0);
       GB_SET(1,1,0);
   } else {
       GB_SET(0,0,0);
       GB_SET(1,0,0);
   }

#if defined (F_CPU) && (F_CPU > 24000000)
   // Delays for Teensy etc where CPU speed might be clocked too fast for cable & shift register on gameboy.
   delayMicroseconds(1);
#endif
   send_byte <<= 1;
 }
}

void modeMidiGbUsbMidiReceive()
{
#ifdef USE_TEENSY

    while(usbMIDI.read()) {
        uint8_t ch = usbMIDI.getChannel() - 1;
        boolean send = false;
        if(ch == memory[MEM_MGB_CH]) {
            ch = 0;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+1]) {
            ch = 1;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+2]) {
            ch = 2;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+3]) {
            ch = 3;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+4]) {
            ch = 4;
            send = true;
        }
        if(!send) return;
        uint8_t s;
        switch(usbMIDI.getType()) {
            case 0x80: // note off
            case 0x90: // note on
                s = 0x90 + ch;
                if(usbMIDI.getType() == 0x80) {
                    s = 0x80 + ch;
                }
                sendByteToGameboy(s);
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData1());
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData2());
                delayMicroseconds(GB_MIDI_DELAY);
                blinkLight(s, usbMIDI.getData2());
            break;
            case 0xB0: // CC
                sendByteToGameboy(0xB0+ch);
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData1());
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData2());
                delayMicroseconds(GB_MIDI_DELAY);
                blinkLight(0xB0+ch, usbMIDI.getData2());
            break;
            case 0xC0: // PG
                sendByteToGameboy(0xC0+ch);
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData1());
                delayMicroseconds(GB_MIDI_DELAY);
                blinkLight(0xC0+ch, usbMIDI.getData2());
            break;
            case 0xE0: // PB
                sendByteToGameboy(0xE0+ch);
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData1());
                delayMicroseconds(GB_MIDI_DELAY);
                sendByteToGameboy(usbMIDI.getData2());
                delayMicroseconds(GB_MIDI_DELAY);
            break;
        }

        statusLedOn();
    }
#endif

#ifdef USE_LEONARDO

    midiEventPacket_t rx;
      do
      {
        rx = MidiUSB.read();
        uint8_t ch = rx.byte1 & 0x0F;
        boolean send = false;
        if(ch == memory[MEM_MGB_CH]) {
            ch = 0;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+1]) {
            ch = 1;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+2]) {
            ch = 2;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+3]) {
            ch = 3;
            send = true;
        } else if (ch == memory[MEM_MGB_CH+4]) {
            ch = 4;
            send = true;
        }
        if (!send) return;
        uint8_t s;
        switch (rx.header)
        {
        case 0x08: // note off
        case 0x09: // note on
          s = 0x90 + ch;
          if (rx.header == 0x08)
          {
            s = 0x80 + ch;
          }
          sendByteToGameboy(s);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte2);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte3);
          delayMicroseconds(GB_MIDI_DELAY);
          blinkLight(s, rx.byte2);
          break;
        case 0x0B: // CC
          sendByteToGameboy(0xB0 + ch);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte2);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte3);
          delayMicroseconds(GB_MIDI_DELAY);
          blinkLight(0xB0 + ch, rx.byte2);
          break;
        case 0x0C: // PG
          sendByteToGameboy(0xC0 + ch);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte2);
          delayMicroseconds(GB_MIDI_DELAY);
          blinkLight(0xC0 + ch, rx.byte2);
          break;
        case 0x0E: // PB
          sendByteToGameboy(0xE0 + ch);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte2);
          delayMicroseconds(GB_MIDI_DELAY);
          sendByteToGameboy(rx.byte3);
          delayMicroseconds(GB_MIDI_DELAY);
          break;
        default:
          return;
        }

        statusLedOn();
      } while (rx.header != 0);
#endif
}


================================================
FILE: Arduinoboy/Mode_Nanoloop.ino
================================================
/**************************************************************************
 * Name:    Timothy Lamb                                                  *
 * Email:   trash80@gmail.com                                             *
 ***************************************************************************/
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

void modeNanoloopSetup()
{
  digitalWrite(pinStatusLed,LOW);
  pinMode(pinGBClock,OUTPUT);
  digitalWrite(pinGBClock,HIGH);

#ifdef USE_TEENSY
  usbMIDI.setHandleRealTimeSystem(usbMidiNanoloopRealtimeMessage);
#endif

  blinkMaxCount=1000;
  modeNanoloopSync();
}

void modeNanoloopSync()
{
  while(1){  //Loop forever
  modeNanoloopUsbMidiReceive();
  if (serial->available()) {                 //If MIDI Byte Availaibleleleiel
    incomingMidiByte = serial->read();           //Read it
    if(!checkForProgrammerSysex(incomingMidiByte) && !usbMode) serial->write(incomingMidiByte);       //Send it back to the Midi out


    if(incomingMidiByte & 0x80) {
    switch (incomingMidiByte) {
      case 0xF8:                                 // Clock Message Recieved
                                                 // Send a clock tick out if the sequencer is running
        if(sequencerStarted) {
          nanoSkipSync = !nanoSkipSync;
          if(countSyncTime) {
            nanoState = sendTickToNanoloop(nanoState, false);
          } else {
            nanoState = sendTickToNanoloop(true, true);
          }
          nanoState = sendTickToNanoloop(nanoState, nanoSkipSync);
          updateVisualSync();
          break;
        }
        break;
      case 0xFA:                                 // Transport Start Message
      case 0xFB:                                 // Transport Continue Message
        sequencerStart();
        break;
      case 0xFC:                                 // Transport Stop Message
        sequencerStop();
        break;
      default:
        break;
      }
    }
  }
  setMode();         //Check if the mode button was depressed
  updateStatusLight();
  }
}

boolean sendTickToNanoloop(boolean state, boolean last_state)
{
  if(!state) {
    if(last_state) {
       GB_SET(0,1,0);
       GB_SET(1,1,0);
    } else {
       GB_SET(0,0,0);
       GB_SET(1,0,0);
    }
    return true;
  } else {
    GB_SET(0,1,0);
    GB_SET(1,1,0);
    return false;
  }
}

void usbMidiNanoloopRealtimeMessage(uint8_t message)
{
    switch(message) {
      case 0xF8:
          if(sequencerStarted) {
            nanoSkipSync = !nanoSkipSync;
            if(countSyncTime) {
              nanoState = sendTickToNanoloop(nanoState, false);
            } else {
              nanoState = sendTickToNanoloop(true, true);
            }
            nanoState = sendTickToNanoloop(nanoState, nanoSkipSync);
            updateVisualSync();
          }
      break;
      case 0xFA:                                // Case: Transport Start Message
      case 0xFB:                                // and Case: Transport Continue Message
          sequencerStart();                       // Start the sequencer
      break;
      case 0xFC:                                // Case: Transport Stop Message
          sequencerStop();
      break;
    }
}


void modeNanoloopUsbMidiReceive()
{
#ifdef USE_TEENSY
    while(usbMIDI.read(memory[MEM_LSDJSLAVE_MIDI_CH]+1)) {
        switch(usbMIDI.getType()) {
            case 0x90: // note on
                getSlaveSyncEffect(usbMIDI.getData1());
            break;
            /*
            case 0: // note on
            break;
            case 3: // CC
            break;
            case 4: // PG
            break;
            case 5: // AT
            break;
            case 6: // PB
            break;
            */
        }
    }
#endif

#ifdef USE_LEONARDO
  midiEventPacket_t rx;
  do
  {
    rx = MidiUSB.read();
    usbMidiNanoloopRealtimeMessage(rx.byte1);
  } while (rx.header != 0);
#endif

}


================================================
FILE: Arduinoboy/Mode_Programmer.ino
================================================
void modeProgrammer()
{
  while(sysexProgrammingConnected || sysexProgrammingMode) {
    checkProgrammerConnected();
    if (serial->available()) checkForProgrammerSysex(serial->read());
    updateProgrammerLeds();
    setMode();
    usbMidiUpdate();
  }
  showSelectedMode();
  switchMode();
}

void setProgrammerConnected()
{
  sysexProgrammerLastResponse = millis();
  if(!sysexProgrammingConnected) {
    programmerSendSettings();
  }
  sysexProgrammingConnected = 1;
}

void checkProgrammerConnected()
{
  programmerSendConnectRequest();
  programmerCheckTimeout();
}

void programmerSendSettings()
{
  sysexData[0] = 0xF0;
  sysexData[1] = sysexManufacturerId;
  sysexData[2] = 0x40;
  memcpy(&sysexData[3], memory, MEM_MAX+1);
  sysexData[MEM_MAX+3] = 0xF7;
  serial->write(sysexData, MEM_MAX+4);
#ifdef USE_TEENSY
  usbMIDI.sendSysEx(MEM_MAX+4, sysexData);
#endif
}

void setProgrammerRequestConnect()
{
  uint8_t data[4] = {0xF0,sysexManufacturerId,65,0xF7};
  serial->write(data, 4);
#ifdef USE_TEENSY
  usbMIDI.sendSysEx(4, data);
#endif
}

void setProgrammerMemorySave()
{
  byte offset = 2;
  for(byte m=4;m<=MEM_MAX;m++) {
    memory[m] = sysexData[offset];
    offset++;
  }
  saveMemory();
  loadMemory();
  programmerSendSettings();
}

void setProgrammerRestoreMemory()
{
  initMemory(1);
  programmerSendSettings();
}

void programmerCheckTimeout()
{
  if(sysexProgrammingConnected && millis() > (sysexProgrammerLastResponse+sysexProgrammerWaitTime)) {
    //programmer timeout!
    sysexProgrammingConnected = 0;
    sysexProgrammingMode      = 0;
  }
  if(sysexProgrammingMode && millis() > (sysexProgrammerLastResponse+sysexProgrammerWaitTime)) {
    //programmer timeout!
    sysexProgrammingConnected = 0;
    sysexProgrammingMode      = 0;
  }
}

void programmerSendConnectRequest()
{
  if(millis() > (sysexProgrammerLastSent+sysexProgrammerCallTime)) {
    uint8_t data[6] = {0xF0, sysexManufacturerId, 0x7F, defaultMemoryMap[MEM_VERSION_FIRST], defaultMemoryMap[MEM_VERSION_SECOND], 0xF7};
    serial->write(data, 6);
#ifdef USE_TEENSY
    usbMIDI.sendSysEx(6, data);
#endif
    sysexProgrammerLastSent = millis();
  }
}

boolean checkSysexChecksum()
{
  byte checksum = sysexData[(sysexPosition - 1)];
  byte checkdata= 0;
  if(checksum) {
    for(int x=2;x!=(sysexPosition - 2);x++) {
      checkdata += sysexData[x];
    }
    if(checkdata & 0x80) checkdata -= 0x7F;
    if(checkdata == checksum) {
      return true;
    }
  }
  return true;
}


void clearSysexBuffer()
{
  for(int x=0;x!=sysexPosition;x++) {
    sysexData[x]= 0;
  }
  sysexPosition = 0;
}

void setMode(byte mode)
{
  memory[MEM_MODE] = mode;
  #ifndef USE_DUE
  EEPROM.write(MEM_MODE, memory[MEM_MODE]);
  #endif
  showSelectedMode();
  switchMode();
}

void sendMode()
{
  uint8_t data[4] = {0xF0, sysexManufacturerId, memory[MEM_MODE], 0xF7};
  serial->write(data, 4);
#ifdef USE_TEENSY
  usbMIDI.sendSysEx(4, data);
#endif
}

void setMidioutDelay(byte a,byte b,byte c,byte d)
{
  memory[MEM_MIDIOUT_BIT_DELAY] = a;
  memory[MEM_MIDIOUT_BIT_DELAY+1] = b;
  memory[MEM_MIDIOUT_BYTE_DELAY] = c;
  memory[MEM_MIDIOUT_BYTE_DELAY+1] = d;
  saveMemory();
  changeTasks();
}

void getSysexData()
{
  if(sysexData[0] == 0x69 && checkSysexChecksum()) {
    //sysex good, do stuff
    sysexPosition = 0;
    if(sysexProgrammingMode) {
      if(sysexData[1] == 64
      && sysexData[2] == defaultMemoryMap[MEM_VERSION_FIRST]
      && sysexData[3] == defaultMemoryMap[MEM_VERSION_SECOND]) {
        //serial connected to programmer
        setProgrammerRequestConnect();
      }
      if(sysexData[1] == 66
      && sysexData[2] == defaultMemoryMap[MEM_VERSION_FIRST]
      && sysexData[3] == defaultMemoryMap[MEM_VERSION_SECOND]) {
        //serial connected to programmer
        setProgrammerConnected();
      }
      if(sysexData[1] == 70) {
        //save states
        setProgrammerMemorySave();
      }
      if(sysexData[1] == 71) {
        //save states
        setProgrammerRestoreMemory();
      }
    }
    if(sysexData[1] == 72) {
      sysexProgrammingMode = true;
      sysexProgrammerLastResponse = millis();
      modeProgrammer();
    }
    if(sysexData[1] == 73) {
      sendMode();
    }
    if(sysexData[1] == 74) {
      setMode(sysexData[2]);
    }
    if(sysexData[1] == 75) {
      setMidioutDelay(sysexData[2],sysexData[3],sysexData[4],sysexData[5]);
    }
  }
  clearSysexBuffer();
}



boolean checkForProgrammerSysex(byte sin)
{
    if(sin == 0xF0) {
        sysexReceiveMode = true;
        sysexPosition= 0;
        return true;
    } else if (sin == 0xF7 && sysexReceiveMode) {
        sysexReceiveMode = false;
        getSysexData();
        sysexPosition= 0;
        return true;
    } else if (sysexReceiveMode == true) {
        sysexData[sysexPosition] = sin;
        sysexPosition++;
        if(sysexPosition > longestSysexMessage) {
            clearSysexBuffer();
            sysexReceiveMode = false;
        }
        return true;
    }
    return false;
}


void blinkSelectedLight(int led)
{
      if(!blinkSwitch[led]) digitalWrite(pinLeds[led],HIGH);
      blinkSwitch[led]=1;
      blinkSwitchTime[led]=0;
}


================================================
FILE: Arduinoboy/UsbMidi.ino
================================================

#ifndef USE_TEENSY
void usbMidiSendTwoByteMessage(uint8_t b1, uint8_t b2) {};
void usbMidiSendThreeByteMessage(uint8_t b1, uint8_t b2, uint8_t b3) {};
void usbMidiSendRTMessage(uint8_t b) {};
void usbMidiHandleSysEx(const uint8_t *data, uint16_t length, bool complete) {};
void usbMidiInit() {};
void usbMidiUpdate() {};
#else

void usbMidiSendTwoByteMessage(uint8_t b1, uint8_t b2)
{
    uint8_t stat = b1 & 0xf0;
    uint8_t chan = (b1 & 0x0f)+1;
    if(stat == 0xC0) {
        usbMIDI.sendProgramChange(b2, chan);
    } else if (stat == 0xD0) {
        usbMIDI.sendAfterTouch(b2, chan);
    }
}

void usbMidiSendThreeByteMessage(uint8_t b1, uint8_t b2, uint8_t b3)
{
    uint8_t channel = (b1&0x0F)+1;

    switch(midiData[0] & 0xF0) {
        case 0x80:
          usbMIDI.sendNoteOff(b2, b3, channel);
          usbMIDI.send_now();
          break;
        case 0x90:
          usbMIDI.sendNoteOn(b2, b3, channel);
          usbMIDI.send_now();
          break;
        case 0xA0:
          usbMIDI.sendPolyPressure(b2, b3, channel);
          break;
        case 0xB0:
          usbMIDI.sendControlChange(b2, b3, channel);
          usbMIDI.send_now();
          break;
        case 0xE0:
          unsigned short v = (unsigned short)b3;
          v<<=7;
          v|=(unsigned short)b2;
          usbMIDI.sendPitchBend(v, channel);
          break;
    }
}

void usbMidiSendRTMessage(uint8_t b)
{
    usbMIDI.sendRealTime(b);
}

void usbMidiUpdate()
{
    usbMIDI.read();
}

void usbMidiHandleSysEx(const uint8_t *data, uint16_t length, bool complete)
{
    if(sysexPosition + length >= longestSysexMessage || (length < 3 && complete)) {
        //wrapped!
        sysexPosition = 0;
        return ;
    }

    if(sysexPosition == 0 && complete) {
        memcpy(&sysexData[0], &data[1], length-2);
        sysexPosition += length-2;
    } else if (sysexPosition == 0 && !complete) {
        memcpy(&sysexData[0], &data[1], length-1);
        sysexPosition += length-1;
    } else if (!complete) {
        memcpy(&sysexData[sysexPosition], &data[0], length);
        sysexPosition += length;
    } else {
        memcpy(&sysexData[sysexPosition], &data[0], length-1);
        sysexPosition += length-1;
    }

    if(complete) {
        getSysexData();
    }
}

void usbMidiInit()
{
    usbMIDI.setHandleSysEx(usbMidiHandleSysEx);
}

#endif
























================================================
FILE: Changelog.md
================================================
## Changelog

### 05/19/20
* Arduinoboy to version 1.3.4
* Added support for Arduino Mega 2560 and Arduino UNO Wifi

### 05/17/20
* Arduinoboy to version 1.3.3
* Added support for Arduino Due

### 05/03/20
* Arduinoboy to version 1.3.2
* Added support for Arduino Leonardo/Yún/Micro (ATmega32U4) (only Leonardo tested)

### 04/19/20
* Arduinoboy to version 1.3.1
* Fixed Nanoloop sync through USB (teensy and Leonardo tested)

### 07/10/16
* New Version 1.3.0a, please download from the [Releases] (https://github.com/trash80/Arduinoboy/releases) if you want the most recent stable version.
* Added Teensy 3.x & LC support. Check the main file for the pin configuration.
* Added USB MIDI support for Teensy
* Updated LSDJ LIVEMAP / SYNCMAP mode. This only works with LSDJ Arduinoboy version 4.8.7 and above. Licensed users can [download it here](http://littlesounddj.com/lsd/latest/full_version/lsdj4_8_7-arduinoboy.zip) Livemap has been removed in favor of stable sync slave mode.

### 06/26/15 
* Project has been moved to GitHub. mGB has been moved to it's own project [Available here](https://github.com/trash80/mGB)

### 12/23/11
* Arduinoboy to version 1.2.3
* Fixed code to work in Arduino 1.0 Software.

### 09/14/11
   * Arduinoboy to version 1.2.2
   * Fixed bug in mGB mode causing the Arduinoboy to respond to other MIDI channels besides the ones assigned to mGB.

### 04/03/11
   * Arduinoboy to version 1.2.0
   * Added EEPROM based settings to all modes which include reassigning MIDI channels in mGB
   * Created software editor for Arduinoboy settings. The file is in the zip and requires the free Max Runtime: http://cycling74.com/downloads/
   * Added 2 new Modes that require a new version of LSDJ. There is a unofficial release of LSDJ which supports these new modes, available here: http://littlesounddj.com/lsd/latest/full_version
      * LIVEMAP / SYNCMAP
       * LIVEMAP - Lsdj will use its own clock, but a incoming midi note will cue midi note # to song row # in live mode.
       * SYNCMAP - Lsdj will sync to incoming MIDI sync, and notes immediately change the song row #.
      * MIDIOUT - LSDJ to MIDIOUT. Each of the 4 gameboy channels send MIDI data on 4 midi channels by the use of effects commands:
       * N - Sends a MIDI Note - Absolute to the value placed in the effect. N00 sends note off, N01-N6F send notes 1 to 112.
       * Q - Sends a MIDI Note relative to the current channel's pitch. The effect value is a offset. so Q0C in PU1 would send a note 1 octave higher than what Pu1 is currently playing. This is useful as a table command to track midi notes as normal notes in the sequencer.
       * X - Sends a MIDI CC - By default in Arduinoboy the high nibble selects a CC#, and the low nibble sends a value [0-F] to [0-127]. This can be changed to allow just 1 midi CC with a range of 00-6F, or 7 CCs with scaled or unscaled values.
       * Y - Sends a program/patch/preset change.

### 02/07/09
* Arduinoboy to version 1.1.0
* Changed Gameboy Pins to the Arduino's "Analog In" pins. From  the old version's 5,6,7 to A0,A1,A2. This allows better more stable behavior. View the source file for changes. And the new "schematic" at the bottom of the page.

### 02/02/09
   * mGB to version 1.3.0
     * Rewrote 90% of code into assembly for much faster performance- especially noticeable on DMG.
     * Changed note behavior. Removed Monophonic note memory to increase performance. 
     * Envelope does not retrigger if the notes overlap and have the same velocity- Good for arpeggios / broken chords. 
     * Note off has a slight delay so immediate retrigged notes don't cause "clicking" effect due to turning off the synth. 
     * Added screen off mode for great signal-to-noise ratio, longer battery life, and better performance on DMG. (To toggle the screen mode hold Select and press A.)
     * Created back-end routine that prioritizes processes for better performance. 
     * Added 8 "noise" shapes to the Wav synth for more interesting effects.
     * Made Wav pitch sweep stable and changed it so it glitches out at values above 8. :D

### 11/05/08
   * New Google group created for Arduinoboy and mGB. http://groups.google.com/group/arduinoboy
   * New Flickr Group. Share your Arduinoboy pics. :) http://flickr.com/groups/arduinoboy
   * mGB to version 1.2.4
    * Fixed small bug with the indicator arrow, it was offset vertically a bit.
    * Fixed bug with unexpected behavior with large PB Ranges
    * PB Range Max is now 48 notes. (hehe)
    * Octave Shift max is now -2/+3 
    * Added some Octave shift logic. If the current note is greater than what the GB can play due to octave shifting, it will select the lower octave note, so no off key notes will play.
    * Added Gameboy Color fast-cpu mode- better performance with newer Gameboys.

### 10/28/08
* mGB to version 1.2.3
    * Added Note markers above synth number, so you can tell if the synth is on. ;)
    * Added PB wheel reset to MIDI panic (Start button)
    * Code more efficient (I'm sure there is still more to do here)
    * nitro2k01 @ http://gameboygenius.8bitcollective.com rewrote my gamejack serial function to make it as fast as possible. THANKS!!
   * Arduinoboy 1.0.5 yet again its just a release to work with mGB 1.2.3 - Everytime the code is sped up on mGB, I remove some delay in Arduinoboy to make the communication faster. This is why you always see a update of Arduinoboy with mGB


### 10/25/08
   * Added Program Change messages to mGB
   * Rewrote MIDI data input for mGB. (Rewrote the function in ASM to make it faster)
   * Added Controller Priority. While changing parameters on the gameboy itself, MIDI messages will not overwrite your changes while your editing them. This is a good live mode feature 
   * Arduinoboy code updated yet again for mGB behavior. Arduinoboy release will now always be included in a zip file inside the mGB zip so you know that the version of Arduinoboy thats included with the mGB archive is the one to use.

### 10/23/08
   * Found & Fixed various bugs in 1.2.0 
   * Changed help text. Made it more clear.

### 10/23/08
   * Added preset load/save memory to mGB. 16 Storage slots for each synth. Recalled via interface or by Midi CC 5 for now, I want to add program change message but would require further rewrites. Check the information below for mGB usage.
   * mGB is now rock solid stable *(It needs Arduinoboy 1.0.3 to work properly)*
   * Changed mGB interface to use less sprites, as a result the look has changed.
   * Arduinoboy 1.0.3 has better behavior for mGB 1.2.0 but should also work better for old mGB versions as well.

### 10/20/08
   * Added interface to mGB. 
   * Changed WAV CC Parameters
   * Arduinoboy 1.0.2 has better behavior for mGB 1.1.0


================================================
FILE: Editor/ArduinoBoyEditor-Midi.maxpat
================================================
{
	"patcher" : 	{
		"fileversion" : 1,
		"appversion" : 		{
			"major" : 7,
			"minor" : 2,
			"revision" : 1,
			"architecture" : "x86",
			"modernui" : 1
		}
,
		"rect" : [ 34.0, 79.0, 708.0, 615.0 ],
		"bglocked" : 0,
		"openinpresentation" : 1,
		"default_fontsize" : 12.0,
		"default_fontface" : 0,
		"default_fontname" : "Arial",
		"gridonopen" : 1,
		"gridsize" : [ 15.0, 15.0 ],
		"gridsnaponopen" : 1,
		"objectsnaponopen" : 1,
		"statusbarvisible" : 2,
		"toolbarvisible" : 1,
		"lefttoolbarpinned" : 0,
		"toptoolbarpinned" : 0,
		"righttoolbarpinned" : 0,
		"bottomtoolbarpinned" : 0,
		"toolbars_unpinned_last_save" : 0,
		"tallnewobj" : 0,
		"boxanimatetime" : 200,
		"enablehscroll" : 1,
		"enablevscroll" : 1,
		"devicewidth" : 0.0,
		"description" : "",
		"digest" : "",
		"tags" : "",
		"style" : "",
		"subpatcher_template" : "",
		"boxes" : [ 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-4",
					"linecount" : 3,
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 877.0, 1231.0, 422.0, 47.0 ],
					"presentation" : 1,
					"presentation_linecount" : 2,
					"presentation_rect" : [ 15.0, 10.0, 448.0, 33.0 ],
					"style" : "",
					"text" : "Select MIDI IN & OUT Port below and plug Arduinoboy 1.2 into the corresponding ports. Wait a few seconds, if the status doesnt change, check your cables."
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-216",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 613.0, 256.0, 168.0, 20.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 192.0, 58.0, 132.0, 20.0 ],
					"style" : "",
					"text" : "Arduinoboy Midi Out"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-215",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 598.0, 241.0, 168.0, 20.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 30.0, 59.0, 168.0, 20.0 ],
					"style" : "",
					"text" : "Arduinoboy Midi In"
				}

			}
, 			{
				"box" : 				{
					"id" : "obj-108",
					"maxclass" : "button",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "bang" ],
					"patching_rect" : [ 67.0, 97.0, 20.0, 20.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"fontsize" : 11.595187,
					"id" : "obj-111",
					"items" : [ "AU DLS Synth 1", ",", "Loopback Bus 1", ",", "Loopback IAC Bus 2", ",", "MIDISPORT 2x2 Port A", ",", "MIDISPORT 2x2 Port B", ",", "Teensy MIDI", ",", "from Max 1", ",", "from Max 2" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 184.0, 144.0, 115.0, 21.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 192.0, 78.0, 142.0, 21.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 11.595187,
					"id" : "obj-116",
					"maxclass" : "newobj",
					"numinlets" : 2,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 184.0, 121.0, 50.0, 21.0 ],
					"style" : "",
					"text" : "midiinfo"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 11.595187,
					"id" : "obj-134",
					"maxclass" : "newobj",
					"numinlets" : 2,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 68.0, 121.0, 50.0, 21.0 ],
					"style" : "",
					"text" : "midiinfo"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"fontsize" : 11.595187,
					"id" : "obj-135",
					"items" : [ "Loopback Bus 1", ",", "Loopback IAC Bus 2", ",", "MIDISPORT 2x2 Port A", ",", "MIDISPORT 2x2 Port B", ",", "Teensy MIDI", ",", "to Max 1", ",", "to Max 2" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 70.0, 145.0, 115.0, 21.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 30.0, 78.0, 141.0, 21.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 11.595187,
					"id" : "obj-136",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "bang" ],
					"patching_rect" : [ 68.0, 73.0, 58.0, 21.0 ],
					"style" : "",
					"text" : "loadbang"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-8",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 231.0, 196.0, 49.0, 22.0 ],
					"style" : "",
					"text" : "midiout"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-6",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "int" ],
					"patching_rect" : [ 118.0, 187.0, 42.0, 22.0 ],
					"style" : "",
					"text" : "midiin"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-180",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 284.0, 777.0, 251.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 376.0, 68.0, 53.0, 24.0 ],
					"style" : "",
					"text" : "Mode"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-115",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 206.0, 1052.0, 81.0, 22.0 ],
					"style" : "",
					"text" : "prepend 70 0"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-107",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1134.0, 1008.0, 48.0, 22.0 ],
					"style" : "",
					"text" : "r mode"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-78",
					"items" : [ "1:", "LSDJ", "Slave", "Mode", ",", "2:", "LSDJ", "Master", "Mode", ",", "3:", "LSDJ", "Keyboard", "Mode", ",", "4:", "Nanoloop", "Sync", ",", "5:", "mGB", "Mode", ",", "6:", "LSDJ", "Live/Sync", "Map", ",", "7:", "LSDJ", "MIDI", "Out" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1134.0, 1033.0, 145.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 435.0, 70.0, 195.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-10",
					"linecount" : 3,
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 573.0, 1216.0, 374.0, 40.0 ],
					"presentation" : 1,
					"presentation_linecount" : 3,
					"presentation_rect" : [ 17.0, 556.0, 374.0, 40.0 ],
					"style" : "",
					"text" : "Delay between each time aBoy checks the Gameboy for\nnew incomming messages. Lower numbers tend to freeze\nLSDJ. Default is 40us with a multiplier of 1",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-106",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 730.0, 1196.0, 81.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 174.0, 536.0, 81.0, 18.0 ],
					"style" : "",
					"text" : "MULTIPLIER"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-105",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 574.0, 1196.0, 128.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 16.0, 536.0, 99.0, 18.0 ],
					"style" : "",
					"text" : "BIT CHECK DELAY"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-77",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 574.0, 1165.0, 317.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 18.0, 505.0, 317.0, 24.0 ],
					"style" : "",
					"text" : "LSDJ MIDI OUT Mode Advanced Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-46",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 798.0, 1195.0, 50.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 242.0, 535.0, 50.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-45",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 674.0, 1195.0, 50.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 118.0, 535.0, 50.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-51",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1115.0, 1124.0, 140.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_bytedelaymulti"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-12",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 990.0, 1126.0, 115.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_bytedelay"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-14",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 798.0, 1125.0, 130.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_bitdelaymulti"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-44",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 674.0, 1126.0, 105.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_bitdelay"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-2",
					"maxclass" : "message",
					"numinlets" : 2,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 372.0, 1124.0, 117.0, 22.0 ],
					"style" : "",
					"text" : "240 105 71 127 247"
				}

			}
, 			{
				"box" : 				{
					"bgcolor" : [ 0.72549, 0.72549, 0.72549, 1.0 ],
					"bgcolor2" : [ 0.34902, 0.34902, 0.34902, 1.0 ],
					"bgfillcolor_angle" : 270.0,
					"bgfillcolor_autogradient" : 0.0,
					"bgfillcolor_color" : [ 0.290196, 0.309804, 0.301961, 1.0 ],
					"bgfillcolor_color1" : [ 0.72549, 0.72549, 0.72549, 1.0 ],
					"bgfillcolor_color2" : [ 0.34902, 0.34902, 0.34902, 1.0 ],
					"bgfillcolor_proportion" : 0.39,
					"bgfillcolor_type" : "gradient",
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"gradient" : 1,
					"id" : "obj-3",
					"maxclass" : "message",
					"numinlets" : 2,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 376.0, 1084.0, 138.0, 26.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 377.0, 466.0, 138.0, 26.0 ],
					"style" : "",
					"text" : "Restore Defaults",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-43",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 86.0, 1178.0, 43.0, 22.0 ],
					"style" : "",
					"text" : "s sout"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-18",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 93.0, 1115.0, 101.0, 22.0 ],
					"style" : "",
					"text" : "prepend 240 105"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-17",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 87.0, 1070.0, 97.0, 22.0 ],
					"style" : "",
					"text" : "append 127 247"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-7",
					"maxclass" : "message",
					"numinlets" : 2,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 925.0, 1119.0, 64.0, 22.0 ],
					"style" : "",
					"text" : "5"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-237",
					"linecount" : 2,
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 628.0, 271.0, 221.0, 33.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 11.0, 469.0, 355.0, 20.0 ],
					"style" : "",
					"text" : "trash80.loves.you.only.sometimes.love. 2010",
					"textcolor" : [ 0.682353, 0.682353, 0.682353, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"bgcolor" : [ 0.529412, 0.690196, 0.545098, 1.0 ],
					"bgcolor2" : [ 0.188235, 0.431373, 0.211765, 1.0 ],
					"bgfillcolor_angle" : 270.0,
					"bgfillcolor_autogradient" : 0.0,
					"bgfillcolor_color" : [ 0.290196, 0.309804, 0.301961, 1.0 ],
					"bgfillcolor_color1" : [ 0.529412, 0.690196, 0.545098, 1.0 ],
					"bgfillcolor_color2" : [ 0.188235, 0.431373, 0.211765, 1.0 ],
					"bgfillcolor_proportion" : 0.39,
					"bgfillcolor_type" : "gradient",
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"gradient" : 1,
					"id" : "obj-235",
					"linecount" : 2,
					"maxclass" : "message",
					"numinlets" : 2,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 928.0, 1042.0, 161.0, 44.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 518.0, 466.0, 180.0, 26.0 ],
					"style" : "",
					"text" : "Send & Save Changes",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"id" : "obj-234",
					"maxclass" : "button",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "bang" ],
					"patching_rect" : [ 360.0, 269.0, 20.0, 20.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-233",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 360.0, 313.0, 47.0, 22.0 ],
					"style" : "",
					"text" : "s reset"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 11.595187,
					"id" : "obj-214",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 834.0, 92.0, 133.0, 21.0 ],
					"style" : "",
					"text" : "prepend bgcolor 0.5 0 0"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-211",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 833.0, 54.0, 63.0, 22.0 ],
					"style" : "",
					"text" : "r statusint"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 11.595187,
					"id" : "obj-209",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patcher" : 					{
						"fileversion" : 1,
						"appversion" : 						{
							"major" : 7,
							"minor" : 2,
							"revision" : 1,
							"architecture" : "x86",
							"modernui" : 1
						}
,
						"rect" : [ 25.0, 47.0, 152.0, 172.0 ],
						"bglocked" : 0,
						"openinpresentation" : 0,
						"default_fontsize" : 10.0,
						"default_fontface" : 0,
						"default_fontname" : "Arial",
						"gridonopen" : 1,
						"gridsize" : [ 15.0, 15.0 ],
						"gridsnaponopen" : 1,
						"objectsnaponopen" : 1,
						"statusbarvisible" : 2,
						"toolbarvisible" : 1,
						"lefttoolbarpinned" : 0,
						"toptoolbarpinned" : 0,
						"righttoolbarpinned" : 0,
						"bottomtoolbarpinned" : 0,
						"toolbars_unpinned_last_save" : 0,
						"tallnewobj" : 0,
						"boxanimatetime" : 200,
						"enablehscroll" : 1,
						"enablevscroll" : 1,
						"devicewidth" : 0.0,
						"description" : "",
						"digest" : "",
						"tags" : "",
						"style" : "",
						"subpatcher_template" : "",
						"boxes" : [ 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 11.595187,
									"id" : "obj-47",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 32.0, 31.0, 68.0, 20.0 ],
									"style" : "",
									"text" : "loadmess 1"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 11.595187,
									"id" : "obj-45",
									"maxclass" : "newobj",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "bang" ],
									"patching_rect" : [ 32.0, 55.75, 54.0, 20.0 ],
									"style" : "",
									"text" : "metro 20"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 11.595187,
									"id" : "obj-44",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 32.0, 103.75, 83.0, 20.0 ],
									"style" : "",
									"text" : "prepend angle"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 11.595187,
									"id" : "obj-43",
									"maxclass" : "newobj",
									"numinlets" : 5,
									"numoutlets" : 4,
									"outlettype" : [ "int", "", "", "int" ],
									"patching_rect" : [ 32.0, 79.75, 79.0, 20.0 ],
									"style" : "",
									"text" : "counter 0 359"
								}

							}
, 							{
								"box" : 								{
									"comment" : "",
									"id" : "obj-51",
									"maxclass" : "outlet",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 32.0, 127.75, 25.0, 25.0 ],
									"style" : ""
								}

							}
 ],
						"lines" : [ 							{
								"patchline" : 								{
									"destination" : [ "obj-44", 0 ],
									"disabled" : 0,
									"hidden" : 0,
									"source" : [ "obj-43", 0 ]
								}

							}
, 							{
								"patchline" : 								{
									"destination" : [ "obj-51", 0 ],
									"disabled" : 0,
									"hidden" : 0,
									"source" : [ "obj-44", 0 ]
								}

							}
, 							{
								"patchline" : 								{
									"destination" : [ "obj-43", 0 ],
									"disabled" : 0,
									"hidden" : 0,
									"source" : [ "obj-45", 0 ]
								}

							}
, 							{
								"patchline" : 								{
									"destination" : [ "obj-45", 0 ],
									"disabled" : 0,
									"hidden" : 0,
									"source" : [ "obj-47", 0 ]
								}

							}
 ]
					}
,
					"patching_rect" : [ 1048.0, 117.0, 71.0, 21.0 ],
					"saved_object_attributes" : 					{
						"description" : "",
						"digest" : "",
						"fontsize" : 10.0,
						"globalpatchername" : "",
						"style" : "",
						"tags" : ""
					}
,
					"style" : "",
					"text" : "p automove"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-207",
					"maxclass" : "newobj",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 823.0, 199.0, 74.0, 22.0 ],
					"style" : "",
					"text" : "prepend set"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-206",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1072.0, 243.0, 216.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 548.0, 14.0, 137.0, 24.0 ],
					"style" : "",
					"text" : "Connected",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-205",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 823.0, 165.0, 50.0, 22.0 ],
					"style" : "",
					"text" : "r status"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-203",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 583.0, 226.0, 216.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 475.0, 14.0, 216.0, 24.0 ],
					"style" : "",
					"text" : "Status"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-202",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1188.0, 805.0, 79.0, 22.0 ],
					"style" : "",
					"text" : "r livemap_ch"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-198",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1146.0, 915.0, 139.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 422.0, 251.0, 139.0, 18.0 ],
					"style" : "",
					"text" : "Midi Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-199",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1146.0, 932.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 422.0, 268.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-200",
					"linecount" : 2,
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1144.0, 881.0, 225.0, 42.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 419.0, 220.0, 281.0, 24.0 ],
					"style" : "",
					"text" : "LSDJ LIVEMAP/SYNCMAP Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"angle" : 74.590027,
					"grad1" : [ 0.047059, 0.611765, 0.913725, 1.0 ],
					"grad2" : [ 0.047059, 0.698039, 0.913725, 1.0 ],
					"id" : "obj-201",
					"maxclass" : "panel",
					"mode" : 1,
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1132.0, 870.0, 279.0, 95.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 412.0, 210.0, 285.0, 94.0 ],
					"proportion" : 0.39,
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-72",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1298.0, 499.0, 67.0, 22.0 ],
					"style" : "",
					"text" : "r mgb_ch5"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-194",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1284.0, 478.0, 67.0, 22.0 ],
					"style" : "",
					"text" : "r mgb_ch4"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-195",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1271.0, 457.0, 67.0, 22.0 ],
					"style" : "",
					"text" : "r mgb_ch3"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-196",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1257.0, 436.0, 67.0, 22.0 ],
					"style" : "",
					"text" : "r mgb_ch2"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-197",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1244.0, 415.0, 67.0, 22.0 ],
					"style" : "",
					"text" : "r mgb_ch1"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-192",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1324.0, 674.0, 79.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 321.0, 251.0, 79.0, 18.0 ],
					"style" : "",
					"text" : "POLY Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-193",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1324.0, 691.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 321.0, 268.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-190",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1247.0, 674.0, 79.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 244.0, 251.0, 79.0, 18.0 ],
					"style" : "",
					"text" : "NOI Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-191",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1247.0, 691.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 244.0, 268.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-188",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1172.0, 674.0, 79.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 169.0, 251.0, 79.0, 18.0 ],
					"style" : "",
					"text" : "WAV Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-189",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1172.0, 691.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 169.0, 268.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-186",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1098.0, 675.0, 79.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 95.0, 252.0, 79.0, 18.0 ],
					"style" : "",
					"text" : "PU2 Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-187",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1098.0, 692.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 95.0, 269.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-182",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1024.0, 675.0, 79.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 21.0, 252.0, 79.0, 18.0 ],
					"style" : "",
					"text" : "PU1 Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-183",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 1024.0, 692.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 21.0, 269.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-184",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1022.0, 641.0, 225.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 19.0, 221.0, 225.0, 24.0 ],
					"style" : "",
					"text" : "mGB Midi Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"angle" : 74.590027,
					"grad1" : [ 0.047059, 0.611765, 0.913725, 1.0 ],
					"grad2" : [ 0.047059, 0.698039, 0.913725, 1.0 ],
					"id" : "obj-185",
					"maxclass" : "panel",
					"mode" : 1,
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 1010.0, 630.0, 402.0, 94.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 7.0, 210.0, 402.0, 94.0 ],
					"proportion" : 0.39,
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-172",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1035.0, 493.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn47"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-173",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1021.0, 471.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn46"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-174",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1007.0, 450.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn45"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-175",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 992.0, 429.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn44"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-176",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 980.0, 408.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn43"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-177",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 966.0, 387.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn42"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-178",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 953.0, 366.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn41"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-165",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 884.0, 493.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn37"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-166",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 869.0, 471.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn36"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-167",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 856.0, 450.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn35"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-168",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 842.0, 429.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn34"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-169",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 829.0, 408.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn33"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-170",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 815.0, 387.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn32"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-171",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 802.0, 366.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn31"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-158",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 740.0, 493.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn27"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-159",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 725.0, 471.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn26"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-160",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 712.0, 450.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn25"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-161",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 698.0, 429.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn24"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-162",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 685.0, 408.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn23"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-163",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 671.0, 387.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn22"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-164",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 658.0, 366.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn21"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-157",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 616.0, 494.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn17"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-141",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 601.0, 472.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn16"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-142",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 588.0, 451.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn15"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-143",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 574.0, 430.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn14"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-144",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 561.0, 409.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn13"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-145",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 547.0, 388.0, 95.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn12"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-42",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 534.0, 367.0, 94.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccn11"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-146",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 1002.0, 852.0, 88.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccs4"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-147",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 989.0, 831.0, 88.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccs3"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-148",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 975.0, 810.0, 88.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccs2"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-149",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 962.0, 789.0, 88.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccs1"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-150",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 549.0, 704.0, 92.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccm4"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-30",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 536.0, 683.0, 92.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccm3"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-31",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 522.0, 662.0, 92.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccm2"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-151",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 509.0, 641.0, 92.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_ccm1"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-152",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 117.0, 817.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_cch4"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-153",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 105.0, 796.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_cch3"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-27",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 90.0, 775.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_cch2"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-28",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 77.0, 754.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_cch1"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-24",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 76.0, 732.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_nch4"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-154",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 63.0, 710.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_nch3"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-155",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 49.0, 688.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_nch2"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-156",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 36.0, 666.0, 89.0, 22.0 ],
					"style" : "",
					"text" : "r midiout_nch1"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-117",
					"items" : [ 1, "CC", "with", "range", "0-6F", ",", 7, "CCs", "with", "range", "0-F" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 495.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 237.0, 427.0, 69.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-118",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 761.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 519.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-119",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 719.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 477.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-120",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 677.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 435.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-121",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 635.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 393.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-122",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 593.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 351.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-123",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 551.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 309.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-124",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 449.0, 871.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 194.0, 427.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-125",
					"items" : [ "Use", "Exact", "Value", ",", "Spread", "value", "from", 0, "to", 127 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 814.0, 871.0, 119.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 563.0, 427.0, 119.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-126",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 374.0, 871.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 121.0, 427.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-127",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 268.0, 872.0, 31.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 15.0, 428.0, 31.0, 18.0 ],
					"style" : "",
					"text" : "NOI"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-128",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 300.0, 871.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 48.0, 427.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-92",
					"items" : [ 1, "CC", "with", "range", "0-6F", ",", 7, "CCs", "with", "range", "0-F" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 496.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 237.0, 406.0, 69.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-93",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 762.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 519.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-94",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 720.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 477.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-95",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 678.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 435.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-96",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 636.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 393.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-97",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 594.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 351.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-98",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 552.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 309.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-99",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 450.0, 850.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 194.0, 406.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-100",
					"items" : [ "Use", "Exact", "Value", ",", "Spread", "value", "from", 0, "to", 127 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 815.0, 850.0, 119.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 563.0, 406.0, 119.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-101",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 375.0, 850.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 121.0, 406.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-102",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 269.0, 851.0, 31.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 16.0, 407.0, 31.0, 18.0 ],
					"style" : "",
					"text" : "WAV"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-103",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 301.0, 850.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 48.0, 406.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-79",
					"items" : [ 1, "CC", "with", "range", "0-6F", ",", 7, "CCs", "with", "range", "0-F" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 496.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 237.0, 385.0, 69.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-80",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 762.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 519.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-81",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 720.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 477.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-82",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 678.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 435.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-84",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 636.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 393.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-85",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 594.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 351.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-86",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 552.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 309.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-87",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 450.0, 829.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 194.0, 385.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-88",
					"items" : [ "Use", "Exact", "Value", ",", "Spread", "value", "from", 0, "to", 127 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 815.0, 829.0, 119.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 563.0, 385.0, 119.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-89",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 375.0, 829.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 121.0, 385.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-90",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 269.0, 830.0, 31.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 16.0, 386.0, 31.0, 18.0 ],
					"style" : "",
					"text" : "PU2"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-91",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 301.0, 829.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 48.0, 385.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-76",
					"items" : [ 1, "CC", "with", "range", "0-6F", ",", 7, "CCs", "with", "range", "0-F" ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 491.0, 776.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 237.0, 364.0, 69.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-75",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 495.0, 789.0, 53.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 242.0, 345.0, 53.0, 18.0 ],
					"style" : "",
					"text" : "CC Mode"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-74",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 817.0, 789.0, 73.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 565.0, 345.0, 73.0, 18.0 ],
					"style" : "",
					"text" : "CC SCALING"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-70",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 762.0, 808.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 519.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-71",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 763.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 520.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#6"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-68",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 720.0, 808.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 477.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-69",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 721.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 478.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#5"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-64",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 678.0, 808.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 435.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-65",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 679.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 436.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#4"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-66",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 636.0, 808.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 393.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-67",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 637.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 394.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#3"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-62",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 594.0, 808.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 351.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-63",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 595.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 352.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#2"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-60",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 458.0, 725.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 309.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-61",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 553.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 310.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#1"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-59",
					"maxclass" : "number",
					"maximum" : 127,
					"minimum" : 1,
					"numinlets" : 1,
					"numoutlets" : 2,
					"outlettype" : [ "", "bang" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 417.0, 725.0, 41.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 194.0, 364.0, 41.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-55",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 451.0, 789.0, 36.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 198.0, 345.0, 36.0, 18.0 ],
					"style" : "",
					"text" : "CC#0"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-56",
					"items" : [ "Use", "Exact", "Value", ",", "Spread", "value", "from", 0, "to", 127 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 815.0, 808.0, 119.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 563.0, 364.0, 119.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-54",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 373.0, 789.0, 71.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 120.0, 345.0, 71.0, 18.0 ],
					"style" : "",
					"text" : "CC MIDI CH"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-53",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 375.0, 808.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 121.0, 364.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-52",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 298.0, 789.0, 74.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 45.0, 345.0, 74.0, 18.0 ],
					"style" : "",
					"text" : "Note MIDI CH"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-49",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 269.0, 809.0, 31.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 16.0, 365.0, 31.0, 18.0 ],
					"style" : "",
					"text" : "PU1"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-50",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 301.0, 808.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 48.0, 364.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-47",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 269.0, 762.0, 251.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 19.0, 318.0, 251.0, 24.0 ],
					"style" : "",
					"text" : "LSDJ MIDI OUT Mode Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"angle" : 74.590027,
					"grad1" : [ 0.047059, 0.611765, 0.913725, 1.0 ],
					"grad2" : [ 0.047059, 0.698039, 0.913725, 1.0 ],
					"id" : "obj-48",
					"maxclass" : "panel",
					"mode" : 1,
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 257.0, 751.0, 692.0, 153.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 8.0, 307.0, 690.0, 156.0 ],
					"proportion" : 0.39,
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-41",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 239.0, 562.0, 84.0, 22.0 ],
					"style" : "",
					"text" : "r sync_midich"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-40",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 146.0, 439.0, 96.0, 22.0 ],
					"style" : "",
					"text" : "r master_midich"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-36",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 239.0, 653.0, 139.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 23.0, 155.0, 139.0, 18.0 ],
					"style" : "",
					"text" : "Midi Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-37",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 239.0, 670.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 97.0, 155.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-38",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 237.0, 619.0, 225.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 19.0, 123.0, 206.0, 24.0 ],
					"style" : "",
					"text" : "LSDJ Slave Mode Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"angle" : 74.590027,
					"grad1" : [ 0.047059, 0.611765, 0.913725, 1.0 ],
					"grad2" : [ 0.047059, 0.698039, 0.913725, 1.0 ],
					"id" : "obj-39",
					"maxclass" : "panel",
					"mode" : 1,
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 225.0, 608.0, 279.0, 95.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 7.0, 111.0, 228.0, 96.0 ],
					"proportion" : 0.39,
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-32",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 147.0, 502.0, 139.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 254.0, 155.0, 139.0, 18.0 ],
					"style" : "",
					"text" : "Midi Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-33",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 147.0, 519.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 328.0, 155.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-34",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 145.0, 468.0, 225.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 250.0, 123.0, 212.0, 24.0 ],
					"style" : "",
					"text" : "LSDJ Master Mode Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"angle" : 74.590027,
					"grad1" : [ 0.047059, 0.611765, 0.913725, 1.0 ],
					"grad2" : [ 0.047059, 0.698039, 0.913725, 1.0 ],
					"id" : "obj-35",
					"maxclass" : "panel",
					"mode" : 1,
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 133.0, 457.0, 279.0, 95.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 238.0, 111.0, 228.0, 96.0 ],
					"proportion" : 0.39,
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-29",
					"maxclass" : "newobj",
					"numinlets" : 60,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 82.0, 1003.0, 815.5, 22.0 ],
					"style" : "",
					"text" : "pack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-26",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 100.0, 312.0, 107.0, 22.0 ],
					"style" : "",
					"text" : "r kb_compatmode"
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-20",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 1,
					"outlettype" : [ "" ],
					"patching_rect" : [ 86.0, 291.0, 72.0, 22.0 ],
					"style" : "",
					"text" : "r kb_midich"
				}

			}
, 			{
				"box" : 				{
					"id" : "obj-25",
					"maxclass" : "toggle",
					"numinlets" : 1,
					"numoutlets" : 1,
					"outlettype" : [ "int" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 188.0, 404.0, 20.0, 20.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 610.0, 176.0, 20.0, 20.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-23",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 208.0, 405.0, 139.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 485.0, 178.0, 139.0, 18.0 ],
					"style" : "",
					"text" : "Compatability Mode"
				}

			}
, 			{
				"box" : 				{
					"fontface" : 1,
					"fontname" : "Arial",
					"fontsize" : 10.0,
					"id" : "obj-22",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 97.0, 387.0, 139.0, 18.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 485.0, 154.0, 139.0, 18.0 ],
					"style" : "",
					"text" : "Midi Channel"
				}

			}
, 			{
				"box" : 				{
					"allowdrag" : 0,
					"id" : "obj-21",
					"items" : [ 1, ",", 2, ",", 3, ",", 4, ",", 5, ",", 6, ",", 7, ",", 8, ",", 9, ",", 10, ",", 11, ",", 12, ",", 13, ",", 14, ",", 15, ",", 16 ],
					"maxclass" : "umenu",
					"numinlets" : 1,
					"numoutlets" : 3,
					"outlettype" : [ "int", "", "" ],
					"parameter_enable" : 0,
					"patching_rect" : [ 97.0, 404.0, 72.0, 22.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 559.0, 154.0, 72.0, 22.0 ],
					"style" : ""
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 16.0,
					"id" : "obj-19",
					"maxclass" : "comment",
					"numinlets" : 1,
					"numoutlets" : 0,
					"patching_rect" : [ 95.0, 353.0, 198.0, 24.0 ],
					"presentation" : 1,
					"presentation_rect" : [ 481.0, 122.0, 198.0, 24.0 ],
					"style" : "",
					"text" : "Keyboard Mode Settings",
					"textcolor" : [ 1.0, 1.0, 1.0, 1.0 ]
				}

			}
, 			{
				"box" : 				{
					"fontname" : "Arial",
					"fontsize" : 12.0,
					"id" : "obj-15",
					"maxclass" : "newobj",
					"numinlets" : 0,
					"numoutlets" : 0,
					"patcher" : 					{
						"fileversion" : 1,
						"appversion" : 						{
							"major" : 7,
							"minor" : 2,
							"revision" : 1,
							"architecture" : "x86",
							"modernui" : 1
						}
,
						"rect" : [ 169.0, 153.0, 1400.0, 794.0 ],
						"bglocked" : 0,
						"openinpresentation" : 0,
						"default_fontsize" : 12.0,
						"default_fontface" : 0,
						"default_fontname" : "Arial",
						"gridonopen" : 1,
						"gridsize" : [ 15.0, 15.0 ],
						"gridsnaponopen" : 1,
						"objectsnaponopen" : 1,
						"statusbarvisible" : 2,
						"toolbarvisible" : 1,
						"lefttoolbarpinned" : 0,
						"toptoolbarpinned" : 0,
						"righttoolbarpinned" : 0,
						"bottomtoolbarpinned" : 0,
						"toolbars_unpinned_last_save" : 0,
						"tallnewobj" : 0,
						"boxanimatetime" : 200,
						"enablehscroll" : 1,
						"enablevscroll" : 1,
						"devicewidth" : 0.0,
						"description" : "",
						"digest" : "",
						"tags" : "",
						"style" : "",
						"subpatcher_template" : "",
						"boxes" : [ 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-50",
									"maxclass" : "message",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 985.0, 531.0, 117.0, 22.0 ],
									"style" : "",
									"text" : "240 105 72 127 247"
								}

							}
, 							{
								"box" : 								{
									"id" : "obj-43",
									"maxclass" : "button",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "bang" ],
									"patching_rect" : [ 985.0, 497.0, 20.0, 20.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-8",
									"maxclass" : "newobj",
									"numinlets" : 0,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 1011.0, 368.0, 63.0, 22.0 ],
									"style" : "",
									"text" : "r statusint"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-2",
									"maxclass" : "newobj",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 1011.0, 411.0, 44.0, 22.0 ],
									"style" : "",
									"text" : "gate 1"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-51",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1465.0, 803.0, 142.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_bytedelaymulti"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-52",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1452.0, 782.0, 117.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_bytedelay"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-53",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1438.0, 761.0, 132.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_bitdelaymulti"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-54",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1425.0, 740.0, 107.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_bitdelay"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-49",
									"maxclass" : "number",
									"numinlets" : 1,
									"numoutlets" : 2,
									"outlettype" : [ "", "bang" ],
									"parameter_enable" : 0,
									"patching_rect" : [ 675.0, 908.0, 50.0, 22.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-45",
									"maxclass" : "number",
									"numinlets" : 1,
									"numoutlets" : 2,
									"outlettype" : [ "", "bang" ],
									"parameter_enable" : 0,
									"patching_rect" : [ 635.0, 936.0, 50.0, 22.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-46",
									"maxclass" : "number",
									"numinlets" : 1,
									"numoutlets" : 2,
									"outlettype" : [ "", "bang" ],
									"parameter_enable" : 0,
									"patching_rect" : [ 621.0, 854.0, 50.0, 22.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-47",
									"maxclass" : "number",
									"numinlets" : 1,
									"numoutlets" : 2,
									"outlettype" : [ "", "bang" ],
									"parameter_enable" : 0,
									"patching_rect" : [ 607.0, 879.0, 50.0, 22.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-233",
									"maxclass" : "newobj",
									"numinlets" : 0,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 227.0, 486.0, 45.0, 22.0 ],
									"style" : "",
									"text" : "r reset"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-126",
									"maxclass" : "message",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 760.0, 515.0, 131.0, 22.0 ],
									"style" : "",
									"text" : "240 105 66 1 3 69 247"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-121",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 760.0, 569.0, 43.0, 22.0 ],
									"style" : "",
									"text" : "s sout"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-123",
									"maxclass" : "newobj",
									"numinlets" : 4,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 761.0, 483.0, 199.0, 22.0 ],
									"style" : "",
									"text" : "if $i3 == 105 && $i4==65 then bang"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-120",
									"maxclass" : "message",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 270.0, 717.0, 32.5, 22.0 ],
									"style" : "",
									"text" : "1"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-119",
									"maxclass" : "message",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 347.0, 717.0, 32.5, 22.0 ],
									"style" : "",
									"text" : "0"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-118",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 400.0, 754.0, 65.0, 22.0 ],
									"style" : "",
									"text" : "s statusint"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-117",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 296.0, 759.0, 52.0, 22.0 ],
									"style" : "",
									"text" : "s status"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-116",
									"maxclass" : "message",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 238.0, 696.0, 83.0, 22.0 ],
									"style" : "",
									"text" : "Disconnected"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-115",
									"maxclass" : "message",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 335.0, 695.0, 69.0, 22.0 ],
									"style" : "",
									"text" : "Connected"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-114",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "" ],
									"patching_rect" : [ 335.0, 655.0, 106.0, 22.0 ],
									"style" : "",
									"text" : "if $i1>5 then bang"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-113",
									"maxclass" : "number",
									"numinlets" : 1,
									"numoutlets" : 2,
									"outlettype" : [ "", "bang" ],
									"parameter_enable" : 0,
									"patching_rect" : [ 335.0, 620.0, 50.0, 22.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"id" : "obj-112",
									"maxclass" : "button",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "bang" ],
									"patching_rect" : [ 334.0, 549.0, 20.0, 20.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"id" : "obj-111",
									"maxclass" : "toggle",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "int" ],
									"parameter_enable" : 0,
									"patching_rect" : [ 305.0, 482.0, 20.0, 20.0 ],
									"style" : ""
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-110",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 1,
									"outlettype" : [ "bang" ],
									"patching_rect" : [ 305.0, 456.0, 60.0, 22.0 ],
									"style" : "",
									"text" : "loadbang"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-109",
									"maxclass" : "newobj",
									"numinlets" : 2,
									"numoutlets" : 1,
									"outlettype" : [ "bang" ],
									"patching_rect" : [ 334.0, 521.0, 71.0, 22.0 ],
									"style" : "",
									"text" : "metro 1000"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-108",
									"maxclass" : "newobj",
									"numinlets" : 5,
									"numoutlets" : 4,
									"outlettype" : [ "int", "", "", "int" ],
									"patching_rect" : [ 334.0, 577.0, 114.0, 22.0 ],
									"style" : "",
									"text" : "counter 0 1 100000"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-202",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1404.0, 858.0, 81.0, 22.0 ],
									"style" : "",
									"text" : "s livemap_ch"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-93",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1329.0, 983.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn47"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-94",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1313.0, 961.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn46"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-95",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1300.0, 940.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn45"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-96",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1286.0, 919.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn44"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-97",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1273.0, 898.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn43"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-98",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1259.0, 877.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn42"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-99",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1246.0, 856.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn41"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-100",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1229.0, 834.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn37"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-101",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1215.0, 812.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn36"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-102",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1202.0, 791.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn35"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-103",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1188.0, 770.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn34"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-104",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect" : [ 1175.0, 749.0, 97.0, 22.0 ],
									"style" : "",
									"text" : "s midiout_ccn33"
								}

							}
, 							{
								"box" : 								{
									"fontname" : "Arial",
									"fontsize" : 12.0,
									"id" : "obj-105",
									"maxclass" : "newobj",
									"numinlets" : 1,
									"numoutlets" : 0,
									"patching_rect
Download .txt
gitextract_yht0xf5z/

├── Arduinoboy/
│   ├── Arduinoboy.ino
│   ├── Led_Functions.ino
│   ├── Memory_Functions.ino
│   ├── Mode.ino
│   ├── Mode_LSDJ_Keyboard.ino
│   ├── Mode_LSDJ_Map.ino
│   ├── Mode_LSDJ_MasterSync.ino
│   ├── Mode_LSDJ_Midiout.ino
│   ├── Mode_LSDJ_SlaveSync.ino
│   ├── Mode_MidiGb.ino
│   ├── Mode_Nanoloop.ino
│   ├── Mode_Programmer.ino
│   └── UsbMidi.ino
├── Changelog.md
├── Editor/
│   └── ArduinoBoyEditor-Midi.maxpat
├── LICENSE
├── README.md
└── platformio.ini
Condensed preview — 18 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (371K chars).
[
  {
    "path": "Arduinoboy/Arduinoboy.ino",
    "chars": 20855,
    "preview": "/***************************************************************************\n ******************************************"
  },
  {
    "path": "Arduinoboy/Led_Functions.ino",
    "chars": 8587,
    "preview": "\n /*\n   showSelectedMode1 turns off the last mode led, turns on the new mode led\n   and delays for a period of time to r"
  },
  {
    "path": "Arduinoboy/Memory_Functions.ino",
    "chars": 1147,
    "preview": "\nboolean checkMemory()\n{\n  byte chk;\n  #ifndef USE_DUE\n  for(int m=0;m<4;m++){\n    chk =  EEPROM.read(MEM_CHECK+m);\n    "
  },
  {
    "path": "Arduinoboy/Mode.ino",
    "chars": 4290,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_LSDJ_Keyboard.ino",
    "chars": 11427,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_LSDJ_Map.ino",
    "chars": 7177,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_LSDJ_MasterSync.ino",
    "chars": 5173,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_LSDJ_Midiout.ino",
    "chars": 7432,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_LSDJ_SlaveSync.ino",
    "chars": 9254,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_MidiGb.ino",
    "chars": 8746,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_Nanoloop.ino",
    "chars": 4501,
    "preview": "/**************************************************************************\n * Name:    Timothy Lamb                    "
  },
  {
    "path": "Arduinoboy/Mode_Programmer.ino",
    "chars": 5148,
    "preview": "void modeProgrammer()\n{\n  while(sysexProgrammingConnected || sysexProgrammingMode) {\n    checkProgrammerConnected();\n   "
  },
  {
    "path": "Arduinoboy/UsbMidi.ino",
    "chars": 2371,
    "preview": "\n#ifndef USE_TEENSY\nvoid usbMidiSendTwoByteMessage(uint8_t b1, uint8_t b2) {};\nvoid usbMidiSendThreeByteMessage(uint8_t "
  },
  {
    "path": "Changelog.md",
    "chars": 6758,
    "preview": "## Changelog\n\n### 05/19/20\n* Arduinoboy to version 1.3.4\n* Added support for Arduino Mega 2560 and Arduino UNO Wifi\n\n###"
  },
  {
    "path": "Editor/ArduinoBoyEditor-Midi.maxpat",
    "chars": 168076,
    "preview": "{\n\t\"patcher\" : \t{\n\t\t\"fileversion\" : 1,\n\t\t\"appversion\" : \t\t{\n\t\t\t\"major\" : 7,\n\t\t\t\"minor\" : 2,\n\t\t\t\"revision\" : 1,\n\t\t\t\"archi"
  },
  {
    "path": "LICENSE",
    "chars": 18047,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
  },
  {
    "path": "README.md",
    "chars": 9174,
    "preview": "# Arduinoboy\nOfficial ArduinoBoy Repository for serial MIDI communication to the Nintendo Gameboy.\n\n![ScreenShot](http:/"
  },
  {
    "path": "platformio.ini",
    "chars": 612,
    "preview": "#\n# Project Configuration File\n#\n# A detailed documentation with the EXAMPLES is located here:\n# http://docs.platformio."
  }
]

About this extraction

This page contains the full source code of the trash80/Arduinoboy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 18 files (291.8 KB), approximately 105.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!