/**
   * Write a track to an output stream.
   *
   * @param track the track to write
   * @param dos a MidiDataOutputStream to write to
   * @return the number of bytes written
   */
  private int writeTrack(Track track, MidiDataOutputStream dos) throws IOException {
    int i = 0, elength = track.size(), trackLength;
    MidiEvent pme = null;
    dos.writeInt(0x4d54726b); // "MTrk"
    trackLength = computeTrackLength(track, dos);
    dos.writeInt(trackLength);
    while (i < elength) {
      MidiEvent me = track.get(i);
      int dtime = 0;
      if (pme != null) dtime = (int) (me.getTick() - pme.getTick());
      dos.writeVariableLengthInt(dtime);
      // FIXME: use running status byte
      byte msg[] = me.getMessage().getMessage();
      dos.write(msg);
      pme = me;
      i++;
    }

    // We're done if the last event was an End of Track meta message.
    if (pme != null && (pme.getMessage() instanceof MetaMessage)) {
      MetaMessage mm = (MetaMessage) pme.getMessage();
      if (mm.getType() == 0x2f) // End of Track message
      return trackLength + 8;
    }

    // Write End of Track meta message
    dos.writeVariableLengthInt(0); // Delta time of 0
    dos.writeByte(0xff); // Meta Message
    dos.writeByte(0x2f); // End of Track message
    dos.writeVariableLengthInt(0); // Length of 0

    return trackLength + 8 + 4;
  }
 /**
  * Compute the length of a track as it will be written to the output stream.
  *
  * @param track the track to measure
  * @param dos a MidiDataOutputStream used for helper method
  * @return the length of the track
  */
 private int computeTrackLength(Track track, MidiDataOutputStream dos) {
   int count = 0, length = 0, i = 0, eventCount = track.size();
   long ptick = 0;
   while (i < eventCount) {
     MidiEvent me = track.get(i);
     long tick = me.getTick();
     length += dos.variableLengthIntLength((int) (tick - ptick));
     ptick = tick;
     length += me.getMessage().getLength();
     i++;
   }
   return length;
 }
 /* Write a sequence to an output stream in standard midi format.
  * @see javax.sound.midi.spi.MidiFileWriter#write(javax.sound.midi.Sequence, int, java.io.OutputStream)
  */
 public int write(Sequence in, int fileType, OutputStream out) throws IOException {
   MidiDataOutputStream dos = new MidiDataOutputStream(out);
   Track[] tracks = in.getTracks();
   dos.writeInt(0x4d546864); // MThd
   dos.writeInt(6);
   dos.writeShort(fileType);
   dos.writeShort(tracks.length);
   float divisionType = in.getDivisionType();
   int resolution = in.getResolution();
   // FIXME: division computation is incomplete.
   int division = 0;
   if (divisionType == Sequence.PPQ) division = resolution & 0x7fff;
   dos.writeShort(division);
   int length = 14;
   for (Track track : tracks) length += writeTrack(track, dos);
   return length;
 }