#include <MusicWithoutDelay.h>
#include <synth.h>
#include <tables.h>

#include <Wire.h>
#include <Adafruit_ADS1015.h>

//multiplexer adresses
Adafruit_ADS1115 adsa (0x48);
Adafruit_ADS1115 adsb (0x49);
Adafruit_ADS1115 adsc (0x4A);
Adafruit_ADS1115 adsd (0x4B);


//note values
const char note0[] PROGMEM = ":d=128,b=300:c-1+";  //plays c4
const char note1[] PROGMEM = ":d=128,b=300:d-1+";  //plays d4
const char note2[] PROGMEM = ":d=128,b=300:e-1+";  //plays e4
const char note3[] PROGMEM = ":d=128,b=300:g-1+";  //plays g4
const char note4[] PROGMEM = ":d=128,b=300:a-1+";  //plays a4
const char note5[] PROGMEM = ":d=128,b=300:c+";  //plays c5
const char note6[] PROGMEM = ":d=128,b=300:d+";  //plays d5
const char note7[] PROGMEM = ":d=128,b=300:e+";  //plays e5
const char note8[] PROGMEM = ":d=128,b=300:g+";  //plays g5
const char note9[] PROGMEM = ":d=128,b=300:a+";  //plays a5
const char note10[] PROGMEM = ":d=128,b=300:c+1+";  //plays c6
const char note11[] PROGMEM = ":d=128,b=300:d+1+";  //plays d6
const char note12[] PROGMEM = ":d=128,b=300:e+1+";  //plays e6
const char note13[] PROGMEM = ":d=128,b=300:g+1+";  //plays g6
const char note14[] PROGMEM = ":d=128,b=300:a+1+";  //plays a6
const char note15[] PROGMEM = ":d=128,b=300:c+2+";  //plays c7

//instruments
MusicWithoutDelay Insta(note0);
MusicWithoutDelay Instb(note1);
MusicWithoutDelay Instc(note2);
MusicWithoutDelay Instd(note3);
MusicWithoutDelay Inste(note4);
MusicWithoutDelay Instf(note5);
MusicWithoutDelay Instg(note6);
MusicWithoutDelay Insth(note7);
MusicWithoutDelay Insti(note8);
MusicWithoutDelay Instj(note9);
MusicWithoutDelay Instk(note10);
MusicWithoutDelay Instl(note11);
MusicWithoutDelay Instm(note12);
MusicWithoutDelay Instn(note13);
MusicWithoutDelay Insto(note14);
MusicWithoutDelay Instp(note15);




int count;
//int vol;
int VA0, VA1, VA2, VA3, VA4, VA5, VA6, VA7, VA8, VA9, VA10, VA11, VA12, VA13, VA14, VA15;
int TH0, TH1, TH2, TH3, TH4, TH5, TH6, TH7, TH8, TH9, TH10, TH11, TH12, TH13, TH14, TH15;
int VOL0, VOL1, VOL2, VOL3, VOL4, VOL5, VOL6, VOL7, VOL8, VOL9, VOL10, VOL11, VOL12, VOL13, VOL14, VOL15;
bool CV;

int ZER;
int ONE;
int TWO;
int THR;
int FOU;
int FIV;
int SIX;
int SEV;
int EIG;
int NIN;
int TEN;
int ELE;
int TWE;
int THT;
int FOT;
int FIT;

void setup() {
  Serial.begin(115200);

      //set the gain for multiplexed INs
    adsa.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
    adsb.setGain(GAIN_ONE); 
    adsc.setGain(GAIN_ONE); 
    adsd.setGain(GAIN_ONE); 

    Serial.println("Ini MPX ");
    adsa.begin();
    adsb.begin();
    adsc.begin();
    adsd.begin();
    Serial.println("MPX Ini");

  Serial.println("Wait4MWD");
  Serial.println("Ini MWD");

  calib();

  Insta.begin(CHA, TRIANGLE, ENVELOPE2, 0);
  Instb.begin(TRIANGLE, ENVELOPE2, 0);
  Instc.begin(TRIANGLE, ENVELOPE2, 0);
  Instd.begin(TRIANGLE, ENVELOPE2, 0);
  Inste.begin(TRIANGLE, ENVELOPE2, 0);
  Instf.begin(TRIANGLE, ENVELOPE2, 0);
  Instg.begin(TRIANGLE, ENVELOPE2, 0);
  Insth.begin(TRIANGLE, ENVELOPE2, 0);
  Insti.begin(TRIANGLE, ENVELOPE2, 0);
  Instj.begin(TRIANGLE, ENVELOPE2, 0);
  Instk.begin(TRIANGLE, ENVELOPE2, 0);
  Instl.begin(TRIANGLE, ENVELOPE2, 0);
  Instm.begin(TRIANGLE, ENVELOPE2, 0);
  Instn.begin(TRIANGLE, ENVELOPE2, 0);
  Insto.begin(TRIANGLE, ENVELOPE2, 0);
  Instp.begin(TRIANGLE, ENVELOPE2, 0);

  Insta.pause(true);
  Instb.pause(true);
  Instc.pause(true);
  Instd.pause(true);
  Inste.pause(true);
  Instf.pause(true);
  Instg.pause(true);
  Insth.pause(true);
  Insti.pause(true);
  Instj.pause(true);
  Instk.pause(true);
  Instl.pause(true);
  Instm.pause(true);
  Instn.pause(true);
  Insto.pause(true);
  Instp.pause(true);

  Serial.println("go!");
}

void calib() {
  //calibrate the LDRs
  Serial.println ("Calib");
  TH0 = (adsa.readADC_SingleEnded(0) + 800);
  TH1 = (adsa.readADC_SingleEnded(1) + 800);
  TH2 = (adsa.readADC_SingleEnded(2) + 800);
  TH3 = (adsa.readADC_SingleEnded(3) + 800);
  TH4 = (adsb.readADC_SingleEnded(0) + 800);
  TH5 = (adsb.readADC_SingleEnded(1) + 800);
  TH6 = (adsb.readADC_SingleEnded(2) + 800);
  TH7 = (adsb.readADC_SingleEnded(3) + 800);
  TH8 = (adsc.readADC_SingleEnded(0) + 800);
  TH9 = (adsc.readADC_SingleEnded(1) + 800);
  TH10 = (adsc.readADC_SingleEnded(2) + 800);
  TH11 = (adsc.readADC_SingleEnded(3) + 800);
  TH12 = (adsd.readADC_SingleEnded(0) + 800);
  TH13 = (adsd.readADC_SingleEnded(1) + 800);
  TH14 = (adsd.readADC_SingleEnded(2) + 800);
  TH15 = (adsd.readADC_SingleEnded(3) + 800);

  Serial.print ("TH0=");
  Serial.println (TH0);
  Serial.print ("TH1=");
  Serial.println (TH1);
  Serial.print ("TH2=");
  Serial.println (TH2);
  Serial.print ("TH3=");
  Serial.println (TH3);
  Serial.print ("TH4=");
  Serial.println (TH4);
  Serial.print ("TH5=");
  Serial.println (TH5);
  Serial.print ("TH6=");
  Serial.println (TH6);
  Serial.print ("TH7=");
  Serial.println (TH7);
  Serial.print ("TH8=");
  Serial.println (TH8);
  Serial.print ("TH9=");
  Serial.println (TH9);
  Serial.print ("TH10=");
  Serial.println (TH10);
  Serial.print ("TH11=");
  Serial.println (TH11);
  Serial.print ("TH12=");
  Serial.println (TH12);
  Serial.print ("TH13=");
  Serial.println (TH13);
  Serial.print ("TH14=");
  Serial.println (TH14);
  Serial.print ("TH15=");
  Serial.println (TH15);  
  }

void loop() {
  CV = digitalRead(17);
  count = 0;
  
  Insta.update();
  Instb.update();
  Instc.update();
  Instd.update();
  Inste.update();
  Instf.update();
  Instg.update();
  Insth.update();
  Insti.update();
  Instj.update();
  Instk.update();
  Instl.update();
  Instm.update();
  Instn.update();
  Insto.update();
  Instp.update();


  //Messure LDR inputs
  VA0 = adsa.readADC_SingleEnded(0);
  VA1 = adsa.readADC_SingleEnded(1);
  VA2 = adsa.readADC_SingleEnded(2);
  VA3 = adsa.readADC_SingleEnded(3);
  
//      Serial.print("VA0: "); Serial.println(VA0);
//      Serial.print("VA1: "); Serial.println(VA1);
//      Serial.print("VA2: "); Serial.println(VA2);
//      Serial.print("VA3: "); Serial.println(VA3);
//      Serial.println(" ");

  VA4 = adsb.readADC_SingleEnded(0);
  VA5 = adsb.readADC_SingleEnded(1);
  VA6 = adsb.readADC_SingleEnded(2);
  VA7 = adsb.readADC_SingleEnded(3);
  
//      Serial.print("VA4: "); Serial.println(VA4);
//      Serial.print("VA5: "); Serial.println(VA5);
//      Serial.print("VA6: "); Serial.println(VA6);
//      Serial.print("VA7: "); Serial.println(VA7);
//      Serial.println(" ");

  VA8 = adsc.readADC_SingleEnded(0);
  VA9 = adsc.readADC_SingleEnded(1);
  VA10 = adsc.readADC_SingleEnded(2);
  VA11 = adsc.readADC_SingleEnded(3);

//      Serial.print("VA8: "); Serial.println(VA8);
//      Serial.print("VA9: "); Serial.println(VA9);
//      Serial.print("VA10: "); Serial.println(VA10);
//      Serial.print("VA11: "); Serial.println(VA11);
//      Serial.println(" ");

  VA12 = adsd.readADC_SingleEnded(0);
  VA13 = adsd.readADC_SingleEnded(1);
  VA14 = adsd.readADC_SingleEnded(2);
  VA15 = adsd.readADC_SingleEnded(3);

//      Serial.print("VA12: "); Serial.println(VA12);
//      Serial.print("VA13: "); Serial.println(VA13);
//      Serial.print("VA14: "); Serial.println(VA14);
//      Serial.print("VA15: "); Serial.println(VA15);
//      Serial.println(" ");

  

  if (VA0 > TH0) {
    count++;
    ZER = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(0, HIGH);
    }
    else if (!CV) {
      digitalWrite(0, LOW);
    }
  }
  else if (VA0 < TH0) {
    ZER = false;
    //Kill ControlVoltage
    digitalWrite(0, LOW);
  }
    
  if (VA1 > TH1) {
    count++;
    ONE = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(1, HIGH);
    }
    else if (!CV) {
      digitalWrite(1, LOW);
    }
  }
  else if (VA1 < TH1) {
    ONE = false;    
    //Kill ControlVoltage
    digitalWrite(1, LOW);
  }
  
  if (VA2 > TH2) {
    count++;
    TWO = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(2, HIGH);
    }
    else if (!CV) {
      digitalWrite(2, LOW);
    }
  }
  else if (VA2 < TH2) {
    TWO = false;
    //Kill ControlVoltage
    digitalWrite(2, LOW);
  }

  if (VA3 > TH3) {
    count++;
    THR = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(4, HIGH);
    }
    else if (!CV) {
      digitalWrite(4, LOW);
    }
  }
  else if (VA3 < TH3) {
    THR = false;
    //Kill ControlVoltage
    digitalWrite(4, LOW);
  }

  if (VA4 > TH4) {
    count++;
    FOU = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(5, HIGH);
    }
    else if (!CV) {
      digitalWrite(5, LOW);
    }
  }
  else if (VA4 < TH4) {
    FOU = false;
    //Kill ControlVoltage
    digitalWrite(5, LOW);
  }

  if (VA5 > TH5) {
    count++;
    FIV = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(6, HIGH);
    }
    else if (!CV) {
      digitalWrite(6, LOW);
    }
  }
  else if (VA5 < TH5) {
    FIV = false;
    //Kill ControlVoltage
    digitalWrite(6, LOW);
  }

  if (VA6 > TH6) {
    count++;
    SIX = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(7, HIGH);
    }
    else if (!CV) {
      digitalWrite(7, LOW);
    }
  }
  else if (VA6 < TH6) {
    SIX = false;
    //Kill ControlVoltage
    digitalWrite(7, LOW);
  }

  if (VA7 > TH7) {
    count++;
    SEV = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(8, HIGH);
    }
    else if (!CV) {
      digitalWrite(8, LOW);
    }
  }
  else if (VA7 < TH7) {
    SEV = false;
    //Kill ControlVoltage
    digitalWrite(8, LOW);
  }

  if (VA8 > TH8) {
    count++;
    EIG = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(9, HIGH);
    }
    else if (!CV) {
      digitalWrite(9, LOW);
    }
  }
  else if (VA8 < TH8) {
    EIG = false;
    //Kill ControlVoltage
    digitalWrite(9, LOW);
  }

  if (VA9 > TH9) {
    count++;
    NIN = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(10, HIGH);
    }
    else if (!CV) {
      digitalWrite(10, LOW);
    }
  }
  else if (VA9 < TH9) {
    NIN = false;
    //Kill ControlVoltage
    digitalWrite(10, LOW);
  }
  
  if (VA10 > TH10) {
    count++;
    TEN = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(11, HIGH);
    }
    else if (!CV) {
      digitalWrite(11, LOW);
    }
  }
  else if (VA10 < TH10) {
    TEN = false;
    //Kill ControlVoltage
    digitalWrite(11, LOW);
  }

  if (VA11 > TH11) {
    count++;
    ELE = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(12, HIGH);
    }
    else if (!CV) {
      digitalWrite(12, LOW);
    }
  }
  else if (VA11 < TH11) {
    ELE = false;
    //Kill ControlVoltage
    digitalWrite(12, LOW);
  }

  if (VA12 > TH12) {
    count++;
    TWE = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(13, HIGH);
    }
    else if (!CV) {
      digitalWrite(13, LOW);
    }
  }
  else if (VA12 < TH12) {
    TWE = false;
    //Kill ControlVoltage
    digitalWrite(13, LOW);
  }

  if (VA13 > TH13) {
    count++;
    THT = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(14, HIGH);
    }
    else if (!CV) {
      digitalWrite(14, LOW);
    }
  }
  else if (VA13 < TH13) {
    THT = false;
    //Kill ControlVoltage
    digitalWrite(14, LOW);
  }

  if (VA14 > TH14) {
    count++;
    FOT = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(15, HIGH);
    }
    else if (!CV) {
      digitalWrite(15, LOW);
    }
  }
  else if (VA14 < TH14) {
    FOT = false;
    //Kill ControlVoltage
    digitalWrite(15, LOW);
  }

  if (VA15 > TH15) {
    count++;
    FIT = true;
    //Output ControlVoltage if switch is activated
    if (CV) {
      digitalWrite(16, HIGH);
    }
    else if (!CV) {
      digitalWrite(16, LOW);
    }
  }
  else if (VA15 < TH15) {
    FIT = false;
    //Kill ControlVoltage
    digitalWrite(16, LOW);
  }


//  Serial.print("Intruments playing = ");
//  Serial.println(count);

  //Play notes and mix down (set volume depending on number of notes playing)
  if (ZER) {
    VOL0 = 50/count+constrain(map(VA0, TH0, TH0+5000, 0, 65), 0, 65);
    Insta.play(true);
    Insta.setVolume(VOL0);
//    Serial.print("Tone0 active at vol:");
//    Serial.println(VOL0);
//    Serial.println(VA0);
  }

  if (!ZER) {
    Insta.pause (true);
  }

  if (ONE) {
    VOL1 = 50/count+constrain(map(VA1, TH1, TH1+5000, 0, 65), 0, 65);
    Instb.play(true);
    Instb.setVolume(VOL1);
//    Serial.print("Tone1 active at vol:");
//    Serial.println(VOL1);
//    Serial.println(VA1);
  }

  if (!ONE) {
    Instb.pause (true);
  }

  if (TWO) {
    VOL2 = 50/count+constrain(map(VA2, TH2, TH2+5000, 0, 65), 0, 65);
    Instc.play(true);
    Instc.setVolume(VOL2);
//    Serial.print("Tone2 active at vol:");
//    Serial.println(VOL2);
//    Serial.println(VA2);
  }

  if (!TWO) {
    Instc.pause (true);
  }
  
  if (THR) {
    VOL3 = 50/count+constrain(map(VA3, TH3, TH3+5000, 0, 65), 0, 65);
    Instd.play(true);
    Instd.setVolume(VOL3);
//    Serial.print("Tone3 active at vol:");
//    Serial.println(VOL3);
//    Serial.println(VA3);
  }

  if (!THR) {
    Instd.pause (true);
  }

  if (FOU) {
    VOL4 = 50/count+constrain(map(VA4, TH4, TH4+5000, 0, 65), 0, 65);
    Inste.play(true);
    Inste.setVolume(VOL4);
//    Serial.print("Tone4 active at vol:");
//    Serial.println(VOL4);
//    Serial.println(VA4);
  }

  if (!FOU) {
    Inste.pause (true);
  }

  if (FIV) {
    VOL5 = 50/count+constrain(map(VA5, TH5, TH5+5000, 0, 65), 0, 65);
    Instf.play(true);
    Instf.setVolume(VOL5);
//    Serial.print("Tone5 active at vol:");
//    Serial.println(VOL5);
//    Serial.println(VA5);
  }

  if (!FIV) {
    Instf.pause (true);
  }


  if (SIX) {
    VOL6 = 50/count+constrain(map(VA6, TH6, TH6+5000, 0, 65), 0, 65);
    Instg.play(true);
    Instg.setVolume(VOL6);
//    Serial.print("Tone6 active at vol:");
//    Serial.println(VOL6);
//    Serial.println(VA6);
  }

  if (!SIX) {
    Instg.pause (true);
  }

  if (SEV) {
    VOL7 = 50/count+constrain(map(VA7, TH7, TH7+5000, 0, 65), 0, 65);
    Insth.play(true);
    Insth.setVolume(VOL7);
//    Serial.print("Tone7 active at vol:");
//    Serial.println(VOL7);
//    Serial.println(VA7);
  }

  if (!SEV) {
    Insth.pause (true);
  }


  if (EIG) {
    VOL8 = 50/count+constrain(map(VA8, TH8, TH8+5000, 0, 65), 0, 65);
    Insti.play(true);
    Insti.setVolume(VOL8);
//    Serial.print("Tone8 active at vol:");
//    Serial.println(VOL8);
//    Serial.println(VA8);
  }

  if (!EIG) {
    Insti.pause (true);
  }

  if (NIN) {
    VOL9 = 50/count+constrain(map(VA9, TH9, TH9+5000, 0, 65), 0, 65);
    Instj.play(true);
    Instj.setVolume(VOL9);
//    Serial.print("Tone9 active at vol:");
//    Serial.println(VOL9);
//    Serial.println(VA9);
  }

  if (!NIN) {
    Instk.pause (true);
  }

    if (TEN) {
    VOL10 = 50/count+constrain(map(VA10, TH10, TH10+5000, 0, 65), 0, 65);
    Instk.play(true);
    Instk.setVolume(VOL10);
//    Serial.print("Tone10 active at vol:");
//    Serial.println(VOL10);
//    Serial.println(VA10);
  }

  if (!TEN) {
    Instk.pause (true);
  }

      if (ELE) {
    VOL11 = 50/count+constrain(map(VA11, TH11, TH11+5000, 0, 65), 0, 65);
    Instl.play(true);
    Instl.setVolume(VOL11);
//    Serial.print("Tone11 active at vol:");
//    Serial.println(VOL11);
//    Serial.println(VA11);
  }

  if (!ELE) {
    Instl.pause (true);
  }
  
    if (TWE) {
    VOL12 = 50/count+constrain(map(VA12, TH12, TH12+5000, 0, 65), 0, 65);
    Instm.play(true);
    Instm.setVolume(VOL12);
//    Serial.print("Tone12 active at vol:");
//    Serial.println(VOL12);
//    Serial.println(VA12);

  }

  if (!TWE) {
    Instm.pause (true);
  }
    
    if (THT) {
    VOL13 = 50/count+constrain(map(VA13, TH13, TH13+5000, 0, 65), 0, 65);
    Instn.play(true);
    Instn.setVolume(VOL13);
//    Serial.print("Tone13 active at vol:");
//    Serial.println(VOL13);
//    Serial.println(VA13);
  }

  if (!THT) {
    Instn.pause (true);
  }
      
    if (FOT) {
    VOL14 = 50/count+constrain(map(VA14, TH14, TH14+5000, 0, 65), 0, 65);
    Insto.play(true);
    Insto.setVolume(VOL14);
//    Serial.print("Tone14 active at vol:");
//    Serial.println(VOL14);
//    Serial.println(VA14);
  }

  if (!FOT) {
    Insto.pause (true);
  }

        
    if (FIT) {
    VOL15 = 50/count+constrain(map(VA15, TH15, TH15+5000, 0, 65), 0, 65);
    Instp.play(true);
    Instp.setVolume(VOL15);
//    Serial.print("Tone15 active at vol:");
//    Serial.println(VOL15);
//    Serial.println(VA15);
  }

  if (!FIT) {
    Instp.pause (true);
  }
}
