/ Guitar_Hero_MIDI / Guitar_Hero_MIDI.ino
Guitar_Hero_MIDI.ino
  1  // SPDX-FileCopyrightText: 2021 John Park for Adafruit Industries
  2  //
  3  // SPDX-License-Identifier: MIT
  4  
  5  //Wii Guitar Hero MIDI Controller
  6  // by John Park for Adafruit Industries
  7  #include <WiiChuck.h>
  8  #include <Adafruit_TinyUSB.h>
  9  #include <MIDI.h>
 10  
 11  Accessory guitar;
 12  Adafruit_USBD_MIDI usb_midi;
 13  MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI);
 14  
 15  int MIDI_OUT_CH = 1;  // pick your midi output channel here
 16  bool DEBUG = 0;  // set to 1 to use serial monitor to check out controller values
 17  
 18  int whammyBar;
 19  int joyX;
 20  int joyY;
 21  int minusButton;  // drop an octave w each press
 22  int plusButton;  // up and octave w each press
 23  int strumDown;
 24  int strumUp;
 25  int fretButtons[5];
 26  
 27  bool minusButtonOn = 0;
 28  bool plusButtonOn = 0;
 29  bool strumDownOn = 0;
 30  bool strumUpOn = 0;
 31  bool fretButtonOn[] = {0, 0, 0, 0, 0};
 32  
 33  int octave = 12;  // note offset value, used to change octaves
 34  
 35  int strumDownChord[] = {36, 40, 43, 45};  //all note values will be offset by octave value
 36  int strumUpChord[] = {36, 41, 43, 45} ;
 37  int fretNotes[] = {24, 26, 28, 29, 31};
 38  
 39  int lastWhammy = 16;  // Use the resting state value of your whammy bar
 40  int whammyPitchVal = 8192;  // resting position of pitchwheel
 41  
 42  int lastJoyX = 223;  // resting value of joyX
 43  int joyXCCNum = 71; // VCF or whatever you assign in synth software
 44  int joyXCCVal = 0;
 45  int lastJoyY = 224;  // resting value of joyY
 46  int joyYCCNum = 72; // VCA
 47  int joyYCCVal = 0;
 48  
 49  void setup() {
 50    Serial.begin(115200);
 51    MIDI.begin(MIDI_CHANNEL_OMNI);
 52    guitar.begin();
 53    guitar.type = GuitarHeroController;
 54  }
 55  
 56  void loop() {
 57    guitar.readData();    // Read inputs and update maps
 58    fretButtons[0] = guitar.values[10];  // green
 59    fretButtons[1] = guitar.values[11];  // red
 60    fretButtons[2] = guitar.values[12];  // yellow
 61    fretButtons[3] = guitar.values[13];  //blue
 62    fretButtons[4] = guitar.values[14]; // orange
 63    minusButton = guitar.values[6];
 64    plusButton = guitar.values[16];
 65    strumDown = guitar.values[7];
 66    strumUp = guitar.values[7];
 67    whammyBar = guitar.values[0];
 68    joyX = guitar.values[20];
 69    joyY = guitar.values[21];
 70  
 71    for(int i=0;i<5;i++){
 72      if(fretButtons[i]==255 && fretButtonOn[i]==0){
 73        MIDI.sendNoteOn(fretNotes[i]+octave, 127, MIDI_OUT_CH);
 74        fretButtonOn[i] = 1;}
 75      if(fretButtons[i]==0 && fretButtonOn[i]==1){
 76        MIDI.sendNoteOff(fretNotes[i]+octave, 0, MIDI_OUT_CH);
 77        fretButtonOn[i] = 0;}
 78      }
 79  
 80    if(whammyBar!=lastWhammy){
 81      whammyPitchVal=map(whammyBar, 15, 26, 8192, 16383); // remap to pitch value range, two semitones here
 82      MIDI.sendPitchBend(whammyPitchVal, MIDI_OUT_CH);
 83      lastWhammy=whammyBar;
 84    }
 85    if(joyX!=lastJoyX){
 86      joyXCCVal=map(joyX, 190, 255, 0, 127); // remap to bigger range
 87      MIDI.sendControlChange(joyXCCNum, joyXCCVal, MIDI_OUT_CH);
 88      lastJoyX=joyX;
 89    }
 90    if(joyY!=lastJoyY){
 91      joyYCCVal=map(joyY, 190, 255, 0, 127); // remap to bigger range
 92      MIDI.sendControlChange(joyYCCNum, joyYCCVal, MIDI_OUT_CH);
 93      lastJoyY=joyY;
 94    }
 95  
 96    if(minusButton==0 && minusButtonOn==0){
 97      octave = constrain((octave - 12), 0, 108);
 98      minusButtonOn = 1;}
 99    if(minusButton==128 && minusButtonOn==1){
100      minusButtonOn = 0;}
101  
102    if(plusButton==255 && plusButtonOn==0){
103      octave = constrain((octave + 12), 0, 108);
104      plusButtonOn = 1;}
105    if(plusButton==0 && plusButtonOn==1){
106      plusButtonOn = 0;}
107  
108    if(strumDown==0 && strumDownOn==0){
109      for(int c=0; c<4; c++){
110        MIDI.sendNoteOn(strumDownChord[c]+octave, 127, MIDI_OUT_CH);}
111      strumDownOn = 1;}
112    if(strumDown==128 && strumDownOn==1){
113      for(int c=0; c<4; c++){
114        MIDI.sendNoteOff(strumDownChord[c]+octave, 0, MIDI_OUT_CH);}
115      strumDownOn = 0;}
116  
117    if(strumUp==255 && strumUpOn==0){
118      for(int c=0; c<4; c++){
119        MIDI.sendNoteOn(strumUpChord[c]+octave, 127, MIDI_OUT_CH);}
120      strumUpOn = 1;}
121    if(strumUp==128 && strumUpOn==1){
122      for(int c=0; c<4; c++){
123        MIDI.sendNoteOff(strumUpChord[c]+octave, 0, MIDI_OUT_CH);}
124      strumUpOn = 0;}
125  
126    delay(5);
127  
128    if(DEBUG){
129      Serial.println("-------------------------------------------");
130      guitar.printInputs();
131      for (int i = 0; i < WII_VALUES_ARRAY_SIZE+3; i++) {
132        Serial.println(
133            "Controller Val " + String(i) + " = "
134                + String((uint8_t) guitar.values[i]));
135      }
136      delay(50);  // keeps the terminal from flooding
137    }
138  }