﻿#include <MozziGuts.h>
#include <Oscil.h> 
#include <tables/sin2048_int8.h> 
#include <tables/saw2048_int8.h>
#include <tables/square2048_int8.h>
#include <tables/triangle_valve_2048_int8.h>
#include <tables/noise2048.h>
#include <tables/cos2048_int8.h> 
#include <mozzi_midi.h>
#include <StateVariable.h>
#include <mozzi_fixmath.h>
#include <mozzi_analog.h>

Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw(SAW2048_DATA);
Oscil <SQUARE2048_TABLE_NUM_CELLS, AUDIO_RATE> aSquare(SQUARE2048_TABLE_DATA);
Oscil <TRIANGLE_VALVE_2048_NUM_CELLS, AUDIO_RATE> aTriangle(TRIANGLE_VALVE_2048_DATA);
Oscil <NOISE2048_TABLE_NUM_CELLS, AUDIO_RATE> aNoise(NOISE2048_TABLE_DATA);

Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin2(SIN2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw2(SAW2048_DATA);
Oscil <SQUARE2048_TABLE_NUM_CELLS, AUDIO_RATE> aSquare2(SQUARE2048_TABLE_DATA);
Oscil <TRIANGLE_VALVE_2048_NUM_CELLS, AUDIO_RATE> aTriangle2(TRIANGLE_VALVE_2048_DATA);
Oscil <NOISE2048_TABLE_NUM_CELLS, AUDIO_RATE> aNoise2(NOISE2048_TABLE_DATA);

Oscil<SIN2048_NUM_CELLS, AUDIO_RATE> aVibrato(SIN2048_DATA);


StateVariable <LOWPASS> lpf;

#define CONTROL_RATE 64
#define HIFI 1
#define BLAUW  2
#define GROEN  3
#define GEEL  4
#define ORANJE  5
#define ROOD  6
#define ZWART  7
#define WIT  8
#define PAARS 9

#define OCTAVE 10

const char OSCIL1 = 0;
const char OSCIL2 = 1;
const char CUTOFF = 2;
const char RESONANCE = 3;
const char LFO_FREQ = 4;
const char ATTACK = 6;
const char RELEASE = 5;
const char MIX  = 7;
int OSCIL1VALUE = 0;
int OSCIL2VALUE = 0;
int LAST_KEY = 0;
boolean NOTE_ON = false;
boolean RELEASE_ON = false;
int GAIN = 0;
int GAINOSC1 = 0;
int GAINOSC2 = 0;

void setup(){
  //Pedals initialiseren
  //RIJEN  
  LAST_KEY =0;
  
  pinMode(ROOD, INPUT);
  digitalWrite(ROOD, HIGH);

  pinMode(ZWART, INPUT);
  digitalWrite(ZWART, HIGH);

  pinMode(WIT, INPUT);
  digitalWrite(WIT, HIGH);
  
  pinMode(PAARS, INPUT);
  digitalWrite(PAARS, HIGH);
  
  pinMode(OCTAVE, INPUT);
  digitalWrite(OCTAVE, HIGH);

  //Kolommen

  pinMode(BLAUW, OUTPUT);
  digitalWrite(BLAUW, HIGH);

  pinMode(GROEN, OUTPUT);
  digitalWrite(GROEN, HIGH);

  pinMode(GEEL, OUTPUT);
  digitalWrite(GEEL, HIGH);

  pinMode(ORANJE, OUTPUT);
  digitalWrite(ORANJE, HIGH);
  // Nu het Synth gedeelte initialiseren
  
  
  setupFastAnalogRead(); 
  startMozzi(CONTROL_RATE);   
}

void updateControl(){

  int note = scanPedals();
  readOscillators();
  int Attack = (127-(analogRead(ATTACK)/24)*3);
  int Release =(127-(analogRead(RELEASE)/24)*3);
  
  if ((analogRead(MIX)/4) > 127) {
    GAINOSC2 = 255;
    GAINOSC1 = 255-((((analogRead(MIX)/4)-128)*2));
  }
  
  if ((analogRead(MIX)/4) <= 127){
    GAINOSC1 = 255;
    GAINOSC2 = 255 + (((analogRead(MIX)/4)-128)*2);
  } 
  
    if ((NOTE_ON==true)&&(GAIN <255)){    
      if ((GAIN + Attack) <=255){
        GAIN = (GAIN + Attack);}
      else 
        {GAIN = 255;}
    if (GAIN == 255) {
      NOTE_ON = false; 
      }}
   
   if ((RELEASE_ON ==true)&&(GAIN != 0)){
     note = LAST_KEY;
     if ((GAIN - Release) >= 0){
     GAIN = GAIN - Release;}
     else
     {GAIN = 0;}
     if (GAIN == 0) {
       RELEASE_ON =false;}}
       
  GAINOSC1 = MaxValue(GAIN, GAINOSC1);
  GAINOSC2 = MaxValue(GAIN, GAINOSC2);
  
  int cutoff = analogRead(CUTOFF)/4;
  int resonance = (analogRead(RESONANCE)/4);
  float lfo_freq = analogRead(LFO_FREQ);
  

      aSin.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aSquare.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aSaw.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aTriangle.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aNoise.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
    
      aSin2.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aSquare2.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aSaw2.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aTriangle2.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));
      aNoise2.setFreq_Q16n16(Q16n16_mtof(Q16n0_to_Q16n16(note)));    
  aVibrato.setFreq(lfo_freq);
  lpf.setCentreFreq(aVibrato.next()+255+cutoff);
  lpf.setResonance(resonance);
  
}


int updateAudio(){
  int oscillator1;
  int oscillator2;
  
  switch(OSCIL1VALUE){
    case 0:
      oscillator1 = aSin.next();
      break;
    case 1: oscillator1 = aSquare.next();
      break;
    case 2: oscillator1 = aSaw.next();
      break;
    case 3: oscillator1 = aTriangle.next();
      break;
    case 4: oscillator1 = aNoise.next();
      break;
  }
    
  switch(OSCIL2VALUE){
    case 0:
      oscillator2 = aSin2.next();
      break;
    case 1: oscillator2 = aSquare2.next();
      break;
    case 2: oscillator2 = aSaw2.next();
      break;
    case 3: oscillator2 = aTriangle2.next();
      break;
    case 4: oscillator2 = aNoise2.next();
      break;
  }
  
  int asign = lpf.next( (oscillator1*(GAINOSC1)) + (oscillator2*(GAINOSC2)) >>8)>>1;  
  return asign;
}


void loop(){
  audioHook(); 
}

int scanPedals() {
int key = 0;  
digitalWrite(BLAUW, LOW);
  if (digitalRead(ROOD) == LOW) {
    key = 36;
  }
  if (digitalRead(ZWART) == LOW) {
    key = 40;
  }
  if (digitalRead(WIT) == LOW) {
    key = 44;
  }
  if (digitalRead(PAARS) == LOW) {
    key = 48;
  }
  digitalWrite(BLAUW, HIGH);
  
  digitalWrite(GROEN, LOW);
  if (digitalRead(ROOD) == LOW) {
    key = 37;
  }
  if (digitalRead(ZWART) == LOW) {
    key = 41;
  }
  if (digitalRead(WIT) == LOW) {
    key = 45;
  }
  digitalWrite(GROEN, HIGH);
  
  digitalWrite(GEEL, LOW);
  if (digitalRead(ROOD) == LOW) {
    key = 38;
  }
  if (digitalRead(ZWART) == LOW) {
    key = 42;
  }
  if (digitalRead(WIT) == LOW) {
    key = 46;
  }
  digitalWrite(GEEL, HIGH);
  
  digitalWrite(ORANJE, LOW);
  if (digitalRead(ROOD) == LOW) {
    key = 39;
  }
  if (digitalRead(ZWART) == LOW) {
    key = 43;
  }
  if (digitalRead(WIT) == LOW) {
    key = 47;
  }
  digitalWrite(ORANJE, HIGH);
  
  if ((key > 0)&&(digitalRead(OCTAVE) == HIGH)){
    key = key - 12;
  }  
  if (key > 0){
      NOTE_ON = true;
      LAST_KEY = key;}
    else{
      NOTE_ON = false;
      RELEASE_ON =true;}
        
        
return key;
}

void readOscillators(){
  int Value1 = analogRead(OSCIL1);
  int Value2 = analogRead(OSCIL2);
  
  if (Value1 == LOW ){
    OSCIL1VALUE = 0;}
  if ((Value1 > LOW)&&(Value1 < 260)){
    OSCIL1VALUE = 1;}
  if ((Value1 > 260)&&(Value1 < 520)){
    OSCIL1VALUE = 2;}
  if ((Value1 > 520)&&(Value1 < 780)){
    OSCIL1VALUE = 3;}
  if ((Value1 >1000)){
     OSCIL1VALUE = 4;}  
  
    if (Value2 == LOW ){
    OSCIL2VALUE = 0;}
  if ((Value2 > LOW)&&(Value2 < 260)){
    OSCIL2VALUE = 1;}
  if ((Value2 > 260)&&(Value2 < 520)){
    OSCIL2VALUE = 2;}
  if ((Value2 > 520)&&(Value2 < 780)){
    OSCIL2VALUE = 3;}
  if ((Value2 > 1000)){
     OSCIL2VALUE = 4;}  
}

int MaxValue(int x, int MaxValue){
  int Result;
  
  if (x < MaxValue){
   Result = x;}
  else
   {Result = MaxValue;} 
  
  return Result;
}
