/*Benchmark MIDI Read Times
  By Benjamin G. Schultz
  July 2017

  Sends a digital trigger (LOW/HIGH) to test the received and read time of MIDI messages.
  Connect the device that receives the digital trigger via pin 9 (we used a sound card).
  Connect the MIDI cable via pin 15 (RX3). Each byte is read as it arrives in the serial buffer.

  See Schultz (2018) for more details, or contact benjamin.g.schultz@gmail.com

  References:
  Schultz, B. G. (2018). The Schultz MIDI Benchmarking toolbox for MIDI interfaces, percussion 
  pads, and sound cards. Behav. Res. Meth. 

   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 3 of the License, or
   (at your option) any later version.

*/

//  SET VARIABLES

// Variables for MIDI
byte commandByte;
byte noteByte;
byte velocityByte;
byte noteOn = 144;
byte drumOn = 153;
byte noteOff = 128;

// variables for pwm
int pwmPin = 9;
int pwm_val = LOW;

// SETUP
void setup() {
  Serial.begin(9600); // slow speed debugging
  
  Serial3.begin(31250); // MIDI default
  //Serial3.begin(62500); // Double Speed
  //Serial3.begin(46875); // 150% Speed
  //Serial3.begin(15625); // Half Speed
  
  pinMode(pwmPin, OUTPUT);
  digitalWrite(pwmPin, pwm_val);

}

// FUNCTIONS
// Checks for MIDI message and sends trigger (single byte method)
void checkMIDI() {

  if (Serial3.available()) {

    commandByte = Serial3.read();//read first byte

    //// DEBUGGING    
    //Serial.print("Command: ");
    //Serial.println(commandByte);
    //// END DEBUGGING

    if (commandByte == noteOn || commandByte == noteOff || commandByte == drumOn) {

      // trigger PWM
      digitalWrite(pwmPin, HIGH);

      while (Serial3.available() == 0) {};
      noteByte = Serial3.read();//read next byte

      while (Serial3.available() == 0) {};
      velocityByte = Serial3.read();//read next byte

      // turn off PWM
      digitalWrite(pwmPin, LOW);
      
      //// DEBUGGING    
      //Serial.print("Midi note: ");
      //Serial.println(noteByte);
      //Serial.print("Velocity: ");
      //Serial.println(velocityByte);
      //// END DEBUGGING

    }
  }
}

// MAIN LOOP
void loop() {
  checkMIDI();
}
