Xbox 360 drum controller as MIDI device
A recently acquired Xbox 360 drum controller proved to be one of the easiest retro interface designs ever. The setup comes standard with a MIDI out! In order to connect it to an Akai MPX8 sampler, a slight re-mapping of MIDI note numbers (can also be done in the sampler) and adjustment of velocity levels was necessary. For this purpose an Arduino Uno with SparkFun MIDI shield have been added..
The code in the Arduino device is pretty straightforward:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
///////////////////////////////////////////////////////////////////////// // MIDI shield on Arduino Uno as midi converter/amplifier // For MicroSoft Xbox360 drum controller // // The Xbox midi output is connected to the input of the shield, // midi notes are being re-mapped and velocity is scaled // // Xbox drum controller sends out the following MIDI notes: // yellow [46] orange [49] // // red [38] blue [48] green [45] // // kick [36] // // only note on (153, 0x99), only velocity between [30 - 80] // so the MIDI input for a kick could be 153 36 70 // // The potentiometers on the MIDI shield control the maximum output // velocity level and an amplification of the velocity between [1..2] // // (cc) e13, June 2016 ///////////////////////////////////////////////////////////////////////// #include <SoftwareSerial.h> SoftwareSerial mySerial(8, 9); // RX, TX for MIDI //#define DEBUG // for serial debug output void setup() { Serial.begin(9600); // debug output // set the data rate for the SoftwareSerial port mySerial.begin(31250); } #define NOTENUMBER 1 #define NOTEON 0 #define VELOCITY 2 int mode; int notenumber, notevelocity; int knobA, knobB; int newdata = 0; void loop() { if (mySerial.available()) { int value = mySerial.read(); if (mode == NOTEON && value == 153) { //hex 0x99: MIDI note on mode = NOTENUMBER; } else if (mode == NOTENUMBER) { notenumber = value; mode = VELOCITY; } else if (mode == VELOCITY) { mode = NOTEON; notevelocity = value; newdata = 1; } } if (newdata > 0) { newdata = 0; switch (notenumber) { // switch case allows for indiviual mapping of drum pads.. case 36: sendMIDI(153, 36, constrain(map(knobB*notevelocity/64, 30, 75, 30, knobA / 8), 0, 127)); break; case 38: sendMIDI(153, 37, constrain(map(knobB*notevelocity/64, 30, 75, 30, knobA / 8), 0, 127)); break; case 48: sendMIDI(153, 38, constrain(map(knobB*notevelocity/64, 30, 75, 30, knobA / 8), 0, 127)); break; case 45: sendMIDI(153, 39, constrain(map(knobB*notevelocity/64, 30, 75, 30, knobA / 8), 0, 127)); break; case 46: sendMIDI(153, 40, constrain(map(knobB*notevelocity/64,30,75,30, knobA / 8),0,127)); break; case 49: sendMIDI(153, 43, constrain(map(knobB*notevelocity/64,30,75,30, knobA / 8),0,127)); break; default: break; } } knobA = analogRead(A0); // set the limit(0-127) for velocity knobB = 64+analogRead(A1)/16; // amplify the velocity, max 2* } void sendMIDI(int channel, int value, int velocity) { mySerial.write(channel); mySerial.write(value); mySerial.write(velocity); #ifdef DEBUG Serial.print(channel); Serial.print(' '); Serial.print(value); Serial.print(' '); Serial.println(velocity); #endif } |
Write a Reply or Comment