private void loadNotes() {
    int program = 0;
    HashMap<Integer, Float> lastTimeNote = new HashMap<Integer, Float>();
    HashMap<Float, Integer> secondsNotes = new HashMap<Float, Integer>();
    this.notas = new ArrayList<MIDINote>();
    for (Track track : sequencia.getTracks()) {
      for (int c = 0; c < track.size(); ++c) {
        MidiEvent event = track.get(c);
        MidiMessage msg = event.getMessage();
        if (msg instanceof ShortMessage) {
          ShortMessage shortmsg = (ShortMessage) msg;
          if (shortmsg.getCommand() == ShortMessage.PROGRAM_CHANGE) {
            program = shortmsg.getData1();
          } else {
            // }else if(program>=25 && program <= 40){
            // else if(program== 30){
            if (shortmsg.getCommand() == ShortMessage.NOTE_ON) {
              MIDINote midiNote = new MIDINote(event, sequencia, tempoProcessor, program);
              // tocador.start();
              int noteChord = midiNote.getChord();
              float noteSecond = midiNote.getSecond();
              if (!lastTimeNote.containsKey(noteChord)) {
                lastTimeNote.put(noteChord, 0.0f);
              }
              if (noteSecond - lastTimeNote.get(noteChord).floatValue() <= this.interval) {
                continue;
              }
              lastTimeNote.put(noteChord, noteSecond);
              // System.out.println("Play chord "+noteChord+" in "+noteSecond+" seconds");
              notas.add(midiNote);
              if (!secondsNotes.containsKey(noteSecond)) {
                secondsNotes.put(noteSecond, 1);
              }
              secondsNotes.put(noteSecond, secondsNotes.get(noteSecond).intValue() + 1);
            }
          }
        }
      }
    }

    // System.out.println("tamanho da pista "+notas.size()+" e track "+maxNote);
    for (float second : secondsNotes.keySet()) {
      int repeated = secondsNotes.get(second).intValue();
      if (repeated > maxNote) {
        this.maxNote = repeated;
      }
    }
    this.notesLength = secondsNotes.size();
    // GameEngine.getInstance().setFramesPerSecond((int)(((tocador.getMicrosecondLength()/1000000)/(notas.size()*1.0))*4000));
    // System.out.println("(int)(("+sequencia.getMicrosecondLength()+"/1000000)/"+notas.size()+"="+(int)((sequencia.getMicrosecondLength()/1000000)/notas.size()))
  }
  private InputStream writeTrack(Track track, int type)
      throws IOException, InvalidMidiDataException {
    int bytesWritten = 0;
    int lastBytesWritten = 0;
    int size = track.size();
    PipedOutputStream thpos = new PipedOutputStream();
    DataOutputStream thdos = new DataOutputStream(thpos);
    PipedInputStream thpis = new PipedInputStream(thpos);

    ByteArrayOutputStream tdbos = new ByteArrayOutputStream();
    tddos = new DataOutputStream(tdbos);
    ByteArrayInputStream tdbis = null;

    SequenceInputStream fStream = null;

    long currentTick = 0;
    long deltaTick = 0;
    long eventTick = 0;
    int runningStatus = -1;

    // -----------------------------
    // Write each event in the track
    // -----------------------------
    for (int i = 0; i < size; i++) {
      MidiEvent event = track.get(i);

      int status;
      int eventtype;
      int metatype;
      int data1, data2;
      int length;
      byte data[] = null;
      ShortMessage shortMessage = null;
      MetaMessage metaMessage = null;
      SysexMessage sysexMessage = null;

      // get the tick
      // $$jb: this gets easier if we change all system-wide time to delta ticks
      eventTick = event.getTick();
      deltaTick = event.getTick() - currentTick;
      currentTick = event.getTick();

      // get the status byte
      status = event.getMessage().getStatus();
      eventtype = getType(status);

      switch (eventtype) {
        case ONE_BYTE:
          shortMessage = (ShortMessage) event.getMessage();
          data1 = shortMessage.getData1();
          bytesWritten += writeVarInt(deltaTick);

          if (status != runningStatus) {
            runningStatus = status;
            tddos.writeByte(status);
            bytesWritten += 1;
          }
          tddos.writeByte(data1);
          bytesWritten += 1;
          break;

        case TWO_BYTE:
          shortMessage = (ShortMessage) event.getMessage();
          data1 = shortMessage.getData1();
          data2 = shortMessage.getData2();

          bytesWritten += writeVarInt(deltaTick);
          if (status != runningStatus) {
            runningStatus = status;
            tddos.writeByte(status);
            bytesWritten += 1;
          }
          tddos.writeByte(data1);
          bytesWritten += 1;
          tddos.writeByte(data2);
          bytesWritten += 1;
          break;

        case SYSEX:
          sysexMessage = (SysexMessage) event.getMessage();
          length = sysexMessage.getLength();
          data = sysexMessage.getMessage();
          bytesWritten += writeVarInt(deltaTick);

          // $$jb: 04.08.99: always write status for sysex
          runningStatus = status;
          tddos.writeByte(data[0]);
          bytesWritten += 1;

          // $$jb: 10.18.99: we don't maintain length in
          // the message data for SysEx (it is not transmitted
          // over the line), so write the calculated length
          // minus the status byte
          bytesWritten += writeVarInt((data.length - 1));

          // $$jb: 10.18.99: now write the rest of the
          // message
          tddos.write(data, 1, (data.length - 1));
          bytesWritten += (data.length - 1);
          break;

        case META:
          metaMessage = (MetaMessage) event.getMessage();
          length = metaMessage.getLength();
          data = metaMessage.getMessage();
          bytesWritten += writeVarInt(deltaTick);

          // $$jb: 10.18.99: getMessage() returns the
          // entire valid midi message for a file,
          // including the status byte and the var-length-int
          // length value, so we can just write the data
          // here.  note that we must _always_ write the
          // status byte, regardless of runningStatus.
          runningStatus = status;
          tddos.write(data, 0, data.length);
          bytesWritten += data.length;
          break;

        case IGNORE:
          // ignore this event
          break;

        case ERROR:
          // ignore this event
          break;

        default:
          throw new InvalidMidiDataException("internal file writer error");
      }
    }
    // ---------------------------------
    // End write each event in the track
    // ---------------------------------

    // Build Track header now that we know length
    thdos.writeInt(MTrk_MAGIC);
    thdos.writeInt(bytesWritten);
    bytesWritten += 8;

    // Now sequence them
    tdbis = new ByteArrayInputStream(tdbos.toByteArray());
    fStream = new SequenceInputStream(thpis, tdbis);
    thdos.close();
    tddos.close();

    return fStream;
  }