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