Download the Processing code zip file with classes.

Code for the main tab:

import java.util.Arrays;
import java.lang.reflect.Array;
import processing.serial.*;
import pitaru.sonia_v2_9.*;// Enums
public static final int DISPLAYMODE_PRESTARTSCREEN = 0;
public static final int DISPLAYMODE_STARTSCREEN = 1;
public static final int DISPLAYMODE_ADVANCED_CONFIG = 2;
public static final int DISPLAYMODE_STARTGAME = 3;
public static final int DISPLAYMODE_PRERUNLEVEL = 4;
public static final int DISPLAYMODE_RUNLEVELINTRO = 5;
public static final int DISPLAYMODE_RUNLEVEL = 6;
public static final int DISPLAYMODE_ENDLEVEL = 7;
public static final int DISPLAYMODE_ENDGAME = 8;
public static final int PLATFORM_OSX = 0;
public static final int PLATFORM_WIN = 1;
// Configurable Parameters (not runtime-settable)
String beatSampleFile = "Pop.aiff";
int platform = PLATFORM_OSX;
boolean debug = false;
int displayWidth = 512;
int displayHeight = 512;
int numPlayers = 1;
// Runtime-settable
long levelTime = 30000;
int beatPeriod = 1000;
float allowedDeviation = 0.5;
boolean useDrum;
// State tracking
int displayMode = DISPLAYMODE_PRESTARTSCREEN;
BeatTracker masterBeatTracker;
RhythmPlayer[] players;
// Misc.
Sample metronomeSample; // The sample played on each metronome beat
Serial port; // For connecting to drum HW
PFont verdana10 = createFont("Verdana", 10, true);
PFont verdana15 = createFont("Verdana", 15, true);
PFont verdana30 = createFont("Verdana", 30, true);
void startGame()
{
if (useDrum) {
// Print a list of the serial ports, for debugging purposes to find out what your ports are called:
println(Serial.list());
if (platform == PLATFORM_OSX) {
port = new Serial(this, Serial.list()[2], 19200);
} else {
port = new Serial(this, "COM5", 19200);
}
}
// Create objects for the game
masterBeatTracker = new BeatTracker();
players = new RhythmPlayer[numPlayers];
for (int i = 0; i < numPlayers; i++) {
players[i] = new RhythmPlayer();
}
displayMode = DISPLAYMODE_PRERUNLEVEL;
}
public void setup()
{
size(displayWidth, displayHeight);
noStroke(); // No border on the next thing drawn
// Initialize sound, load samples
Sonia.start(this);

try {
metronomeSample = new Sample(beatSampleFile);
} finally {
if (metronomeSample == null) {
println("Unable to load sample. Please make sure "
+ beatSampleFile + " exists and is in the data directory.");
exit();
}
}
}public void stop()
{
Sonia.stop();
super.stop();
}
int lastDrumVal = 0;
public void serialEvent(Serial port) {
String input = port.readStringUntil(10);

if (input != null) {
// Read the current time as early as possible to minimize errors due to
// latency in getting to the actual processing function
long currentTime = millis();

input = trim(input);

if (debug) {
println("Input from serial: " + input);
}

String strs[] = input.split(" ");
input = strs[1];

int drumVal = Integer.parseInt(input);

// Leave it up to player object to verify the hit is good.
// This way we can potentially calibrate each individually.
players[0].gotDrumHit(drumVal, currentTime);
}
}void draw() {
switch(displayMode) {
case DISPLAYMODE_PRESTARTSCREEN:
preStartScreen();
break;
case DISPLAYMODE_STARTSCREEN:
startScreen();
break;
case DISPLAYMODE_ADVANCED_CONFIG:
case DISPLAYMODE_STARTGAME:
startGame();
break;
case DISPLAYMODE_PRERUNLEVEL:
preRunLevel();
break;
case DISPLAYMODE_RUNLEVELINTRO:
runLevelIntro();
break;
case DISPLAYMODE_RUNLEVEL:
runLevel();
break;
case DISPLAYMODE_ENDLEVEL:
endLevel();
break;
case DISPLAYMODE_ENDGAME:
break;
}
}

 

Arduino Code: