Hi,

I wrote this program to make some use out of my old guitar hero controller, but there is a bit of a delay when I want to play a note or chord. I know this isn't because of the controller because I set up a simple JFrame containing a JButton to play a chord and the delay is still present. How can I make this more efficient?

driver.java
Java Code:
import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;
import net.java.games.input.Event;
import net.java.games.input.EventQueue;

public class driver {

	// these must be static final
	static final String A = "A";
	static final String B = "B";
	static final String C = "C";
	static final String X = "X";
	static final String Y = "Y";
	static final String Z = "z";
	static final String LT = "Left Thumb 2";
	static final String RT = "Right Thumb 2";
	static final String PS = "Mode";
	static final String POV = "pov";
	static int curInst = 27; // 27 is Guitar
	
	static Controller controller = null;
	private static boolean[] state = new boolean[] {false, false, false, false, false}; // array of buttons (true means button is pressed)

	public static void main(String[] args) {
		
		Controller[] controllerArray = ControllerEnvironment.getDefaultEnvironment().getControllers();
		if (controllerArray.length == 0) {
			System.out.println("Found no controllers.");
			System.exit(0);
		}
		else if (controllerArray.length == 1) { // only one controller
			controller = controllerArray[0];
		}
		else { System.out.println("FIX ME"); }
		
		final OpenInstrument myInstrument = new OpenInstrument();
		myInstrument.SetInstrument(curInst, 1);
		myInstrument.SetInstrument(curInst, 2);
		
		while (true) {
			controller.poll();
			EventQueue queue = controller.getEventQueue();
			Event event = new Event();

			while (queue.getNextEvent(event)) {
				
				Component comp = event.getComponent();
				final String name = comp.getName();
				float value = event.getValue();

				//System.out.println(name + " " + value);
				
				// The following code uses static final Strings
				// for comparison in order to use the == operator instead of .equals()
				if (name == Z)
					myInstrument.setPitchBend(value);
				else if (name == A)
					state[0] = (value == 1.0f);
				else if (name == B)
					state[1] = (value == 1.0f);
				else if (name == C)
					state[2] = (value == 1.0f);
				else if (name == X)
					state[3] = (value == 1.0f);
				else if (name == Y)
					state[4] = (value == 1.0f);
				else if (name == POV) {
					
					if (value == 0.75f) { // strum bar DOWN
						new Thread( new Runnable() { public void run() {
							if (state[1] && state[2] && state[0] && !state[3] && !state[4])
								myInstrument.playChord(new int[]{50, 57, 62, 66});			// D
							else if (!state[1] && !state[2] && state[0] && state[3] && state[4])
								myInstrument.playChord(new int[]{40, 47, 52, 55, 59, 64});	// Em
							else if (!state[1] && state[2] && !state[0] && state[3] && state[4])
								myInstrument.playChord(new int[]{42, 49, 54, 61, 66});		// F#m
							else if (state[1] && state[2] && state[0] && state[3] && !state[4])
								myInstrument.playChord(new int[]{43, 47, 50, 55, 62, 67});	// G
							else if (!state[1] && state[2] && state[0] && state[3] && !state[4])
								myInstrument.playChord(new int[]{45, 52, 57, 61, 64});		// A
							else if (state[1] && !state[2] && state[0] && state[3] && !state[4])
								myInstrument.playChord(new int[]{42, 47, 54, 59, 62, 66});	// Bm
							else if (!state[1] && state[2] && state[0] && state[3] && state[4])
								myInstrument.playChord(new int[]{49, 55, 61, 64});			// C#dim
							
							// individual notes
							else if (state[4])
								myInstrument.playNote(47);
							else if (state[3])
								myInstrument.playNote(45);
							else if (state[0])
								myInstrument.playNote(43);
							else if (state[2])
								myInstrument.playNote(42);
							else if (state[1])
								myInstrument.playNote(40);
						} }).start();
					}
					else if (value == 0.25f) { // strum bar UP
						new Thread( new Runnable() { public void run() {
							if (state[1] && state[2] && state[0] && !state[3] && !state[4])
								myInstrument.playChord(new int[]{50, 57, 62, 66});			// D
							else if (!state[1] && !state[2] && state[0] && state[3] && state[4])
								myInstrument.playChord(new int[]{40, 47, 52, 55, 59, 64});	// Em
							else if (!state[1] && state[2] && !state[0] && state[3] && state[4])
								myInstrument.playChord(new int[]{42, 49, 54, 61, 66});		// F#m
							else if (state[1] && state[2] && state[0] && state[3] && !state[4])
								myInstrument.playChord(new int[]{43, 47, 50, 55, 62, 67});	// G
							else if (!state[1] && state[2] && state[0] && state[3] && !state[4])
								myInstrument.playChord(new int[]{45, 52, 57, 61, 64});		// A
							else if (state[1] && !state[2] && state[0] && state[3] && !state[4])
								myInstrument.playChord(new int[]{42, 47, 54, 59, 62, 66});	// Bm
							else if (!state[1] && state[2] && state[0] && state[3] && state[4])
								myInstrument.playChord(new int[]{49, 55, 61, 64});			// C#dim
							
							// individual notes
							else if (state[4])
								myInstrument.playNote(57);
							else if (state[3])
								myInstrument.playNote(55);
							else if (state[0])
								myInstrument.playNote(54);
							else if (state[2])
								myInstrument.playNote(52);
							else if (state[1])
								myInstrument.playNote(50);
						} }).start();
					}
					else if (value == 1.0f) { //change pitch of instrument (lower)
						if (!state[1] && !state[2] && !state[0] && !state[3] && !state[4]) {
							myInstrument.setTranspose(myInstrument.getTranspose()-1); // half step
						}
						else {
							myInstrument.setTranspose(myInstrument.getTranspose()-12); //octave
						}
					}
					else if (value == 0.5f) {//change pitch of instrument (higher)
						if (!state[1] && !state[2] && !state[0] && !state[3] && !state[4]) {
							myInstrument.setTranspose(myInstrument.getTranspose()+1); // half step
						}
						else {
							myInstrument.setTranspose(myInstrument.getTranspose()+12); //octave
						}
					}
				}
				// cycle through instruments
				else if (name == LT && value == 1.0f) {
					if (curInst == 0) {
						curInst = myInstrument.instrs.length-1;
					}
					else {
						curInst--;	
					}
					myInstrument.SetInstrument(curInst, 1);
					myInstrument.SetInstrument(curInst, 2);
					System.out.println(myInstrument.instrs[curInst].getName());
				}
				// cycle through instruments
				else if (name == RT && value == 1.0f) {
					if (curInst == myInstrument.instrs.length-1) {
						curInst = 0;
					}
					else {
						curInst++;	
					}
					myInstrument.SetInstrument(curInst, 1);
					myInstrument.SetInstrument(curInst, 2);
					System.out.println(myInstrument.instrs[curInst].getName());
				}
				//reset to defaults
				else if (name == PS && value == 1.0f) {
					curInst = 27;
					myInstrument.SetInstrument(curInst, 1);
					myInstrument.SetInstrument(curInst, 2);
					myInstrument.setTranspose(0);
				}
				
			}

		}

	}

}
OpenInstrument.java
Java Code:
import javax.sound.midi.Instrument;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Patch;
import javax.sound.midi.Soundbank;
import javax.sound.midi.Synthesizer;

public class OpenInstrument {
	
	Synthesizer synth;
	MidiChannel channels[];
	Soundbank bank;
	public Instrument instrs[];
	Instrument myInstrument;
	Patch myPatch;
	int trans = 0;
	long delay = 50;
	
	OpenInstrument() {
		try
        {
        	// Locate the default synthesizer
            synth = MidiSystem.getSynthesizer();
            // Open the synthesizer
            synth.open();
            // Get the available Midi channels - there are usually 16
            channels = synth.getChannels();
            // Get the synth's soundbank where all the sounds are stored
            bank = synth.getDefaultSoundbank();
    		// Load all the available instruments
            synth.loadAllInstruments(bank); 
    		// Get a list of the available instruments
            instrs = synth.getLoadedInstruments();
        }
		catch (Exception exc) {	exc.printStackTrace(); }
	}
	
	public void PrintInstrumentList() {
		for (int i = 0; i < instrs.length; i++) {
            System.out.println(i + ") " + instrs[i].getName());
        }
	}
	
	public void SetInstrument(int instrumentNum, int channelNum) {
		myInstrument = instrs[instrumentNum];		
		// Get the information describing the instrument - the
        // patch contains the sound bank and program number
        myPatch = myInstrument.getPatch();
		// Set a channel to use the specfied instrument
        channels[channelNum].programChange(myPatch.getBank(),myPatch.getProgram());
        channels[1].allNotesOff();
		channels[2].allNotesOff();
	}
	
	public void playChord(int[] chord) {
		try {
			channels[1].allNotesOff();
			channels[2].allNotesOff();
			for (int i = 0; i < chord.length; i++) {
				channels[1].noteOn(chord[i]+trans, 127);
				Thread.sleep(delay);
			}
    	}
		catch (Exception exc) {	exc.printStackTrace(); }
	}
	
	public void playNote(int note) {
		try {
			channels[2].allNotesOff();
			channels[2].noteOn(note+trans, 127);
    	}
		catch (Exception exc) {	exc.printStackTrace(); }
	}
	
	public void setPitchBend(float bend) {
		int value = (int)(bend * 8191 + 8192);
		channels[1].setPitchBend(value); // 16383 max, 8192 normal
		channels[2].setPitchBend(value); // 16383 max, 8192 normal
	}
	
	public void setTranspose(int value) {
		trans = value;
	}
	
	public int getTranspose() {
		return trans;
	}
		
	public void close() {
		// Close the synthesizer device
        synth.close();
	}
	
}