/*
 * DuckyMIDI Controller - v1.0
 * 17-key duck-themed MIDI drumpad
 */

#include <Adafruit_TinyUSB.h>
#include <MIDI.h>

Adafruit_USBD_MIDI usb_midi;
MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI);

const byte PAD_PINS[17] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

const byte MIDI_NOTES[17] = {
  36,
  38,
  42,
  46,
  48,
  50,
  45,
  47,
  49,
  51,
  52,
  53,
  54,
  55,
  56,
  57,
  58
};

byte velocity = 100;
byte midiChannel = 10;

bool padStates[17] = {false};
bool lastPadStates[17] = {false};
unsigned long lastDebounceTime[17] = {0};
const unsigned long DEBOUNCE_DELAY = 10;

void setup() {
  usb_midi.setStringDescriptor("DuckyMIDI");
  MIDI.begin(MIDI_CHANNEL_OMNI);

  for (int i = 0; i < 17; i++) {
    pinMode(PAD_PINS[i], INPUT_PULLUP);
  }
}

void loop() {
  unsigned long now = millis();

  for (int i = 0; i < 17; i++) {
    bool reading = (digitalRead(PAD_PINS[i]) == LOW);

    if (reading != lastPadStates[i]) {
      lastDebounceTime[i] = now;
    }

    if ((now - lastDebounceTime[i]) > DEBOUNCE_DELAY) {
      if (reading != padStates[i]) {
        padStates[i] = reading;

        if (padStates[i]) {
          MIDI.sendNoteOn(MIDI_NOTES[i], velocity, midiChannel);
        } else {
          MIDI.sendNoteOff(MIDI_NOTES[i], 0, midiChannel);
        }
      }
    }

    lastPadStates[i] = reading;
  }

  MIDI.read();
}
