/*
MIDI Programmer early version of software
by rich deangelis 2021
*/
extern char* __brkval;
int freeMemory() {
char top;
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
}
#include <LiquidCrystal.h>
// pins, top row RS R/W ENt d0 d1 d2 d3 d4 d5 d6 d7
//LiquidCrystal lcdtop(49, 46, 47, 44, 45, 42, 43, 40, 41, 38, 39);
// pins, botm row RS R/W ENt d0 d1 d2 d3 d4 d5 d6 d7
//LiquidCrystal lcdbot(49, 46, 51, 44, 45, 42, 43, 40, 41, 38, 39);
LiquidCrystal lcdtop(12, 11, 10, 9, 8, 7);
LiquidCrystal lcdbot = lcdtop;
// ************************************************************* Define custom characters
//character 0
byte Separator[8] = {
B01110,
B01110,
B01110,
B01110,
B01110,
B01110,
B01110,
B01110,
};
//character 1
byte ArrowUp[8] = {
B00100,
B01110,
B01110,
B11111,
B00100,
B00100,
B00100,
B00100,
};
//character 2
byte ArrowDown[8] = {
B00100,
B00100,
B00100,
B00100,
B11111,
B01110,
B01110,
B00100,
};
//character 3
byte BigDown[8] = {
B11111,
B11111,
B11111,
B11111,
B01110,
B01110,
B00100,
B00100,
};
//character 4
byte Note[8] = {
B00010,
B00010,
B00010,
B00010,
B01110,
B11110,
B01100,
B00000,
};
//character 5
byte Anti1[8] = {
B11111,
B11011,
B10011,
B11011,
B11011,
B11011,
B10001,
B11111,
};
//character 6
byte Anti2[8] = {
B11111,
B10001,
B01110,
B11101,
B11011,
B10111,
B00000,
B11111,
};
//character 7
byte Hbar[8] = {
B01010,
B10101,
B01010,
B00100,
B00100,
B01010,
B10101,
B01010,
};
// **************************************************************************************************************** System Variables
int x = 0; //for whatev.
boolean Redraw = true; //when true, an LED/LCD redraw is done at the start of loop. Initial run will draw it.
boolean Shift = false; //set true when shift button (#0)is held down
boolean EncLeft = false; //For LEFT Encoder: set true to enable 2nd parameter, default 0 is 1st parameter
boolean EncRight = false; //For RIGHT Encoder: set true to enable 4th parameter, default 0 is 3rd parameter
byte byteRead = 0; //something to put in characters read from serial inputs
byte byteAgentFirst = 0; //holds 1st byte from an agent transmission
byte byteAgentSecond = 0; //holds 2nd byte from an agent transmission
int NewUserInput = 0; //bit flags for Agent Reception, bit 0 set when 1st byte received, bit 1 set when 2nd byte received
byte LEDS[40]; //holds the image of all LEDs on the various panels. 0=off, 1=on 3=slow flash, 5=fast flash
byte Ones = '0';
byte Tens = '0';
int Page = 0; //Page numbers 0...n determine the LCD screen shown and the parameters it shows
//Page 0 SYSTEM, has synth select, unit select, channel select (for any synth)
//for DW 6000:
//Page 1 OSC screen 1 has octave1,2, waveform1,2
//Page 2 OSC screen 2 has level1,2, interval, and detune
//Page 3 VCF screen 1 has cutoff, VCF env.int., resonance, tracking
//Page 4 VCF screen 2 has attack, decay, slope, release
//Page 5 VCF screen 3 has breakpoint, sustain, VCF env.polarity
//Page 6 AMP screen 1 has attack, decay, slope, release
//Page 7 AMP screen 2 has breakpoint, sustain
//Page 8 MOD screen 1 has MG frequency, MG delay, MG to OSC, MG to VCF
//Page 9 MOD screen 2 has bend to pitch, bend to filter
//Page 10 EFX screen 1 has noise, Chorus, portamento
//for DW 8000:
//Page 11 OSC screen 1 has octave1,2, waveform1,2
//Page 12 OSC screen 2 has level1,2, interval, and detune
//Page 13 OSC screen 3 has autobend intensity, OSC1/2 select, time, direction(mode)
//Page 14 VCF screen 1 has cutoff, VCF env.int., resonance, tracking
//Page 15 VCF screen 2 has attack, decay, slope, release
//Page 16 VCF screen 3 has breakpoint, sustain, VCF env.polarity, velocity sensitivity
//Page 17 AMP screen 1 has attack, decay, slope, release
//Page 18 AMP screen 2 has breakpoint, sustain, velocity sensitivity
//Page 19 MOD screen 1 has LFO frequency, LFO delay, LFO to OSC, LFO to VCF
//Page 20 MOD screen 2 has LFO waveform, touch to pitch, touch to filter, touch to VCA
//Page 21 EFX screen 1 has delay time, delay fine, feedback, FX level
//Page 22 EFX screen 2 has fx mod frequency, fx mod intensity
//Page 23 EFX screen 3 has bend to OSC, Bend to VCF, portamento time, noise level
//Page 24 GLO screen 1 has nothing (yet), for any synth
//int MaxPage = 24; //this should match that up there ^
// ************************************************************ System Parameters to be saved in NV memory
int SysUnitID = 0; //default Synth Unit #
int SysSynthName = 1; //Identifies the synth, 1 = "Korg DW-6000"
// 2 = "Korg DW-8000"
// 3 = "Korg Poly800"
int SysMIDIChannel = 0; //default MIDI channel for TX and RX. User sees 1-16 but it's 0-15.
// ************************************************************* Synth Parameters to be Tx/Rx for Korg DW6000
byte PDW6_Assign = 0; //Assign Mode [0-2] bits 5-4 of param 0
byte PDW6_BendOsc = 2; //Bend Osc [0-12] bits 3-0 of param 0
byte PDW6_PortTime = 15; //Portamento Time [0-31] param 1
byte PDW6_Osc1Level = 21; //Osc 1 Level [0-31] param 2
byte PDW6_Osc2Level = 22; //Osc 2 Level [0-31] param 3
byte PDW6_NoiseLevel = 1; //Noise Level [0-31] param 4
byte PDW6_Cutoff = 33; //Cutoff [0-63] param 5
byte PDW6_Resonance = 6; //Resonance [0-31] param 6
byte PDW6_VCFEGIntensity = 16; //VCF EG Intensity [0-31] param 7
byte PDW6_FAttack = 0; //VCF EG Attack [0-31] param 8
byte PDW6_FDecay = 10; //VCF EG Decay [0-31] param 9
byte PDW6_FBreakpoint = 15; //VCF EG Breakpoint [0-31] param 10
byte PDW6_FSlope = 10; //VCF EG Slope [0-31] param 11
byte PDW6_FSustain = 29; //VCF EG Sustain [0-31] param 12
byte PDW6_FRelease = 9; //VCF EG Release [0-31] param 13
byte PDW6_AAtack = 0; //VCA EG Attack [0-31] param 14
byte PDW6_ADecay = 3; //VCA EG Decay [0-31] param 15
byte PDW6_ABreakpoint = 25; //VCA EG Breakpoint [0-31] param 16
byte PDW6_ASlope = 17; //VCA EG Slope [0-31] param 17
byte PDW6_BendVCF = 0; //Bend VCF [0,1] bit 5 of param 18
byte PDW6_ASustain = 28; //VCA EG Sustain [0-31] bits 4-0 of param 18
byte PDW6_Osc1Octave = 0; //Osc 1 Octave [0-2] bits 6-5 of param 19
byte PDW6_ARelease = 5; //VCA EG Release [0-31] bits 4-0 of param 19
byte PDW6_Osc2Octave = 1; //Osc 2 Octave [0-2] bits 6-5 of param 20
byte PDW6_MGFrequency = 12; //MG Frequency [0-31] bits 4-0 of param 20
byte PDW6_KeyTracking = 1; //Keyboard Tracking [0-2] bits 6-5 of param 21
byte PDW6_MGDelay = 11; //MG Delay [0-31] bits 4-0 of param 21
byte PDW6_Polarity = 0; //Polarity [0,1] bit 5 of param 22
byte PDW6_MG2Osc = 3; //MG to Osc [0-31] bits 4-0 of param 22
byte PDW6_Chorus = 1; //Chorus [0,1] bit 5 of param 23
byte PDW6_MG2VCF = 0; //MG to VCF [0-31] bits 4-0 of param 24
byte PDW6_Osc1Waveform = 2; //Osc 1 Waveform [0-7] 5-3 of param 24
byte PDW6_Osc2Waveform = 1; //Osc 2 Waveform [0-7] 2-0 of param 24
byte PDW6_Interval = 0; //Osc 2 Interval [0-4] bits 5-3 of param 25
byte PDW6_Detune = 2; //Osc 2 Detune [0-6] bits 2-0 of param 25
// ************************************************************* Synth Parameters to be Tx/Rx for Korg DW6000
byte PDW8_x = 0; //
//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
// SETUP
//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
void setup() {
Serial.begin(115200);
Serial.println("Boot");
//Serial0: not used
//Serial1: The Primary MIDI In/Out
Serial1.begin(31250); //MIDI rate
//Serial2: Agent Button/LED processor
Serial2.begin(38400); //agent jumper-set rate
//Serial3: Secondary MIDI In/Out
Serial3.begin(31250); //MIDI rate
// Initialize Agent processors
Serial2.write(0xFE); //reset Agents
delay(500); //was 3000 with only 4 processors, works with 7000 and 16 agents.
Serial2.write(0xAE); //enumerate Agents
Serial2.write(0xAF);
//read and toss out agent responses
while (Serial2.available()) {
byteRead = Serial2.read();
delay(10);
}
//************************************************************************* Initial LCD Screen
// set up the top LCD
lcdtop.begin(40, 2);
lcdtop.clear();
lcdtop.noCursor();
lcdtop.noBlink();
lcdtop.noAutoscroll();
lcdtop.leftToRight();
// set up the bot(tom) LCD
lcdbot.begin(40, 2);
lcdbot.clear();
lcdbot.noCursor();
lcdbot.noBlink();
lcdbot.noAutoscroll();
lcdbot.leftToRight();
// Print a message to the LCD first row.
lcdtop.print("Angelis Electronics Presents ");
// Print a message to the LCD 2nd row.
lcdtop.setCursor(0, 1);
lcdtop.print(" A New Technology in ");
// Print a message to the LCD 3rd row.
lcdbot.print(" Vintage Synth Programming ");
// Print a message to the LCD 4th row.
lcdbot.setCursor(0, 1);
lcdbot.print(" <applause and cheers> ");
lcdbot.write(byte(0)); //custom character 0
lcdbot.write(byte(1)); //custom character 1
lcdbot.write(byte(2)); //custom character 2
lcdbot.write(byte(3)); //custom character 3
lcdbot.write(byte(4)); //custom character 4
lcdbot.write(byte(5)); //custom character 5
lcdbot.write(byte(6)); //custom character 6
lcdbot.write(byte(7)); //custom character 7
//load up custom characters
lcdtop.createChar(0,Separator);
lcdbot.createChar(0,Separator);
lcdtop.createChar(1,ArrowUp);
lcdbot.createChar(1,ArrowUp);
lcdtop.createChar(2,ArrowDown);
lcdbot.createChar(2,ArrowDown);
lcdtop.createChar(3,BigDown);
lcdbot.createChar(3,BigDown);
lcdtop.createChar(4,Note);
lcdbot.createChar(4,Note);
lcdtop.createChar(5,Anti1);
lcdbot.createChar(5,Anti1);
lcdtop.createChar(6,Anti2);
lcdbot.createChar(6,Anti2);
lcdtop.createChar(7,Hbar);
lcdbot.createChar(7,Hbar);
delay(1000); //give human beings time to see this intro screen
// ********************************************************************************* Initialize our LED array
for (x = 0 ; x < 40 ; x++ ) {
LEDS[x] = 0; //assign all leds as off in our array
}
//LED cycle test
for ( x = 0 ; x < 24 ; x++ ) {
SetLED(x+40); //turn on an LED writing directly to agent
delay(64); //hold LED state for 1/16 second
SetLED(x); //turn it off again
}
}
//end of setup chunk
// LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
// MAIN LOOP
// LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
void loop() {
// ********************************************************************************************** Print the LCD
if (Redraw) {
UpdateAllLEDS(); //send entirely new LED array to Agent
RedrawScreen(); //clear and redraw all basic characters, variable fields are written with _
FillLCDRow1(); //fills in variable data for top row with current values
FillLCDRow2(); //fills in variable data for second row with current values
FillLCDRow3(); //fills in variable data for third row with current values
//got it upt to screen 5 and 1/2 of 6 without blowing up, try ? ...
Serial.print("Page: ");
ConvertToChars(Page);
Serial.print((char) Tens);
Serial.print((char) Ones);
Serial.print(" (");
Serial.print(freeMemory());
Serial.println(" free)");
FillLCDRow4a(); //fills in variable data for bottom row with what's current values
FillLCDRow4b(); //fills in variable data for bottom row with what's current values
FillLCDRow4c(); //fills in variable data for bottom row with what's current values
FillLCDRow4d(); //fills in variable data for bottom row with what's current values
Page = ((Page + 1) % 24);
// Redraw = false; //done,so don't do it again until necessary.
}
// *********************************************************************************************** READ AGENT, RESPOND TO BUTTONS
//read serial data from Agent processor, store into AgentByteFirst & AgentByteSecond and set flags.
if (Serial2.available()) {
// read the most recent byte from Agent
byteRead = Serial2.read();
if (byteRead == 0xE0) { // first message byte is always E0 from board #0
byteAgentFirst = byteRead;
NewUserInput = 0b01; //set 1st bit to flag byte 1 arrived but not 2nd.
//after first byte, do nothing until 2nd byte arrives.
}
if (byteRead <= 0x5F) {// second message byte is switch or encoder event code
byteAgentSecond = byteRead;
NewUserInput = (0b10 | NewUserInput); //sets 2nd bit to flag 2nd byte arrived.
}
}
if (NewUserInput == 0b11) {
//we have a button event!
//ClickAgents();
DoButtonPress(byteAgentSecond); //call to handle button & encoder events
NewUserInput = 0; //clears flags to indicate no button events
Redraw = true; //possible changes requires a screen update
}
delay(25); //just 1/40 second delay
} //end of loop chunk
// SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
// subroutines!
// SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
//convert input to Ones and Tens for LCD ***************************************************** ConvertToChars
//this takes the input and converts to two global bytes as characters "Ones" and "Tens" for direct display.
//the highest value is 63 so the tens only calculate to a '6'.
void ConvertToChars(int input) {
Ones = '0' + (input % 10);
Tens = (input / 10) % 10;
Tens = Tens == 0 ? ' ' : '0' + Tens;
}
// **************************************************************************************************************** ButtonPress()
void DoButtonPress(byte RxByte) {
// ******************************************************************************* Encoder routines
if (RxByte == 64) { //encoder 1 left turn event
x=0;
}
if (RxByte == 65) { //encoder 2 left turn event
x=0;
}
if (RxByte == 80) { //encoder 1 right turn event
x=0;
}
if (RxByte == 81) { //encoder 2 right turn event
x=0;
}
// ******************************************************************************* Pilot Button routines
if (RxByte == 0) { //button 0 press SHIFT BUTTON
Shift = true;
LEDS[0] = 1; //turn on red led
}
if (RxByte == 1) { //button 1 press SYS BUTTON
if (Shift==false) {
Page = 0;
PageLEDSDark();
LEDS[1] = 1; //turn on red led
}
}
if (RxByte == 2) { //button 2 press OSC BUTTON
if (Shift==false) {
if (Page == 1) {
Page = 2;
PageLEDSDark();
LEDS[10] = 1; //turn on green led
}
else {
Page = 1;
PageLEDSDark();
LEDS[2] = 1; //turn on red led
}
}
}
if (RxByte == 3) { //button 3 press FIL BUTTON
if (Shift==false) {
switch (Page) {
case 3:
Page = 4;
PageLEDSDark();
LEDS[11] = 1; //turn on green led
break;
case 4:
Page = 5;
PageLEDSDark();
LEDS[3] = 1; //turn on red led
LEDS[11] = 1; //turn on green led
break;
default:
Page = 3;
PageLEDSDark();
LEDS[3] = 1; //turn on red led
}
}
}
if (RxByte == 4) { //button 4 press AMP BUTTON
if (Shift==false) {
if (Page == 6) {
Page = 7;
PageLEDSDark();
LEDS[12] = 1; //turn on green led
}
else {
Page = 6;
PageLEDSDark();
LEDS[4] = 1; //turn on red led
}
}
}
if (RxByte == 5) { //button 5 press MOD BUTTON
if (Shift==false) {
if (Page == 8) {
Page = 9;
PageLEDSDark();
LEDS[13] = 1; //turn on green led
}
else {
Page = 8;
PageLEDSDark();
LEDS[5] = 1; //turn on red led
}
}
}
if (RxByte == 6) { //button 6 press BUS+FX BUTTON
if (Shift==false) {
Page = 10;
PageLEDSDark();
LEDS[6] = 1; //turn on red led
}
}
if (RxByte == 7) { //button 7 press GLOBAL BUTTON
if (Shift==false) {
Page =24;
PageLEDSDark();
LEDS[7] = 1; //turn on red led
}
}
// ******************************************************************************* Enigma Button routines
if (RxByte == 8) { //button 8 (left encoder) press
if (EncLeft) { //toggle state of left encoder cursor
EncLeft=false;
LEDS[17] = 0; //turn off green led
LEDS[16] = 1; //turn on green led
}
else {
EncLeft=true;
LEDS[16] = 0; //turn off green led
LEDS[17] = 1; //turn on green led
}
}
if (RxByte == 9) { //button 9 (right encoder) press
if (EncRight) { //toggle state of right encoder cursor
EncRight=false;
LEDS[22] = 0; //turn off green led
LEDS[21] = 1; //turn on green led
}
else {
EncRight=true;
LEDS[21] = 0; //turn off green led
LEDS[22] = 1; //turn on green led
}
}
if (RxByte == 10) { //button 10 press ENC LEFT MINIMIZE
x=0;
}
if (RxByte == 11) { //button 11 press ENC LEFT MAXIMIZE
x=0;
}
if (RxByte == 12) { //button 12 press <<unused>>
x=0;
}
if (RxByte == 13) { //button 13 press <<unused>>
x=0;
}
if (RxByte == 14) { //button 14 press ENC RIGHT MINIMIZE
x=0;
}
if (RxByte == 15) { //button 15 press ENC RIGHT MAXIMIZE
x=0;
}
// ************************************************************************ Pilot release buttons
if (RxByte == 32) { //RELEASE SHIFT (button 0)
Shift = false;
LEDS[0] = 0; //turn off red led
}
if (RxByte == 33) { //RELEASE 1
}
if (RxByte == 34) { //RELEASE 2
}
if (RxByte == 35) { //RELEASE 3
}
if (RxByte == 36) { //RELEASE 4
}
if (RxByte == 37) { //RELEASE 5
}
if (RxByte == 38) { //RELEASE 6
}
if (RxByte == 39) { //RELEASE 7
}
// ************************************************************************ Enigma release buttons
if (RxByte == 40) { //RELEASE 8 (encoder left)
}
if (RxByte == 41) { //RELEASE 9 (encoder right)
}
if (RxByte == 42) { //RELEASE 10
}
if (RxByte == 43) { //RELEASE 11
}
if (RxByte == 44) { //RELEASE 12
}
if (RxByte == 45) { //RELEASE 13
}
if (RxByte == 46) { //RELEASE 14
}
if (RxByte == 47) { //RELEASE 15
}
}
// ***************************************************************************************************************** UpdateAllLEDS()
//This writes our array to the Agent
void UpdateAllLEDS() {
int y = 0;
// the &1 is used to mask for bit 0 of the LED[] array value, ignoring bits 1,2 that indicate flashing
y = (LEDS[0]&1) + ((LEDS[1]&1)*2) + ((LEDS[2]&1)*4) + ((LEDS[3]&1)*8) + ((LEDS[4]&1)*16) + ((LEDS[5]&1)*32) + ((LEDS[6]&1)*64) + ((LEDS[7]&1)*128);
Serial2.write(176); //command for board #0
Serial2.write(208+0); //LED group 0 command
Serial2.write(byte(y)); //assembled bits for Red LEDs on Pilot board
y = (LEDS[8]&1) + ((LEDS[9]&1)*2) + ((LEDS[10]&1)*4) + ((LEDS[11]&1)*8) + ((LEDS[12]&1)*16) + ((LEDS[13]&1)*32) + ((LEDS[14]&1)*64) + ((LEDS[15]&1)*128);
Serial2.write(176); //command for board #0
Serial2.write(208+1); //LED group 1 command
Serial2.write(byte(y)); //assembled bits for Green LEDs on Pilot board
y = (LEDS[16]&1) + ((LEDS[17]&1)*2) + ((LEDS[18]&1)*4) + ((LEDS[20]&1)*16) + ((LEDS[21]&1)*32) + ((LEDS[22]&1)*64);
Serial2.write(176); //command for board #0
Serial2.write(208+2); //LED group 2 command
Serial2.write(byte(y)); //assembled bits for Green LEDs on Enigma board
}
// ********************************************************************************************************************* PageLEDSDark()
// the pilot page LEDs are all red & green LEDs except for #0,8 over the shift button which are not used.
// This turns all the page leds off in our LED array so it can later be written with new settings.
void PageLEDSDark() { // turn off all the pilot page LEDs
//notice led 0 is left out
LEDS[1] = 0; //red...
LEDS[2] = 0;
LEDS[3] = 0;
LEDS[4] = 0;
LEDS[5] = 0;
LEDS[6] = 0;
LEDS[7] = 0;
//notice led 8 is left out
LEDS[9] = 0; //green ...
LEDS[10] = 0;
LEDS[11] = 0;
LEDS[12] = 0;
LEDS[13] = 0;
LEDS[14] = 0;
LEDS[15] = 0;
}
// *************************************************************************************************************** SetLED()
//This directly controls the Agent, does not alter our LED array.
void SetLED(int number) {
Serial2.write(176); //command for one LED on board #0
Serial2.write(number); //command to address the particular LED by number
}
// ************************************************************************************************************* LEDSDark()
//This directly controls the Agent, does not alter our LED array.
void LEDSDark() {
Serial2.write(176); //command for board #0
Serial2.write(192); //command to turn off every LED
}
// ********************************************************************************************************** ClickAgents()
void ClickAgents() {
Serial2.write(0xCC);
}
// ********************************************************************************************************** RedrawScreen()
void RedrawScreen() {
//makes the basic user screen with empty fields to be written in later.
lcdtop.clear();
lcdbot.clear();
// Print a message to the LCD first row.
lcdtop.print("Unit__ "); //has variable fields a2,b12,c2 for unit#,synth name,channel
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(4)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.print(" ____________ ");
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(4)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.write(byte(7)); //custom horiz-bar character
lcdtop.print(" Chan__");
// Print a message to the LCD 2nd row.
lcdtop.setCursor(0, 1);
lcdtop.print("_________"); //has variable fields d9,e9,f9,g9 for parameter labels (4 of them)
lcdtop.write(byte(0)); //custom separator character
lcdtop.print("_________");
lcdtop.write(byte(0)); //custom separator character
lcdtop.write(byte(0)); //custom separator character
lcdtop.print("_________");
lcdtop.write(byte(0)); //custom separator character
lcdtop.print("_________");
// Print a message to the LCD 3rd row.
lcdbot.print(" _ "); //has variable fields h1,i1.j1,k1 for cursor characters (on or off)
lcdbot.write(byte(0)); //custom separator character
lcdbot.print(" _ ");
lcdbot.write(byte(0)); //custom separator character
lcdbot.write(byte(0)); //custom separator character
lcdbot.print(" _ ");
lcdbot.write(byte(0)); //custom separator character
lcdbot.print(" _ ");
// Print a message to the LCD 4th row.
lcdbot.setCursor(0, 1);
lcdbot.print("_________"); //has variable fields l9,m9,n9,o9 for parameter values (4 of them)
lcdbot.write(byte(0)); //custom separator character
lcdbot.print("_________");
lcdbot.write(byte(0)); //custom separator character
lcdbot.write(byte(0)); //custom separator character
lcdbot.print("_________");
lcdbot.write(byte(0)); //custom separator character
lcdbot.print("_________");
}
// ****************************************************************************************************************** FillLCDRow1()
void FillLCDRow1() {
lcdtop.setCursor(4,0); //position for field a2, a 2 digit unit number 00-99
if (SysUnitID<10) {
lcdtop.print(" ");
}
lcdtop.print(SysUnitID);
lcdtop.setCursor(14,0); //position for field b12, a 12 character name of the synth being programmed
switch (SysSynthName) {
case 1:
lcdtop.print("Korg DW-6000");
break;
case 2:
lcdtop.print("Korg DW-8000");
break;
case 3:
lcdtop.print("Korg Poly800");
break;
case 4:
lcdtop.print("Yamaha FB-01");
break;
case 5:
lcdtop.print("Yamaha TX802");
break;
case 6:
lcdtop.print("Yamaha DX7II");
break;
case 7:
lcdtop.print(" Kawai K3m ");
break;
case 8:
lcdtop.print(" Siel DK-80 ");
break;
case 9:
lcdtop.print(" ADA MQ-1 ");
break;
case 10:
lcdtop.print("Antares ATR1");
break;
case 11:
lcdtop.print("Behr.DSP1000");
break;
case 12:
lcdtop.print("Ensoniq DP|4");
break;
default:
lcdtop.print("????????????");
}
lcdtop.setCursor(38,0); //position for field c2, a 2 digit midi channel number, with no leading zero, shifted from [0-15] to [1-16]
if (SysMIDIChannel<9) {
lcdtop.print(" ");
}
lcdtop.print(SysMIDIChannel+1); //we display 0-15 as 1-16
}
// ********************************************************************************************************************** FillLCDRow2()
void FillLCDRow2() {
lcdtop.setCursor(0,1); //position for field d9, a 9 character parameter label (left encoder position 1)
switch (Page) {
case 0:
lcdtop.print(" Unit # "); //for system page 0
break;
case 1:
lcdtop.print("Octave-1 "); //for DW6000
break;
case 2:
lcdtop.print(" Level-1 ");
break;
case 3:
lcdtop.print(" Cutoff ");
break;
case 4:
lcdtop.print("F-Attack ");
break;
case 5:
lcdtop.print("F-Breakpt");
break;
case 6:
lcdtop.print("A-Attack ");
break;
case 7:
lcdtop.print("A-Breakpt");
break;
case 8:
lcdtop.print("LFO-Freq ");
break;
case 9:
lcdtop.print("Bend->Osc");
break;
case 10:
lcdtop.print("Noise-Lev");
break;
case 11:
lcdtop.print("Octave-1 "); //for DW8000
break;
case 12:
lcdtop.print(" Level-1 ");
break;
case 13:
lcdtop.print("ABend-Int");
break;
case 14:
lcdtop.print(" Cutoff ");
break;
case 15:
lcdtop.print("F-Attack ");
break;
case 16:
lcdtop.print("F-Breakpt");
break;
case 17:
lcdtop.print("A-Attack ");
break;
case 18:
lcdtop.print("A-Breakpt");
break;
case 19:
lcdtop.print("LFO-Freq ");
break;
case 20:
lcdtop.print("LFO-Wavfm");
break;
case 21:
lcdtop.print("Dly-Range");
break;
case 22:
lcdtop.print("FXMod-Frq");
break;
case 23:
lcdtop.print("Bend->Osc");
break;
default:
lcdtop.print("_________");
}
lcdtop.setCursor(10,1); //position for field e9, a 9 character parameter label (left encoder position 2)
switch (Page) {
case 0:
lcdtop.print("SynthType"); //for system page 0
break;
case 1:
lcdtop.print("Waveform1"); //for DW6000
break;
case 2:
lcdtop.print("Interval ");
break;
case 3:
lcdtop.print("Resonance");
break;
case 4:
lcdtop.print(" F-Decay ");
break;
case 5:
lcdtop.print(" ");
break;
case 6:
lcdtop.print(" A-Decay ");
break;
case 7:
lcdtop.print(" ");
break;
case 8:
lcdtop.print("LFO-->OSC");
break;
case 9:
lcdtop.print(" ");
break;
case 10:
lcdtop.print("PortaTime");
break;
case 11:
lcdtop.print("Waveform1"); //for DW8000
break;
case 12:
lcdtop.print("Interval ");
break;
case 13:
lcdtop.print("ABend-1&2");
break;
case 14:
lcdtop.print("Resonance");
break;
case 15:
lcdtop.print(" F-Decay ");
break;
case 16:
lcdtop.print("F-VelSens");
break;
case 17:
lcdtop.print(" A-Decay ");
break;
case 18:
lcdtop.print("A-VelSens");
break;
case 19:
lcdtop.print("LFO-->Osc");
break;
case 20:
lcdtop.print("Pres->VCF");
break;
case 21:
lcdtop.print("Dly-FineT");
break;
case 22:
lcdtop.print(" ");
break;
case 23:
lcdtop.print("Portamnto");
break;
default:
lcdtop.print("_________");
}
lcdtop.setCursor(21,1); //position for field f9, a 9 character parameter label (right encoder position 1)
switch (Page) {
case 0:
lcdtop.print("MIDI-Chan"); //for system page 0
break;
case 1:
lcdtop.print("Octave-2 "); //for DW6000
break;
case 2:
lcdtop.print(" Level-2 ");
break;
case 3:
lcdtop.print("Env-->VCF");
break;
case 4:
lcdtop.print(" F-Slope ");
break;
case 5:
lcdtop.print("F-Sustain");
break;
case 6:
lcdtop.print(" A-Slope ");
break;
case 7:
lcdtop.print("A-Sustain");
break;
case 8:
lcdtop.print("LFO-Delay");
break;
case 9:
lcdtop.print("Bend->VCF");
break;
case 10:
lcdtop.print(" Chorus ");
break;
case 11:
lcdtop.print(" Octave-2"); //for DW8000
break;
case 12:
lcdtop.print(" Level-2 ");
break;
case 13:
lcdtop.print("ABendTime");
break;
case 14:
lcdtop.print("Env-->VCF");
break;
case 15:
lcdtop.print(" F-Slope ");
break;
case 16:
lcdtop.print("F-Sustain");
break;
case 17:
lcdtop.print(" A-Slope ");
break;
case 18:
lcdtop.print("A-Sustain");
break;
case 19:
lcdtop.print("LFO-Delay");
break;
case 20:
lcdtop.print("Pres->Osc");
break;
case 21:
lcdtop.print("Dly-Level");
break;
case 22:
lcdtop.print("Mod-->Dly");
break;
case 23:
lcdtop.print("Bend->VCF");
break;
default:
lcdtop.print("_________");
}
lcdtop.setCursor(31,1); //position for field g9, a 9 character parameter label (right encoder position 2)
switch (Page) {
case 0:
lcdtop.print(" "); //for system page 0
break;
case 1:
lcdtop.print("Waveform2"); //for DW6000
break;
case 2:
lcdtop.print(" Detune ");
break;
case 3:
lcdtop.print("Key-Track");
break;
case 4:
lcdtop.print("F-Release");
break;
case 5:
lcdtop.print("F-Polarty");
break;
case 6:
lcdtop.print("A-Release");
break;
case 7:
lcdtop.print(" ");
break;
case 8:
lcdtop.print("LFO-->VCF");
break;
case 9:
lcdtop.print(" ");
break;
case 10:
lcdtop.print("AsignMode");
break;
case 11:
lcdtop.print("Waveform2"); //for DW8000
break;
case 12:
lcdtop.print(" Detune ");
break;
case 13:
lcdtop.print("ABend-Dir");
break;
case 14:
lcdtop.print("Key Track");
break;
case 15:
lcdtop.print("F-Release");
break;
case 16:
lcdtop.print("Polarity ");
break;
case 17:
lcdtop.print("A-Release");
break;
case 18:
lcdtop.print(" ");
break;
case 19:
lcdtop.print("LFO-->VCF");
break;
case 20:
lcdtop.print("Pres->VCA");
break;
case 21:
lcdtop.print("DlyFeedbk");
break;
case 22:
lcdtop.print(" ");
break;
case 23:
lcdtop.print("Noise Lvl");
break;
default:
lcdtop.print("_________");
}
}
// ****************************************************************************************************************** FillLCDRow3()
void FillLCDRow3() {
lcdbot.setCursor(4,0); //position for field h1, a single character blank or big down arrow
if (EncLeft) {
lcdbot.write(byte(32)); //That's an empty space
}
else {
lcdbot.write(byte(3)); //That's the custom BigDown Arrow
}
lcdbot.setCursor(14,0); //position for field i1, a single character blank or big down arrow
if (EncLeft) {
lcdbot.write(byte(3)); //That's the custom BigDown Arrow
}
else {
lcdbot.write(byte(32)); //That's an empty space
}
lcdbot.setCursor(25,0); //position for field j1, a single character blank or big down arrow
if (EncRight) {
lcdbot.write(byte(32)); //That's an empty space
}
else {
lcdbot.write(byte(3)); //That's the custom BigDown Arrow
}
lcdbot.setCursor(35,0); //position for field k1, a single character blank or big down arrow
if (EncRight) {
lcdbot.write(byte(3)); //That's the custom BigDown Arrow
}
else {
lcdbot.write(byte(32)); //That's an empty space
}
}
// **************************************************************************************************************** FillLCDRow4()a
void FillLCDRow4a() {
lcdbot.setCursor(0,1); //position for field L9, a 9 character value specific for each synth parameter
if (SysSynthName==1) { //for the DW-6000
switch (Page) {
case 0:
if (SysUnitID<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(SysUnitID); //SysUnitID
lcdbot.print(" ");
break;
case 1:
if (PDW6_Osc1Octave==0) {
lcdbot.print(" 16' ");
}
if (PDW6_Osc1Octave==1) {
lcdbot.print(" 8' ");
}
if (PDW6_Osc1Octave==2) {
lcdbot.print(" 4' ");
}
break;
case 2:
if (PDW6_Osc1Level<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_Osc1Level); //PDW6_Osc1Level
lcdbot.print(" ");
break;
case 3:
if (PDW6_Cutoff<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_Cutoff); //PDW6_Cutoff
lcdbot.print(" ");
break;
case 4:
if (PDW6_FAttack<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_FAttack); //PDW6_FAttack
lcdbot.print(" ");
break;
case 5:
if (PDW6_FBreakpoint<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_FBreakpoint); //PDW6_FBreakpoint
lcdbot.print(" ");
break;
case 6:
if (PDW6_AAtack<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_AAtack); //PDW6_AAtack
lcdbot.print(" ");
break;
case 7:
if (PDW6_ABreakpoint<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_ABreakpoint); //PDW6_ABreakpoint
lcdbot.print(" ");
break;
case 8:
if (PDW6_MGFrequency<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_MGFrequency); //PDW6_MGFrequency
lcdbot.print(" ");
break;
case 9:
if (PDW6_BendOsc<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_BendOsc); //PDW6_BendOsc
lcdbot.print(" ");
break;
case 10:
if (PDW6_NoiseLevel<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_NoiseLevel); //PDW6_NoiseLevel
lcdbot.print(" ");
break;
default:
lcdbot.print(" ");
}
}
if (SysSynthName==2) { //for the DW-8000
}
if (SysSynthName==3) { //for the EX-800
}
}
// ***************************************************************************************************************** FillLCDRow4()b
void FillLCDRow4b() {
lcdbot.setCursor(10,1); //position for field m9, a 9 character value specific for each synth parameter
if (SysSynthName==1) { //for the DW-6000
switch (Page) {
case 0:
if (SysSynthName==1) {
lcdbot.print(" DW-6000 ");
}
if (SysSynthName==2) {
lcdbot.print(" DW-8000 ");
}
if (SysSynthName==3) {
lcdbot.print(" EX-800 ");
}
break;
case 1:
if (PDW6_Osc1Waveform==0) {
lcdbot.print("Bras&Strg");
}
if (PDW6_Osc1Waveform==1) {
lcdbot.print(" Violin ");
}
if (PDW6_Osc1Waveform==2) {
lcdbot.print("Aco.Piano");
}
if (PDW6_Osc1Waveform==3) {
lcdbot.print(" E.Piano ");
}
if (PDW6_Osc1Waveform==4) {
lcdbot.print("Syn-Bass ");
}
if (PDW6_Osc1Waveform==5) {
lcdbot.print("Saxophone");
}
if (PDW6_Osc1Waveform==6) {
lcdbot.print(" Clavi ");
}
if (PDW6_Osc1Waveform==7) {
lcdbot.print(" Bell ");
}
break;
case 2:
if (PDW6_Interval==0) {
lcdbot.print(" Unison ");
}
if (PDW6_Interval==1) {
lcdbot.print("Minor 3rd");
}
if (PDW6_Interval==2) {
lcdbot.print("Major 3rd");
}
if (PDW6_Interval==3) {
lcdbot.print(" 4th ");
}
if (PDW6_Interval==4) {
lcdbot.print(" 5th ");
}
break;
case 3:
if (PDW6_Resonance<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_Resonance); //PDW6_Resonance
lcdbot.print(" ");
break;
case 4:
if (PDW6_FDecay<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_FDecay); //PDW6_FDecay
lcdbot.print(" ");
break;
case 5:
lcdbot.print(" ");
break;
case 6:
if (PDW6_ADecay<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_ADecay); //PDW6_ADecay
lcdbot.print(" ");
break;
// /* AT CASE 7 AND BEYOND IT WOULD KILL THE PROCESSOR
case 7:
lcdbot.print(" ");
break;
case 8:
if (PDW6_MG2Osc<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_MG2Osc); //PDW6_MG2Osc
lcdbot.print(" ");
break;
case 9:
lcdbot.print(" ");
break;
case 10:
if (PDW6_PortTime<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print("10"); //PDW6_PortTime
lcdbot.print(" ");
break;
// */
default:
lcdbot.print(" ");
}
}
if (SysSynthName==2) { //for the DW-8000
}
if (SysSynthName==3) { //for the EX-800
}
}
// ****************************************************************************************************************** FillLCDRow4()c
void FillLCDRow4c() {
lcdbot.setCursor(21,1); //position for field n9, a 9 character value specific for each synth parameter
if (SysSynthName==1) { //for the DW-6000
switch (Page) {
case 0:
if (SysMIDIChannel<9) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(SysMIDIChannel+1);
lcdbot.print(" ");
break;
case 1:
if (PDW6_Osc2Octave==0) {
lcdbot.print(" 16' ");
}
if (PDW6_Osc2Octave==1) {
lcdbot.print(" 8' ");
}
if (PDW6_Osc2Octave==2) {
lcdbot.print(" 4' ");
}
break;
case 2:
if (PDW6_Osc2Level<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_Osc2Level);
lcdbot.print(" ");
break;
case 3:
if (PDW6_VCFEGIntensity<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_VCFEGIntensity);
lcdbot.print(" ");
break;
case 4:
if (PDW6_FSlope<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_FSlope);
lcdbot.print(" ");
break;
case 5:
if (PDW6_FSustain<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_FSustain);
lcdbot.print(" ");
break;
// /* AT CASE 6 AND BEYOND IT WOULD KILL THE PROCESSOR
case 6:
if (PDW6_ASlope<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_ASlope);
lcdbot.print(" ");
break;
case 7:
if (PDW6_ASustain<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_ASustain);
lcdbot.print(" ");
break;
case 8:
if (PDW6_MGDelay<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print(PDW6_MGDelay);
lcdbot.print(" ");
break;
case 9:
if (PDW6_BendVCF==0) {
lcdbot.print(" Off ");
}
if (PDW6_BendVCF==1) {
lcdbot.print(" On ");
}
break;
case 10:
if (PDW6_Chorus==0) {
lcdbot.print(" Off ");
}
if (PDW6_Chorus==1) {
lcdbot.print(" On ");
}
break;
// */
default:
lcdbot.print(" ");
}
}
if (SysSynthName==2) { //for the DW-8000
}
if (SysSynthName==3) { //for the EX-800
}
}
// ***************************************************************************************************************** FillLCDRow4()d
void FillLCDRow4d() {
lcdbot.setCursor(31,1); //position for field o9, a 9 character value specific for each synth parameter
if (SysSynthName==1) { //for the DW-6000
switch (Page) {
case 0:
lcdbot.print(" ");
break;
case 1:
if (PDW6_Osc2Waveform==0) {
lcdbot.print("Bras&Strg");
}
if (PDW6_Osc2Waveform==1) {
lcdbot.print(" Violin ");
}
if (PDW6_Osc2Waveform==2) {
lcdbot.print("Aco.Piano");
}
if (PDW6_Osc2Waveform==3) {
lcdbot.print("Elc.Piano");
}
if (PDW6_Osc2Waveform==4) {
lcdbot.print("Syn-Bass ");
}
if (PDW6_Osc2Waveform==5) {
lcdbot.print("Saxophone");
}
if (PDW6_Osc2Waveform==6) {
lcdbot.print(" Clavi ");
}
if (PDW6_Osc2Waveform==7) {
lcdbot.print(" Bell ");
}
break;
case 2:
lcdbot.print(" ");
lcdbot.print("2"); //PDW6_Detune
lcdbot.print(" ");
break;
case 3:
if (PDW6_KeyTracking==0) {
lcdbot.print(" Off ");
}
if (PDW6_KeyTracking==1) {
lcdbot.print(" Half ");
}
if (PDW6_KeyTracking==2) {
lcdbot.print(" Full ");
}
break;
case 4:
if (PDW6_FRelease<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print("4"); //PDW6_FRelease
lcdbot.print(" ");
break;
case 5:
if (PDW6_Polarity==0) {
lcdbot.print("normal UP");
}
if (PDW6_Polarity==1) {
lcdbot.print("invt DOWN");
}
break;
// /* AT CASE 6 AND BEYOND IT WOULD KILL THE PROCESSOR
case 6:
ConvertToChars(PDW6_ARelease);
lcdbot.print(" ");
lcdbot.print(Tens); //PDW6_ARelease
lcdbot.print(Ones); //PDW6_ARelease
lcdbot.print(" ");
break;
case 7:
lcdbot.print(" ");
break;
case 8:
if (PDW6_MG2VCF<10) {
lcdbot.print(" ");
}
lcdbot.print(" ");
lcdbot.print("8"); //PDW6_MG2VCF
lcdbot.print(" ");
break;
case 9:
lcdbot.print(" ");
break;
case 10:
if (PDW6_Assign==0) {
lcdbot.print("P1-Seqnce");
}
if (PDW6_Assign==1) {
lcdbot.print("P2-Fixed ");
}
if (PDW6_Assign==3) {
lcdbot.print(" Unison ");
}
break;
// */
default:
lcdbot.print(" ");
}
}
if (SysSynthName==2) { //for the DW-8000
}
if (SysSynthName==3) { //for the EX-800
}
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
// MIDI Subroutines
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
/*
void MIDITx(int Note, int vel) {
//transmit a midi note on then a note off
Serial1.write(0x90+(MIDIChannel)); //note on
Serial1.write(Note); //note #
Serial1.write(vel); //velocity
// delay(1);
Serial1.write(0x80+(MIDIChannel)); //note off
Serial1.write(Note); //note #
Serial1.write(0x00); //velocity of 0
}
*/
//this is the end my friend. the end.