//*******************************************************************************************************************
// Variáveis de Definição do Usuário.                      
//*******************************************************************************************************************
 
unsigned char PadNote[6] = {51};         // Notas MIDI - 0 a 127
 
int PadCutOff[6] = {100,100,100,100,100,100};           // Valor Mínimo do Sensor para causar o som

int MaxPlayTime[6] = {90,90,90,90,90,90};               // Ciclos a passar antes da Segunda Batida ser acionada.


//variaveis Mux

unsigned char PadNoteMux[6] = {38,36,46};         // Notas MIDI - 0 a 127
 
int PadCutOffMux[6] = {100,100,100,100,100,100};           // Valor Mínimo do Sensor para causar o som
 
int MaxPlayTimeMux[6] = {90,90,90,90,90,90};               // Ciclos a passar antes da Segunda Batida ser acionada.
 
#define  midichannel    0;                              // Canal Midi
 
boolean VelocityFlag  = true;                           // Se o som será de acordo com a intensidade da Batida.


// Variaveis MUX
int r0 = 0;      //value of select pin at the 4051 (s0)
int r1 = 0;      //value of select pin at the 4051 (s1)
int r2 = 0;      //value of select pin at the 4051 (s2)
int pinMux = 0;
 
 
 
 
 
//*******************************************************************************************************************
// Variáveis de uso Interno                   
//*******************************************************************************************************************
 
boolean activePad[6] = {0,0,0,0,0,0};                   // Salva se os pads estao ativos ou nao.
int PinPlayTime[6] = {0,0,0,0,0,0};                     // Contador dos ciclos desde que o pad foi acionado.

boolean activePadMux[6] = {0,0,0,0,0,0};                   // Salva se os pads estao ativos ou nao.
int PinPlayTimeMux[6] = {0,0,0,0,0,0}; 
 
unsigned char status;
 
int pin = 0;    
int hitavg = 0;
 
//*******************************************************************************************************************
// Setup                       
//*******************************************************************************************************************
 
void setup()
{
  Serial.begin(57600); 
  
  //Pinos para o MUX
  pinMode(2, OUTPUT);    // s0
  pinMode(3, OUTPUT);    // s1
  pinMode(4, OUTPUT);    // s2  
}
 
//*******************************************************************************************************************
// Main Program                
//*******************************************************************************************************************
 
void loop()
{
  for(int pin=0; pin < 2; pin++) // Percorre os Pinos Analógicos
  {
    if (pin == 1) //Pino de entrada do muxMUX
    {
      for (pinMux=0; pinMux<3; pinMux++) { //Percorre os pinos do Mux
      r0 = bitRead(pinMux,0);    // use this with arduino 0013 (and newer versions)     
      r1 = bitRead(pinMux,1);    // use this with arduino 0013 (and newer versions)     
      r2 = bitRead(pinMux,2);    // use this with arduino 0013 (and newer versions)     
      digitalWrite(2, r0);
      digitalWrite(3, r1);
      digitalWrite(4, r2);
      hitavg = analogRead(pin);  // Lê o Valor do Sensor 
      if((hitavg > PadCutOffMux[pinMux]))  // Verifica se o valor pego pelo sensor é maior que o Valor minimo para causar o Som
      {
        if((activePadMux[pinMux] == false))  // Verifica se o Pad já está sendo executado.
        {
          if(VelocityFlag == true)  // Verifica se o som será de acordo com a Intensidade da Batida, para gerar o Sinal Midi.
          {
           // hitavg = 127 / ((1023 - PadCutOffMux[pinMux]) / (hitavg - PadCutOffMux[pinMux]));    // With full range (Too sensitive ?)
            hitavg = (hitavg / 8) -1 ;                                                 // Upper range
          }
          else
          {
            hitavg = 127;
          }
 
          MIDI_TX(144,PadNoteMux[pinMux],hitavg); // Joga o SInal MIDI
          PinPlayTimeMux[pinMux] = 0;  //Seta o Ciclo para '0'
          activePadMux[pinMux] = true;  // Altera o Pad para Ativo.
        }
        else
        {
          PinPlayTimeMux[pinMux] = PinPlayTimeMux[pinMux] + 1; // Caso o Pad ja esteja ativo, incrementa 1 Ciclo.
        }
      }
      else if((activePadMux[pinMux] == true)) // ESTA SEGUNDA PARTE É RESPONSÁVEL APENAS POR INCREMENTAR OS CICLOS E ATIVAR/DESATIVAR OS PADS.
      {
        PinPlayTimeMux[pinMux] = PinPlayTimeMux[pinMux] + 1;
       
        if(PinPlayTimeMux[pinMux] > MaxPlayTimeMux[pinMux])
        {
          activePadMux[pinMux] = false;
          MIDI_TX(128,PadNoteMux[pinMux],127);
        }
      }
      
    }
    }
      else
      {
      hitavg = analogRead(pin);  // Lê o Valor do Sensor 
      if((hitavg > PadCutOff[pin]))  // Verifica se o valor pego pelo sensor é maior que o Valor minimo para causar o Som
      {
        if((activePad[pin] == false))  // Verifica se o Pad já está sendo executado.
        {
          if(VelocityFlag == true)  // Verifica se o som será de acordo com a Intensidade da Batida, para gerar o Sinal Midi.
          {
          // hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin]));    // With full range (Too sensitive ?)
           hitavg = (hitavg / 8) -1 ;                                                 // Upper range
          }
          else
          {
            hitavg = 127;
          }
 
          MIDI_TX(144,PadNote[pin],hitavg); // Joga o SInal MIDI
          PinPlayTime[pin] = 0;  //Seta o Ciclo para '0'
          activePad[pin] = true;  // Altera o Pad para Ativo.
        }
        else
        {
          PinPlayTime[pin] = PinPlayTime[pin] + 1; // Caso o Pad ja esteja ativo, incrementa 1 Ciclo.
        }
      }
      else if((activePad[pin] == true)) // ESTA SEGUNDA PARTE É RESPONSÁVEL APENAS POR INCREMENTAR OS CICLOS E ATIVAR/DESATIVAR OS PADS.
      {
        PinPlayTime[pin] = PinPlayTime[pin] + 1;
       
        if(PinPlayTime[pin] > MaxPlayTime[pin])
        {
          activePad[pin] = false;
          MIDI_TX(128,PadNote[pin],127);
        }
      }
    }
  }
}
 
 
//*******************************************************************************************************************
// Função que transmite o MIDI                       
//*******************************************************************************************************************
void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{
  status = MESSAGE + midichannel;
  Serial.write(status);
  Serial.write(PITCH);
  Serial.write(VELOCITY);
}