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 #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 #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 #include #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 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 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>= 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;xwrite(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" : [ 1161.0, 728.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn32" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-106", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1148.0, 707.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn31" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-86", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1134.0, 984.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn27" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-87", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1121.0, 962.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn26" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-88", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1107.0, 941.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn25" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-89", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1094.0, 920.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn24" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-90", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1080.0, 899.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn23" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-91", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1067.0, 878.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn22" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-92", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1053.0, 857.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn21" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-85", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1040.0, 835.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn17" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-72", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1391.0, 832.0, 69.0, 22.0 ], "style" : "", "text" : "s mgb_ch5" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-74", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1377.0, 811.0, 69.0, 22.0 ], "style" : "", "text" : "s mgb_ch4" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-77", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1364.0, 790.0, 69.0, 22.0 ], "style" : "", "text" : "s mgb_ch3" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-83", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1350.0, 769.0, 69.0, 22.0 ], "style" : "", "text" : "s mgb_ch2" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-84", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1337.0, 748.0, 69.0, 22.0 ], "style" : "", "text" : "s mgb_ch1" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-37", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1026.0, 813.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn16" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-38", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1013.0, 792.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn15" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-39", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 999.0, 771.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn14" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-40", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 986.0, 750.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn13" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-41", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 972.0, 729.0, 97.0, 22.0 ], "style" : "", "text" : "s midiout_ccn12" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-42", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 959.0, 708.0, 96.0, 22.0 ], "style" : "", "text" : "s midiout_ccn11" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-33", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 945.0, 947.0, 90.0, 22.0 ], "style" : "", "text" : "s midiout_ccs4" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-34", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 932.0, 926.0, 90.0, 22.0 ], "style" : "", "text" : "s midiout_ccs3" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-35", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 918.0, 905.0, 90.0, 22.0 ], "style" : "", "text" : "s midiout_ccs2" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-36", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 905.0, 884.0, 90.0, 22.0 ], "style" : "", "text" : "s midiout_ccs1" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-29", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 891.0, 863.0, 94.0, 22.0 ], "style" : "", "text" : "s midiout_ccm4" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-30", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 878.0, 842.0, 94.0, 22.0 ], "style" : "", "text" : "s midiout_ccm3" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-31", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 864.0, 821.0, 94.0, 22.0 ], "style" : "", "text" : "s midiout_ccm2" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-32", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 851.0, 800.0, 94.0, 22.0 ], "style" : "", "text" : "s midiout_ccm1" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-25", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 837.0, 773.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_cch4" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-26", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 824.0, 752.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_cch3" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-27", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 810.0, 731.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_cch2" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-28", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 797.0, 710.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_cch1" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-24", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 783.0, 923.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_nch4" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 770.0, 901.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_nch3" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-22", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 756.0, 879.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_nch2" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-21", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 743.0, 857.0, 91.0, 22.0 ], "style" : "", "text" : "s midiout_nch1" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-16", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 542.0, 793.0, 49.0, 22.0 ], "style" : "", "text" : "s mnull" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-17", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 730.0, 832.0, 96.0, 22.0 ], "style" : "", "text" : "s kb_midich2ins" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-19", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 716.0, 810.0, 109.0, 22.0 ], "style" : "", "text" : "s kb_compatmode" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-20", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 702.0, 789.0, 74.0, 22.0 ], "style" : "", "text" : "s kb_midich" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 689.0, 768.0, 98.0, 22.0 ], "style" : "", "text" : "s master_midich" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-15", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 675.0, 747.0, 86.0, 22.0 ], "style" : "", "text" : "s sync_midich" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-10", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 648.0, 726.0, 83.0, 22.0 ], "style" : "", "text" : "s force_mode" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-11", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 662.0, 705.0, 50.0, 22.0 ], "style" : "", "text" : "s mode" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-9", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 621.0, 833.0, 65.0, 22.0 ], "style" : "", "text" : "s version2" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-4", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 608.0, 812.0, 65.0, 22.0 ], "style" : "", "text" : "s version1" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-7", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 435.0, 590.0, 61.0, 22.0 ], "style" : "", "text" : "r syspack" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-5", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 540.0, 643.0, 1372.0, 22.0 ], "style" : "", "text" : "0 240 105 65" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-3", "maxclass" : "newobj", "numinlets" : 4, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 498.0, 615.0, 199.0, 22.0 ], "style" : "", "text" : "if $i3 == 105 && $i4==64 then bang" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-1", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 69, "outlettype" : [ "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int", "int" ], "patching_rect" : [ 540.0, 680.0, 937.0, 22.0 ], "style" : "", "text" : "unpack 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 0 0 0 0 0 0 0 0 0" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-82", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 432.0, 550.0, 43.0, 22.0 ], "style" : "", "text" : "s sout" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-81", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 432.0, 523.0, 131.0, 22.0 ], "style" : "", "text" : "240 105 64 1 3 67 247" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-80", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 432.0, 447.0, 61.0, 22.0 ], "style" : "", "text" : "r syspack" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-79", "maxclass" : "newobj", "numinlets" : 6, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 432.0, 483.0, 325.0, 22.0 ], "style" : "", "text" : "if $i3 == 105 && $i4==127 && $i5==1 && $i6==3 then bang" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-78", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 239.0, 337.0, 34.0, 22.0 ], "style" : "", "text" : "gate" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-76", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 240.0, 415.0, 63.0, 22.0 ], "style" : "", "text" : "s syspack" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-75", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 260.0, 214.0, 33.0, 22.0 ], "style" : "", "text" : "r sin" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-73", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 124.0, 302.0, 113.0, 22.0 ], "style" : "", "text" : "if $i1==0 then bang" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-71", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 371.0, 368.0, 32.5, 22.0 ], "style" : "", "text" : "0" } } , { "box" : { "id" : "obj-69", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "patching_rect" : [ 205.0, 335.0, 20.0, 20.0 ], "style" : "" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-67", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 124.0, 264.0, 81.0, 22.0 ], "style" : "", "text" : "r sysexstatus" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-65", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 340.0, 259.0, 98.0, 22.0 ], "style" : "", "text" : "prepend append" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-63", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 240.0, 369.0, 32.5, 22.0 ], "style" : "", "text" : "0" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-58", "linecount" : 2, "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 260.0, 292.0, 55.0, 35.0 ], "style" : "", "text" : "append 247" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-18", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 51.0, 206.0, 83.0, 22.0 ], "style" : "", "text" : "s sysexstatus" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-14", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 76.0, 170.0, 113.0, 22.0 ], "style" : "", "text" : "if $i1 == 247 then 0" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-12", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 50.0, 100.0, 33.0, 22.0 ], "style" : "", "text" : "r sin" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-6", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 51.0, 149.0, 113.0, 22.0 ], "style" : "", "text" : "if $i1 == 240 then 1" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-10", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 8 ] } } , { "patchline" : { "destination" : [ "obj-100", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 51 ] } } , { "patchline" : { "destination" : [ "obj-101", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 50 ] } } , { "patchline" : { "destination" : [ "obj-102", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 49 ] } } , { "patchline" : { "destination" : [ "obj-103", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 48 ] } } , { "patchline" : { "destination" : [ "obj-104", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 47 ] } } , { "patchline" : { "destination" : [ "obj-105", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 46 ] } } , { "patchline" : { "destination" : [ "obj-106", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 45 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 9 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 11 ] } } , { "patchline" : { "destination" : [ "obj-15", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 10 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 7 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 4 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 3 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 2 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 1 ] } } , { "patchline" : { "destination" : [ "obj-16", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 14 ] } } , { "patchline" : { "destination" : [ "obj-19", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 13 ] } } , { "patchline" : { "destination" : [ "obj-20", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 12 ] } } , { "patchline" : { "destination" : [ "obj-202", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 64 ] } } , { "patchline" : { "destination" : [ "obj-21", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 15 ] } } , { "patchline" : { "destination" : [ "obj-22", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 16 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 17 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 18 ] } } , { "patchline" : { "destination" : [ "obj-25", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 22 ] } } , { "patchline" : { "destination" : [ "obj-26", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 21 ] } } , { "patchline" : { "destination" : [ "obj-27", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 20 ] } } , { "patchline" : { "destination" : [ "obj-28", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 19 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 26 ] } } , { "patchline" : { "destination" : [ "obj-30", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 25 ] } } , { "patchline" : { "destination" : [ "obj-31", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 24 ] } } , { "patchline" : { "destination" : [ "obj-32", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 23 ] } } , { "patchline" : { "destination" : [ "obj-33", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 30 ] } } , { "patchline" : { "destination" : [ "obj-34", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 29 ] } } , { "patchline" : { "destination" : [ "obj-35", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 28 ] } } , { "patchline" : { "destination" : [ "obj-36", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 27 ] } } , { "patchline" : { "destination" : [ "obj-37", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 36 ] } } , { "patchline" : { "destination" : [ "obj-38", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 35 ] } } , { "patchline" : { "destination" : [ "obj-39", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 34 ] } } , { "patchline" : { "destination" : [ "obj-4", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 5 ] } } , { "patchline" : { "destination" : [ "obj-40", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 33 ] } } , { "patchline" : { "destination" : [ "obj-41", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 32 ] } } , { "patchline" : { "destination" : [ "obj-42", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 31 ] } } , { "patchline" : { "destination" : [ "obj-45", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 7 ] } } , { "patchline" : { "destination" : [ "obj-46", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 6 ] } } , { "patchline" : { "destination" : [ "obj-47", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 5 ] } } , { "patchline" : { "destination" : [ "obj-49", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 10 ] } } , { "patchline" : { "destination" : [ "obj-51", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 68 ] } } , { "patchline" : { "destination" : [ "obj-52", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 67 ] } } , { "patchline" : { "destination" : [ "obj-53", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 66 ] } } , { "patchline" : { "destination" : [ "obj-54", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 65 ] } } , { "patchline" : { "destination" : [ "obj-72", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 63 ] } } , { "patchline" : { "destination" : [ "obj-74", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 62 ] } } , { "patchline" : { "destination" : [ "obj-77", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 61 ] } } , { "patchline" : { "destination" : [ "obj-83", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 60 ] } } , { "patchline" : { "destination" : [ "obj-84", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 59 ] } } , { "patchline" : { "destination" : [ "obj-85", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 37 ] } } , { "patchline" : { "destination" : [ "obj-86", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 44 ] } } , { "patchline" : { "destination" : [ "obj-87", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 43 ] } } , { "patchline" : { "destination" : [ "obj-88", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 42 ] } } , { "patchline" : { "destination" : [ "obj-89", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 41 ] } } , { "patchline" : { "destination" : [ "obj-9", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 6 ] } } , { "patchline" : { "destination" : [ "obj-90", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 40 ] } } , { "patchline" : { "destination" : [ "obj-91", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 39 ] } } , { "patchline" : { "destination" : [ "obj-92", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 38 ] } } , { "patchline" : { "destination" : [ "obj-93", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 58 ] } } , { "patchline" : { "destination" : [ "obj-94", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 57 ] } } , { "patchline" : { "destination" : [ "obj-95", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 56 ] } } , { "patchline" : { "destination" : [ "obj-96", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 55 ] } } , { "patchline" : { "destination" : [ "obj-97", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 54 ] } } , { "patchline" : { "destination" : [ "obj-98", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 53 ] } } , { "patchline" : { "destination" : [ "obj-99", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-1", 52 ] } } , { "patchline" : { "destination" : [ "obj-113", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-108", 0 ] } } , { "patchline" : { "destination" : [ "obj-112", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-109", 0 ] } } , { "patchline" : { "destination" : [ "obj-111", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-110", 0 ] } } , { "patchline" : { "destination" : [ "obj-116", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-110", 0 ] } } , { "patchline" : { "destination" : [ "obj-120", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-110", 0 ] } } , { "patchline" : { "destination" : [ "obj-109", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-111", 0 ] } } , { "patchline" : { "destination" : [ "obj-108", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-112", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-112", 0 ] } } , { "patchline" : { "destination" : [ "obj-114", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-113", 0 ] } } , { "patchline" : { "destination" : [ "obj-116", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-114", 0 ] } } , { "patchline" : { "destination" : [ "obj-120", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-114", 0 ] } } , { "patchline" : { "destination" : [ "obj-117", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-115", 0 ] } } , { "patchline" : { "destination" : [ "obj-117", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-116", 0 ] } } , { "patchline" : { "destination" : [ "obj-118", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-119", 0 ] } } , { "patchline" : { "destination" : [ "obj-14", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-6", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-118", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-120", 0 ] } } , { "patchline" : { "destination" : [ "obj-126", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-123", 0 ] } } , { "patchline" : { "destination" : [ "obj-115", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-126", 0 ] } } , { "patchline" : { "destination" : [ "obj-119", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-126", 0 ] } } , { "patchline" : { "destination" : [ "obj-121", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-126", 0 ] } } , { "patchline" : { "destination" : [ "obj-18", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-43", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-116", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-233", 0 ] } } , { "patchline" : { "destination" : [ "obj-120", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-233", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-50", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-43", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-121", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-50", 0 ] } } , { "patchline" : { "destination" : [ "obj-78", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-58", 0 ] } } , { "patchline" : { "destination" : [ "obj-18", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-71", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-63", 0 ] } } , { "patchline" : { "destination" : [ "obj-76", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-63", 0 ] } } , { "patchline" : { "destination" : [ "obj-58", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-65", 0 ] } } , { "patchline" : { "destination" : [ "obj-73", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-67", 0 ] } } , { "patchline" : { "destination" : [ "obj-78", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-67", 0 ] } } , { "patchline" : { "destination" : [ "obj-63", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-69", 0 ] } } , { "patchline" : { "destination" : [ "obj-3", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-5", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-63", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-71", 0 ] } } , { "patchline" : { "destination" : [ "obj-69", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-73", 0 ] } } , { "patchline" : { "destination" : [ "obj-58", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-75", 0 ] } } , { "patchline" : { "destination" : [ "obj-65", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-75", 0 ] } } , { "patchline" : { "destination" : [ "obj-63", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-78", 0 ] } } , { "patchline" : { "destination" : [ "obj-108", 3 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-79", 0 ] } } , { "patchline" : { "destination" : [ "obj-81", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-79", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-123", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-80", 0 ] } } , { "patchline" : { "destination" : [ "obj-79", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-80", 0 ] } } , { "patchline" : { "destination" : [ "obj-82", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-81", 0 ] } } ] } , "patching_rect" : [ 92.0, 245.0, 51.0, 22.0 ], "saved_object_attributes" : { "description" : "", "digest" : "", "globalpatchername" : "", "style" : "", "tags" : "" } , "style" : "", "text" : "p sysex" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-83", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 305.0, 151.0, 41.0, 22.0 ], "style" : "", "text" : "r sout" } } , { "box" : { "fontname" : "Arial", "fontsize" : 12.0, "id" : "obj-11", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 116.0, 217.0, 35.0, 22.0 ], "style" : "", "text" : "s sin" } } , { "box" : { "angle" : 74.590027, "grad1" : [ 0.047059, 0.611765, 0.913725, 1.0 ], "grad2" : [ 0.047059, 0.698039, 0.913725, 1.0 ], "id" : "obj-16", "maxclass" : "panel", "mode" : 1, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 83.0, 342.0, 279.0, 95.0 ], "presentation" : 1, "presentation_rect" : [ 469.0, 111.0, 228.0, 96.0 ], "proportion" : 0.39, "style" : "" } } , { "box" : { "angle" : 270.0, "bgcolor" : [ 0.5, 0, 0, 0 ], "border" : 2, "bordercolor" : [ 0.501961, 0.501961, 0.501961, 0.0 ], "id" : "obj-213", "maxclass" : "panel", "mode" : 0, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1012.0, 228.0, 187.0, 107.0 ], "presentation" : 1, "presentation_rect" : [ 532.0, 10.0, 166.0, 31.0 ], "proportion" : 0.39, "style" : "" } } , { "box" : { "angle" : 260.0, "border" : 2, "bordercolor" : [ 0.501961, 0.501961, 0.501961, 0.0 ], "grad1" : [ 0.403922, 0.701961, 0.109804, 1.0 ], "grad2" : [ 0.521569, 0.866667, 0.0, 1.0 ], "id" : "obj-210", "maxclass" : "panel", "mode" : 1, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 1060.0, 232.0, 187.0, 107.0 ], "presentation" : 1, "presentation_rect" : [ 532.0, 10.0, 166.0, 31.0 ], "proportion" : 0.39, "style" : "" } } , { "box" : { "angle" : 74.590027, "grad1" : [ 0.517647, 0.517647, 0.517647, 1.0 ], "grad2" : [ 0.376471, 0.376471, 0.376471, 1.0 ], "id" : "obj-104", "maxclass" : "panel", "mode" : 1, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 558.0, 1152.0, 695.0, 152.0 ], "presentation" : 1, "presentation_rect" : [ 8.0, 492.0, 689.0, 117.0 ], "proportion" : 0.39, "style" : "" } } , { "box" : { "angle" : 74.590027, "grad1" : [ 1.0, 0.8, 0.0, 1.0 ], "grad2" : [ 1.0, 0.701961, 0.0, 1.0 ], "id" : "obj-179", "maxclass" : "panel", "mode" : 1, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 272.0, 766.0, 692.0, 153.0 ], "presentation" : 1, "presentation_rect" : [ 357.0, 50.0, 340.0, 58.0 ], "proportion" : 0.39, "style" : "" } } , { "box" : { "angle" : 74.590027, "grad1" : [ 1.0, 0.8, 0.0, 1.0 ], "grad2" : [ 1.0, 0.701961, 0.0, 1.0 ], "id" : "obj-217", "maxclass" : "panel", "mode" : 1, "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 287.0, 781.0, 692.0, 153.0 ], "presentation" : 1, "presentation_rect" : [ 8.0, 50.0, 346.0, 58.0 ], "proportion" : 0.39, "style" : "" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-29", 20 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-100", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 12 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-101", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 8 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-103", 0 ] } } , { "patchline" : { "destination" : [ "obj-78", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-107", 0 ] } } , { "patchline" : { "destination" : [ "obj-116", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-108", 0 ] } } , { "patchline" : { "destination" : [ "obj-134", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-108", 0 ] } } , { "patchline" : { "destination" : [ "obj-234", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-111", 1 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-111", 1 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-115", 0 ] } } , { "patchline" : { "destination" : [ "obj-111", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-116", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 17 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-117", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 49 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-118", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 48 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-119", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 47 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-120", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 46 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-121", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 45 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-122", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 44 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-123", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 43 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-124", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 21 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-125", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 13 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-126", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 9 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-128", 0 ] } } , { "patchline" : { "destination" : [ "obj-135", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-134", 0 ] } } , { "patchline" : { "destination" : [ "obj-234", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-135", 1 ] } } , { "patchline" : { "destination" : [ "obj-6", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-135", 1 ] } } , { "patchline" : { "destination" : [ "obj-108", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-136", 0 ] } } , { "patchline" : { "destination" : [ "obj-46", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-68", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-141", 0 ] } } , { "patchline" : { "destination" : [ "obj-64", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-142", 0 ] } } , { "patchline" : { "destination" : [ "obj-66", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-143", 0 ] } } , { "patchline" : { "destination" : [ "obj-62", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-144", 0 ] } } , { "patchline" : { "destination" : [ "obj-60", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-145", 0 ] } } , { "patchline" : { "destination" : [ "obj-125", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-146", 0 ] } } , { "patchline" : { "destination" : [ "obj-100", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-147", 0 ] } } , { "patchline" : { "destination" : [ "obj-88", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-148", 0 ] } } , { "patchline" : { "destination" : [ "obj-56", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-149", 0 ] } } , { "patchline" : { "destination" : [ "obj-117", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-150", 0 ] } } , { "patchline" : { "destination" : [ "obj-76", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-151", 0 ] } } , { "patchline" : { "destination" : [ "obj-126", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-152", 0 ] } } , { "patchline" : { "destination" : [ "obj-101", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-153", 0 ] } } , { "patchline" : { "destination" : [ "obj-103", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-154", 0 ] } } , { "patchline" : { "destination" : [ "obj-91", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-155", 0 ] } } , { "patchline" : { "destination" : [ "obj-50", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-156", 0 ] } } , { "patchline" : { "destination" : [ "obj-70", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-157", 0 ] } } , { "patchline" : { "destination" : [ "obj-80", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-158", 0 ] } } , { "patchline" : { "destination" : [ "obj-81", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-159", 0 ] } } , { "patchline" : { "destination" : [ "obj-82", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-160", 0 ] } } , { "patchline" : { "destination" : [ "obj-84", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-161", 0 ] } } , { "patchline" : { "destination" : [ "obj-85", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-162", 0 ] } } , { "patchline" : { "destination" : [ "obj-86", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-163", 0 ] } } , { "patchline" : { "destination" : [ "obj-87", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-164", 0 ] } } , { "patchline" : { "destination" : [ "obj-93", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-165", 0 ] } } , { "patchline" : { "destination" : [ "obj-94", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-166", 0 ] } } , { "patchline" : { "destination" : [ "obj-95", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-167", 0 ] } } , { "patchline" : { "destination" : [ "obj-96", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-168", 0 ] } } , { "patchline" : { "destination" : [ "obj-97", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-169", 0 ] } } , { "patchline" : { "destination" : [ "obj-18", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-17", 0 ] } } , { "patchline" : { "destination" : [ "obj-98", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-170", 0 ] } } , { "patchline" : { "destination" : [ "obj-99", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-171", 0 ] } } , { "patchline" : { "destination" : [ "obj-118", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-172", 0 ] } } , { "patchline" : { "destination" : [ "obj-119", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-173", 0 ] } } , { "patchline" : { "destination" : [ "obj-120", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-174", 0 ] } } , { "patchline" : { "destination" : [ "obj-121", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-175", 0 ] } } , { "patchline" : { "destination" : [ "obj-122", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-176", 0 ] } } , { "patchline" : { "destination" : [ "obj-123", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-177", 0 ] } } , { "patchline" : { "destination" : [ "obj-124", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-178", 0 ] } } , { "patchline" : { "destination" : [ "obj-43", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 50 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-183", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 51 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-187", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 52 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-189", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 53 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-191", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 54 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-193", 0 ] } } , { "patchline" : { "destination" : [ "obj-191", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-194", 0 ] } } , { "patchline" : { "destination" : [ "obj-189", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-195", 0 ] } } , { "patchline" : { "destination" : [ "obj-187", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-196", 0 ] } } , { "patchline" : { "destination" : [ "obj-183", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-197", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 55 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-199", 0 ] } } , { "patchline" : { "destination" : [ "obj-43", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-21", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-20", 0 ] } } , { "patchline" : { "destination" : [ "obj-199", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-202", 0 ] } } , { "patchline" : { "destination" : [ "obj-207", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-205", 0 ] } } , { "patchline" : { "destination" : [ "obj-206", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-207", 0 ] } } , { "patchline" : { "destination" : [ "obj-210", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-209", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 3 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-21", 0 ] } } , { "patchline" : { "destination" : [ "obj-214", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-211", 0 ] } } , { "patchline" : { "destination" : [ "obj-213", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-214", 0 ] } } , { "patchline" : { "destination" : [ "obj-233", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-234", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-235", 0 ] } } , { "patchline" : { "destination" : [ "obj-128", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-24", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 4 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-25", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-26", 0 ] } } , { "patchline" : { "destination" : [ "obj-89", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-53", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-28", 0 ] } } , { "patchline" : { "destination" : [ "obj-115", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-92", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-30", 0 ] } } , { "patchline" : { "destination" : [ "obj-79", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-31", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 2 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-33", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-37", 0 ] } } , { "patchline" : { "destination" : [ "obj-33", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-40", 0 ] } } , { "patchline" : { "destination" : [ "obj-37", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-41", 0 ] } } , { "patchline" : { "destination" : [ "obj-59", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-42", 0 ] } } , { "patchline" : { "destination" : [ "obj-45", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-44", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 56 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-45", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 57 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-46", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 6 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-50", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 10 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-53", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 18 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-56", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 22 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-59", 0 ] } } , { "patchline" : { "destination" : [ "obj-11", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-6", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 23 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-60", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 24 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-62", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 26 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-64", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 25 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-66", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 27 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-68", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 28 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-70", 0 ] } } , { "patchline" : { "destination" : [ "obj-193", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-72", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 14 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-76", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 1 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-78", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 15 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-79", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 35 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-80", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 34 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-81", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 33 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-82", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-83", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 32 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-84", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 31 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-85", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 30 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-86", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 29 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-87", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 19 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-88", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 11 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-89", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 7 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-91", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 16 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-92", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 42 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-93", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 41 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-94", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 40 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-95", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 39 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-96", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 38 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-97", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 37 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-98", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 36 ], "disabled" : 0, "hidden" : 0, "source" : [ "obj-99", 0 ] } } ], "dependency_cache" : [ ], "autosave" : 0 } } ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {description} Copyright (C) {year} {fullname} 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. {signature of Ty Coon}, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ================================================ FILE: README.md ================================================ # Arduinoboy Official ArduinoBoy Repository for serial MIDI communication to the Nintendo Gameboy. ![ScreenShot](http://trash80.net/arduinoboy/aboy1_2_0.jpg) ## About Arduinoboy is software for the [Arduino hardware platform](http://arduino.cc) that allows serial communication (MIDI) to the Nintendo Gameboy for music applications such as [LittleSoundDJ](http://littlesounddj.com), [Nanoloop.](http://www.nanoloop.com/), and [mGB](https://github.com/trash80/mGB) ## Current Features * Affordable and easily accessible parts for assembly. * Accurate MIDI Sync, Start and Stop commands. * Push Button selector sets the sync/state modes [(7 modes available)](#modes-details) * [mGB](https://github.com/trash80/mGB) Mode: Full MIDI in support across all Gameboy Channels, including a unique "poly" mode allows you to play your Game Boy like a synthesizer. * Midi Out Doubles as a Midi Thru * "Filtering" data for only sync messages, no dedicated MIDI line required. * Can be powered by the Game Boy's gamelink port. * USB upgradeable via Arduino. * Midi settings configurable using a Mac/PC editor built in Max. * Tested and works with DMG (Original), Gameboy Color, and Advance/SP. ## Modes Details #### Mode 1 - LSDJ as MIDI Slave Sync Slave your Game Boy running [LittleSoundDJ](http://littlesounddj.com) to your midi sequencer or Digital audio workstation. You can send the arduinoboy midi notes to change sync resolution and start/stop the LSDJ sequencer. _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 Higher note values than these map LSDJ song position row offset on a Song Start. In LSDJ the `sync` mode should be set to `Slave` #### Mode 2 LSDJ as MIDI Master Sync. Send Midi sync with LSDJ as a midi clock master, LSDJ also sends a Midi Note on message that corresponds to the song row number on play. In LSDJ the `sync` mode should be set to `Master` #### Mode 3 LSDJ PC Keyboard mode. This mode emulates the [PC Keyboard Mode](http://littlesounddj.wikia.com/wiki/PC_Keyboard_Interface) built into LSDJ, allowing you to control the following aspects of LSDJ: Features: * The first octave controls M-U-T-E, * Cursor control (LSDJ Live mode only), * Table selection * Table cue. _PC Keyboard mode midi note map_ * 36 - `C-1` Mute Pu1 Off/On * 37 - `C#1` Mute Pu2 Off/On * 38 - `D-1` Mute Wav Off/On * 39 - `D#1` Mute Noi Off/On * 40 - `E-1` Livemode Cue Sequence * 41 - `F-1` Livemode Cursor Up * 42 - `F#1` Livemode Cursor Down * 43 - `G-1` Livemode Cursor Left * 44 - `G#1` Live mode Cursor Right * 45 - `A-1` Table Up * 46 - `A#1` Table Down * 47 - `B-1` Cue Table * 48+ - Notes from this note up will accept midi in from an external keyboard or sequencer and allow you to play the notes`C-2 to C-8`. * Midi Program Change messages will select from instrument table * Default Midi channel is 16. You can set this in the top of the main source file in the archive, or via the [Max Pat editor](#max). In LSDJ the `sync` mode should be set to `Keyboard` #### Mode 4 MIDI to Nanoloop sync Sync [Nanoloop.](http://www.nanoloop.com/) to external midi clock signals sent to the midi in. In Nanoloop, the sync mode should be set to `slave`. #### Mode 5 Full MIDI with mGB [mGB](https://github.com/trash80/mGB) is a Gameboy cartridge program (You need a Flash Cart and Transfer hardware) That enables the Gameboy to act as a MIDI supported sound module that allows full control of the Game Boy sound hardware. It works with the old DMG Gameboy as well as GBC/GBA. #### Mode 6 LSDJ MIDIMAP Lsdj will sync to incoming MIDI sync, and incoming MIDI notes are mapped to LSDJ's song row #. The currently selected row's MIDI note is displayed on the top right of the LSDJ screen, and incoming MIDI notes will also display the relative song row number in the same location. In LSDJ the `sync` mode should be set to `MI.MAP`. *This requires a special version of LSDJ, which can be found in your account on the [LSDJ website](http://littlesounddj.com/lsd/latest/full_version/).* #### Mode 7 LSDJ MIDIOUT Each of the 4 gameboy channels send MIDI data on 4 midi channels by the use of effects commands: * `Nxx` - Sends a MIDI Note - Absolute to the value placed in the effect. N00 sends note off, `N01`-`N6F` send midi notes 1 to 112. * `Qxx` - Sends a [MIDI Note](http://www.electronics.dit.ie/staff/tscarff/Music_technology/midi/midi_note_numbers_for_octaves.htm) 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. * `Xxx` - 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. * `Yxx` - Sends a program/patch/preset change. By default each channel of LSDJ is mapped to midi channels 1-4. For example note commands from PU1 will be sent to midi channel 1. In LSDJ the `sync` mode should be set to `Midiout`. *This requires a special version of LSDJ, which can be found in your account on the [LSDJ website](http://littlesounddj.com/lsd/latest/full_version/).* ## Max Editor ![Editor gui](Editor/editor.png) [The Arduinoboy Editor for Max](https://github.com/trash80/Arduinoboy/tree/master/Editor) for PC/OSX machines is a gui editor that allows you to edit the various global midi settings of your arduinoboy without editing or flashing code, over midi. It used to required the now deprecated Max Runtime, but you can also run it using a demo of [Cycling '74's Max application](https://cycling74.com/downloads/) ### Maxpat Settings * `Midi In/Out` Connect your arduinoboy to these ports on your system. Once it has connected, all the lights on your arduinoboy should flash in order, and the editor will show a green `Connected`. * `Mode` Setting this will tell your arduinoboy what mode to boot into automatically. This is handy if you built your own arduinoboy and decided you wanted to skimp out on LEDs and a button. * `LSDJ Slave Mode settings` - The midi channel LSDJ slave mode will receive its commands on. * `LSDJ Master Mode settings` - The midi channel LSDJ Master mode will send its midi notes mapped to row number on. * `Keyboard Mode settings` - What channel LSDJ will look for its keyboard mode midi commands. No idea what compatibility mode does. * `mGB midi settings` - Map each incoming midi channel to a specific Gameboy channel in mGB. * `LSDJ Livesync/Livemap settings` - The midi channel Livesync/Livemap will listen to incoming midi commands from. * `LSDJ Midiout settings` - Here you can set the following: * `Note midi channel` - The channel each LSDJ channel will send it's midi note commands on. * `CC midi channel` - The channel each LSDJ channel will send it's Continuous Controller commands on. * `CC 0` - The initial CC each channel will send. The type of data it will send is based on the next setting. * `CC Mode` - Game Boys have limitations! You can either have arduinoboy send one CC with many values, or 7 with limited 8bit values. 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. * `CC Scaling ` - Set wether the 7 CCs are scaled or unscaled. ## Future Features & wishlist * Build instructions, and a Arduino Shield ## How To build an Arduinoboy ![ScreenShot](http://farm3.static.flickr.com/2229/2316803721_c22f9c2387.jpg) ![ScreenShot](http://trash80.net/arduinoboy/arduinoboy_schematic_1_1_0.png) * [Build Photos](http://flickr.com/photos/trash80/2316803175/in/set-72157604068871573/) * [Old version (Pre 1.1.0)](http://trash80.net/junkfood/arduinoboy/arduinoboy-schem-v.0.9.8-r1.png) ### Video Demos * [Keyboard Mode Test](http://youtube.com/watch?v=TnLUuvc78XY) * [Sync Demos](http://youtube.com/watch?v=iVmhy-Lo7BI) * [Arduino inside of Gameboy DMG](http://youtube.com/watch?v=VwrMuOA0VnY) * [mGB Example & Arduinoboy build into a DMG](http://vimeo.com/1853931) * [PDF explores mGB with a MIDI guitar](http://www.youtube.com/watch?v=HAU9MzZ2qeE) ## Thanks To * [Arduino](http://arduino.cc) * [Nitro2k01](http://blog.gg8.se/wordpress/) for ASM help with mGB * [GWEM](http://www.preromanbritain.com/gwem/lsdj_midi/g33k.html) g33k page * [Midines](http://wayfar.net) Thanks for the help x|k! * [firestARTer](http://www.firestarter-music.de) help with keyboard & Midi handling information. * [Gijs Gieskes](http://gieskes.nl) Found source code that gave insight into Nanoloop sync * [Little Sound DJ](http://littlesounddj.com) * [http://devrs.com/gb](http://devrs.com/gb) Madcatz PC link port for gb serial specs * [http://chipmusic.org](http://chipmusic.org) For all things Chipmusic. ================================================ FILE: platformio.ini ================================================ # # Project Configuration File # # A detailed documentation with the EXAMPLES is located here: # http://docs.platformio.org/en/latest/projectconf.html # # A sign `#` at the beginning of the line indicates a comment # Comment lines are ignored. # Simple and base environment # [env:mybaseenv] # platform = %INSTALLED_PLATFORM_NAME_HERE% # framework = # board = # # Automatic targets - enable auto-uploading # targets = upload [platformio] src_dir = Arduinoboy [env:teensy31] platform = teensy framework = arduino board = teensy31 targets = upload build_flags = -UUSB_SERIAL -DUSB_MIDI board_f_cpu = 24000000L