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;
  }
Example #2
0
 public int sendSysex(SysexMessage msg) {
   return sendSysex(msg.getMessage());
 }