Program: 11370
Project: 11370
Buggy source:
/** 
 * Parses MIDI events
 * @param header the header bits
 * @param event the event byte
 */
private void parseMidiEvent(int header,byte event){
  int midiEvent=event & 0xff;
  int timeToWait;
  if (midiState == MIDI_STATE_TIMESTAMP) {
    if ((midiEvent & 0x80) == 0) {
      midiState=MIDI_STATE_WAIT;
    }
  }
  if (midiState == MIDI_STATE_TIMESTAMP) {
    timestamp=((header & 0x3f) << 7) | (midiEvent & 0x7f);
    midiState=MIDI_STATE_WAIT;
  }
 else   if (midiState == MIDI_STATE_WAIT) {
switch (midiEvent & 0xf0) {
case 0xf0:
{
switch (midiEvent) {
case 0xf0:
synchronized (systemExclusiveStream) {
            systemExclusiveStream.reset();
            systemExclusiveStream.write(midiEvent);
            midiState=MIDI_STATE_SIGNAL_SYSEX;
          }
        break;
case 0xf1:
case 0xf3:
      midiEventKind=midiEvent;
    midiState=MIDI_STATE_SIGNAL_2BYTES_2;
  break;
case 0xf2:
midiEventKind=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_2;
break;
case 0xf6:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTuneRequest(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTuneRequest(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf8:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimingClock(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimingClock(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfa:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStart(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStart(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfb:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiContinue(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiContinue(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfc:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStop(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStop(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfe:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiActiveSensing(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiActiveSensing(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xff:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiReset(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiReset(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
default :
break;
}
}
break;
case 0x80:
case 0x90:
case 0xa0:
case 0xb0:
case 0xe0:
midiEventKind=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_2;
break;
case 0xc0:
case 0xd0:
midiEventKind=midiEvent;
midiState=MIDI_STATE_SIGNAL_2BYTES_2;
break;
default :
if ((midiEventKind & 0xf0) != 0xf0) {
midiEventNote=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_3;
}
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_2BYTES_2) {
switch (midiEventKind & 0xf0) {
case 0xc0:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiProgramChange(sender,arg1 & 0xf,arg2);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiProgramChange(sender,midiEventKind & 0xf,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xd0:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiChannelAftertouch(sender,arg1 & 0xf,arg2);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiChannelAftertouch(sender,midiEventKind & 0xf,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf0:
{
switch (midiEventKind) {
case 0xf1:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimeCodeQuarterFrame(sender,arg1);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimeCodeQuarterFrame(sender,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf3:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongSelect(sender,arg1);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongSelect(sender,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_3BYTES_2) {
switch (midiEventKind & 0xf0) {
case 0x80:
case 0x90:
case 0xa0:
case 0xb0:
case 0xe0:
case 0xf0:
midiEventNote=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_3;
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_3BYTES_3) {
switch (midiEventKind & 0xf0) {
case 0x80:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiNoteOff(sender,arg1 & 0xf,arg2,arg3);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiNoteOff(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0x90:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
if (midiEventVelocity == 0) {
midiInputEventListener.onMidiNoteOff(sender,arg1 & 0xf,arg2,arg3);
}
 else {
midiInputEventListener.onMidiNoteOn(sender,arg1 & 0xf,arg2,arg3);
}
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
if (midiEventVelocity == 0) {
midiInputEventListener.onMidiNoteOff(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
 else {
midiInputEventListener.onMidiNoteOn(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xa0:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPolyphonicAftertouch(sender,arg1 & 0xf,arg2,arg3);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPolyphonicAftertouch(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xb0:
midiEventVelocity=midiEvent;
switch (midiEventNote & 0x7f) {
case 98:
parameterNumber&=0x3f80;
parameterNumber|=midiEventVelocity & 0x7f;
parameterMode=PARAMETER_MODE_NRPN;
break;
case 99:
parameterNumber&=0x007f;
parameterNumber|=(midiEventVelocity & 0x7f) << 7;
parameterMode=PARAMETER_MODE_NRPN;
break;
case 100:
parameterNumber&=0x3f80;
parameterNumber|=midiEventVelocity & 0x7f;
parameterMode=PARAMETER_MODE_RPN;
break;
case 101:
parameterNumber&=0x007f;
parameterNumber|=(midiEventVelocity & 0x7f) << 7;
parameterMode=PARAMETER_MODE_RPN;
break;
case 38:
parameterValue&=0x3f80;
parameterValue|=midiEventVelocity & 0x7f;
if (parameterNumber != 0x3fff) {
if (parameterMode == PARAMETER_MODE_RPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
 else if (parameterMode == PARAMETER_MODE_NRPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
}
break;
case 6:
parameterValue&=0x007f;
parameterValue|=(midiEventVelocity & 0x7f) << 7;
if (parameterNumber != 0x3fff) {
if (parameterMode == PARAMETER_MODE_RPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
 else if (parameterMode == PARAMETER_MODE_NRPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
}
break;
default :
break;
}
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiControlChange(sender,arg1 & 0xf,arg2,arg3);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiControlChange(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xe0:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPitchWheel(sender,arg1 & 0xf,(arg2 & 0x7f) | ((arg3 & 0x7f) << 7));
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPitchWheel(sender,midiEventKind & 0xf,(midiEventNote & 0x7f) | ((midiEventVelocity & 0x7f) << 7));
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf0:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongPositionPointer(sender,(arg1 & 0x7f) | ((arg2 & 0x7f) << 7));
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongPositionPointer(sender,(midiEventNote & 0x7f) | ((midiEventVelocity & 0x7f) << 7));
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_SYSEX) {
if (midiEvent == 0xf7) {
synchronized (systemExclusiveStream) {
systemExclusiveStream.write(midiEvent);
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(systemExclusiveStream.toByteArray()){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSystemExclusive(sender,array);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSystemExclusive(sender,systemExclusiveStream.toByteArray());
}
}
}
midiState=MIDI_STATE_TIMESTAMP;
}
 else {
synchronized (systemExclusiveStream) {
systemExclusiveStream.write(midiEvent);
}
}
}
}

Fixed version (ground truth):
/** 
 * Parses MIDI events
 * @param header the header bits
 * @param event the event byte
 */
private void parseMidiEvent(int header,byte event){
  int midiEvent=event & 0xff;
  int timeToWait;
  if (midiState == MIDI_STATE_TIMESTAMP) {
    if ((midiEvent & 0x80) == 0) {
      midiState=MIDI_STATE_WAIT;
    }
    if (midiEvent == 0xf7) {
synchronized (systemExclusiveRecoveryStream) {
        if (systemExclusiveRecoveryStream.size() > 0) {
          int removed=systemExclusiveRecoveryStream.replaceLastByte(midiEvent);
          if (removed >= 0) {
            timestamp=((header & 0x3f) << 7) | (removed & 0x7f);
            timeToWait=calculateTimeToWait(timestamp);
            if (useTimestamp && timeToWait > 0) {
              timer.schedule(new MidiTimerTask(systemExclusiveRecoveryStream.toByteArray()){
                @Override public void run(){
                  if (midiInputEventListener != null) {
                    midiInputEventListener.onMidiSystemExclusive(sender,array);
                  }
                }
              }
,timeToWait);
            }
 else {
              if (midiInputEventListener != null) {
                midiInputEventListener.onMidiSystemExclusive(sender,systemExclusiveRecoveryStream.toByteArray());
              }
            }
          }
          systemExclusiveRecoveryStream.reset();
        }
        midiState=MIDI_STATE_TIMESTAMP;
        return;
      }
    }
 else {
synchronized (systemExclusiveRecoveryStream) {
        if (systemExclusiveRecoveryStream.size() > 0) {
          systemExclusiveRecoveryStream.reset();
        }
      }
    }
  }
  if (midiState == MIDI_STATE_TIMESTAMP) {
    timestamp=((header & 0x3f) << 7) | (midiEvent & 0x7f);
    midiState=MIDI_STATE_WAIT;
  }
 else   if (midiState == MIDI_STATE_WAIT) {
switch (midiEvent & 0xf0) {
case 0xf0:
{
switch (midiEvent) {
case 0xf0:
synchronized (systemExclusiveStream) {
            systemExclusiveStream.reset();
            systemExclusiveStream.write(midiEvent);
            systemExclusiveRecoveryStream.reset();
            midiState=MIDI_STATE_SIGNAL_SYSEX;
          }
        break;
case 0xf1:
case 0xf3:
      midiEventKind=midiEvent;
    midiState=MIDI_STATE_SIGNAL_2BYTES_2;
  break;
case 0xf2:
midiEventKind=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_2;
break;
case 0xf6:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTuneRequest(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTuneRequest(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf8:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimingClock(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimingClock(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfa:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStart(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStart(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfb:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiContinue(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiContinue(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfc:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStop(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiStop(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xfe:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiActiveSensing(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiActiveSensing(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xff:
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiReset(sender);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiReset(sender);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
default :
break;
}
}
break;
case 0x80:
case 0x90:
case 0xa0:
case 0xb0:
case 0xe0:
midiEventKind=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_2;
break;
case 0xc0:
case 0xd0:
midiEventKind=midiEvent;
midiState=MIDI_STATE_SIGNAL_2BYTES_2;
break;
default :
if ((midiEventKind & 0xf0) != 0xf0) {
midiEventNote=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_3;
}
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_2BYTES_2) {
switch (midiEventKind & 0xf0) {
case 0xc0:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiProgramChange(sender,arg1 & 0xf,arg2);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiProgramChange(sender,midiEventKind & 0xf,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xd0:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiChannelAftertouch(sender,arg1 & 0xf,arg2);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiChannelAftertouch(sender,midiEventKind & 0xf,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf0:
{
switch (midiEventKind) {
case 0xf1:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimeCodeQuarterFrame(sender,arg1);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiTimeCodeQuarterFrame(sender,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf3:
midiEventNote=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventNote){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongSelect(sender,arg1);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongSelect(sender,midiEventNote);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_3BYTES_2) {
switch (midiEventKind & 0xf0) {
case 0x80:
case 0x90:
case 0xa0:
case 0xb0:
case 0xe0:
case 0xf0:
midiEventNote=midiEvent;
midiState=MIDI_STATE_SIGNAL_3BYTES_3;
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_3BYTES_3) {
switch (midiEventKind & 0xf0) {
case 0x80:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiNoteOff(sender,arg1 & 0xf,arg2,arg3);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiNoteOff(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0x90:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
if (midiEventVelocity == 0) {
midiInputEventListener.onMidiNoteOff(sender,arg1 & 0xf,arg2,arg3);
}
 else {
midiInputEventListener.onMidiNoteOn(sender,arg1 & 0xf,arg2,arg3);
}
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
if (midiEventVelocity == 0) {
midiInputEventListener.onMidiNoteOff(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
 else {
midiInputEventListener.onMidiNoteOn(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xa0:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPolyphonicAftertouch(sender,arg1 & 0xf,arg2,arg3);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPolyphonicAftertouch(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xb0:
midiEventVelocity=midiEvent;
switch (midiEventNote & 0x7f) {
case 98:
parameterNumber&=0x3f80;
parameterNumber|=midiEventVelocity & 0x7f;
parameterMode=PARAMETER_MODE_NRPN;
break;
case 99:
parameterNumber&=0x007f;
parameterNumber|=(midiEventVelocity & 0x7f) << 7;
parameterMode=PARAMETER_MODE_NRPN;
break;
case 100:
parameterNumber&=0x3f80;
parameterNumber|=midiEventVelocity & 0x7f;
parameterMode=PARAMETER_MODE_RPN;
break;
case 101:
parameterNumber&=0x007f;
parameterNumber|=(midiEventVelocity & 0x7f) << 7;
parameterMode=PARAMETER_MODE_RPN;
break;
case 38:
parameterValue&=0x3f80;
parameterValue|=midiEventVelocity & 0x7f;
if (parameterNumber != 0x3fff) {
if (parameterMode == PARAMETER_MODE_RPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
 else if (parameterMode == PARAMETER_MODE_NRPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
}
break;
case 6:
parameterValue&=0x007f;
parameterValue|=(midiEventVelocity & 0x7f) << 7;
if (parameterNumber != 0x3fff) {
if (parameterMode == PARAMETER_MODE_RPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
 else if (parameterMode == PARAMETER_MODE_NRPN) {
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,parameterNumber,parameterValue){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,arg1 & 0xf,arg2 & 0x3fff,arg3 & 0x3fff);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onNRPNMessage(sender,midiEventKind & 0xf,parameterNumber & 0x3fff,parameterValue & 0x3fff);
}
}
}
}
break;
default :
break;
}
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiControlChange(sender,arg1 & 0xf,arg2,arg3);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiControlChange(sender,midiEventKind & 0xf,midiEventNote,midiEventVelocity);
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xe0:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventKind,midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPitchWheel(sender,arg1 & 0xf,(arg2 & 0x7f) | ((arg3 & 0x7f) << 7));
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiPitchWheel(sender,midiEventKind & 0xf,(midiEventNote & 0x7f) | ((midiEventVelocity & 0x7f) << 7));
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
case 0xf0:
midiEventVelocity=midiEvent;
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(midiEventNote,midiEventVelocity){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongPositionPointer(sender,(arg1 & 0x7f) | ((arg2 & 0x7f) << 7));
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSongPositionPointer(sender,(midiEventNote & 0x7f) | ((midiEventVelocity & 0x7f) << 7));
}
}
midiState=MIDI_STATE_TIMESTAMP;
break;
default :
midiState=MIDI_STATE_TIMESTAMP;
break;
}
}
 else if (midiState == MIDI_STATE_SIGNAL_SYSEX) {
if (midiEvent == 0xf7) {
synchronized (systemExclusiveStream) {
int removed=systemExclusiveStream.replaceLastByte(midiEvent);
if (removed >= 0) {
timestamp=((header & 0x3f) << 7) | (removed & 0x7f);
}
timeToWait=calculateTimeToWait(timestamp);
if (useTimestamp && timeToWait > 0) {
timer.schedule(new MidiTimerTask(systemExclusiveStream.toByteArray()){
@Override public void run(){
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSystemExclusive(sender,array);
}
}
}
,timeToWait);
}
 else {
if (midiInputEventListener != null) {
midiInputEventListener.onMidiSystemExclusive(sender,systemExclusiveStream.toByteArray());
}
}
systemExclusiveStream.replaceLastByte(removed);
systemExclusiveStream.write(midiEvent);
systemExclusiveRecoveryStream.reset();
try {
systemExclusiveRecoveryStream.write(systemExclusiveStream.toByteArray());
}
 catch (IOException ignored) {
}
}
midiState=MIDI_STATE_TIMESTAMP;
}
 else {
synchronized (systemExclusiveStream) {
systemExclusiveStream.write(midiEvent);
}
}
}
}