1 /*
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
57
58 private static final int MThd_MAGIC = 0x4d546864; // 'MThd'
59 private static final int MTrk_MAGIC = 0x4d54726b; // 'MTrk'
60
61 private static final int ONE_BYTE = 1;
62 private static final int TWO_BYTE = 2;
63 private static final int SYSEX = 3;
64 private static final int META = 4;
65 private static final int ERROR = 5;
66 private static final int IGNORE = 6;
67
68 private static final int MIDI_TYPE_0 = 0;
69 private static final int MIDI_TYPE_1 = 1;
70
71 private static final int bufferSize = 16384; // buffersize for write
72 private DataOutputStream tddos; // data output stream for track writing
73
74 /**
75 * MIDI parser types.
76 */
77 private static final int types[] = {
78 MIDI_TYPE_0,
79 MIDI_TYPE_1
80 };
81
82 @Override
83 public int[] getMidiFileTypes() {
84 int[] localArray = new int[types.length];
85 System.arraycopy(types, 0, localArray, 0, types.length);
86 return localArray;
87 }
88
89 /**
90 * Obtains the file types that this provider can write from the
91 * sequence specified.
92 * @param sequence the sequence for which midi file type support
93 * is queried
94 * @return array of file types. If no file types are supported,
95 * returns an array of length 0.
96 */
97 @Override
98 public int[] getMidiFileTypes(Sequence sequence){
99 int typesArray[];
100 Track tracks[] = sequence.getTracks();
101
102 if( tracks.length==1 ) {
103 typesArray = new int[2];
104 typesArray[0] = MIDI_TYPE_0;
105 typesArray[1] = MIDI_TYPE_1;
106 } else {
107 typesArray = new int[1];
108 typesArray[0] = MIDI_TYPE_1;
109 }
110
111 return typesArray;
112 }
113
114 @Override
115 public int write(Sequence in, int type, OutputStream out) throws IOException {
116 Objects.requireNonNull(out);
117 if (!isFileTypeSupported(type, in)) {
118 throw new IllegalArgumentException("Could not write MIDI file");
119 }
120 byte [] buffer = null;
132 while( (bytesRead = fileStream.read( buffer )) >= 0 ) {
133 out.write( buffer, 0, bytesRead );
134 bytesWritten += bytesRead;
135 }
136 // Done....return bytesWritten
137 return (int) bytesWritten;
138 }
139
140 @Override
141 public int write(Sequence in, int type, File out) throws IOException {
142 Objects.requireNonNull(in);
143 FileOutputStream fos = new FileOutputStream(out); // throws IOException
144 int bytesWritten = write( in, type, fos );
145 fos.close();
146 return bytesWritten;
147 }
148
149 //=================================================================================
150
151 private InputStream getFileStream(int type, Sequence sequence) throws IOException {
152 Track tracks[] = sequence.getTracks();
153 int bytesBuilt = 0;
154 int headerLength = 14;
155 int length = 0;
156 int timeFormat;
157 float divtype;
158
159 PipedOutputStream hpos = null;
160 DataOutputStream hdos = null;
161 PipedInputStream headerStream = null;
162
163 InputStream trackStreams [] = null;
164 InputStream trackStream = null;
165 InputStream fStream = null;
166
167 // Determine the filetype to write
168 if( type==MIDI_TYPE_0 ) {
169 if (tracks.length != 1) {
170 return null;
171 }
172 } else if( type==MIDI_TYPE_1 ) {
173 if (tracks.length < 1) { // $$jb: 05.31.99: we _can_ write TYPE_1 if tracks.length==1
174 return null;
175 }
176 } else {
177 if(tracks.length==1) {
178 type = MIDI_TYPE_0;
179 } else if(tracks.length>1) {
180 type = MIDI_TYPE_1;
181 } else {
182 return null;
183 }
327 ByteArrayInputStream tdbis = null;
328
329 SequenceInputStream fStream = null;
330
331 long currentTick = 0;
332 long deltaTick = 0;
333 long eventTick = 0;
334 int runningStatus = -1;
335
336 // -----------------------------
337 // Write each event in the track
338 // -----------------------------
339 for(int i=0; i<size; i++) {
340 MidiEvent event = track.get(i);
341
342 int status;
343 int eventtype;
344 int metatype;
345 int data1, data2;
346 int length;
347 byte data[] = null;
348 ShortMessage shortMessage = null;
349 MetaMessage metaMessage = null;
350 SysexMessage sysexMessage = null;
351
352 // get the tick
353 // $$jb: this gets easier if we change all system-wide time to delta ticks
354 eventTick = event.getTick();
355 deltaTick = event.getTick() - currentTick;
356 currentTick = event.getTick();
357
358 // get the status byte
359 status = event.getMessage().getStatus();
360 eventtype = getType( status );
361
362 switch( eventtype ) {
363 case ONE_BYTE:
364 shortMessage = (ShortMessage) event.getMessage();
365 data1 = shortMessage.getData1();
366 bytesWritten += writeVarInt( deltaTick );
367
|
1 /*
2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
57
58 private static final int MThd_MAGIC = 0x4d546864; // 'MThd'
59 private static final int MTrk_MAGIC = 0x4d54726b; // 'MTrk'
60
61 private static final int ONE_BYTE = 1;
62 private static final int TWO_BYTE = 2;
63 private static final int SYSEX = 3;
64 private static final int META = 4;
65 private static final int ERROR = 5;
66 private static final int IGNORE = 6;
67
68 private static final int MIDI_TYPE_0 = 0;
69 private static final int MIDI_TYPE_1 = 1;
70
71 private static final int bufferSize = 16384; // buffersize for write
72 private DataOutputStream tddos; // data output stream for track writing
73
74 /**
75 * MIDI parser types.
76 */
77 private static final int[] types = {
78 MIDI_TYPE_0,
79 MIDI_TYPE_1
80 };
81
82 @Override
83 public int[] getMidiFileTypes() {
84 int[] localArray = new int[types.length];
85 System.arraycopy(types, 0, localArray, 0, types.length);
86 return localArray;
87 }
88
89 /**
90 * Obtains the file types that this provider can write from the
91 * sequence specified.
92 * @param sequence the sequence for which midi file type support
93 * is queried
94 * @return array of file types. If no file types are supported,
95 * returns an array of length 0.
96 */
97 @Override
98 public int[] getMidiFileTypes(Sequence sequence){
99 int[] typesArray;
100 Track[] tracks = sequence.getTracks();
101
102 if( tracks.length==1 ) {
103 typesArray = new int[2];
104 typesArray[0] = MIDI_TYPE_0;
105 typesArray[1] = MIDI_TYPE_1;
106 } else {
107 typesArray = new int[1];
108 typesArray[0] = MIDI_TYPE_1;
109 }
110
111 return typesArray;
112 }
113
114 @Override
115 public int write(Sequence in, int type, OutputStream out) throws IOException {
116 Objects.requireNonNull(out);
117 if (!isFileTypeSupported(type, in)) {
118 throw new IllegalArgumentException("Could not write MIDI file");
119 }
120 byte [] buffer = null;
132 while( (bytesRead = fileStream.read( buffer )) >= 0 ) {
133 out.write( buffer, 0, bytesRead );
134 bytesWritten += bytesRead;
135 }
136 // Done....return bytesWritten
137 return (int) bytesWritten;
138 }
139
140 @Override
141 public int write(Sequence in, int type, File out) throws IOException {
142 Objects.requireNonNull(in);
143 FileOutputStream fos = new FileOutputStream(out); // throws IOException
144 int bytesWritten = write( in, type, fos );
145 fos.close();
146 return bytesWritten;
147 }
148
149 //=================================================================================
150
151 private InputStream getFileStream(int type, Sequence sequence) throws IOException {
152 Track[] tracks = sequence.getTracks();
153 int bytesBuilt = 0;
154 int headerLength = 14;
155 int length = 0;
156 int timeFormat;
157 float divtype;
158
159 PipedOutputStream hpos = null;
160 DataOutputStream hdos = null;
161 PipedInputStream headerStream = null;
162
163 InputStream[] trackStreams = null;
164 InputStream trackStream = null;
165 InputStream fStream = null;
166
167 // Determine the filetype to write
168 if( type==MIDI_TYPE_0 ) {
169 if (tracks.length != 1) {
170 return null;
171 }
172 } else if( type==MIDI_TYPE_1 ) {
173 if (tracks.length < 1) { // $$jb: 05.31.99: we _can_ write TYPE_1 if tracks.length==1
174 return null;
175 }
176 } else {
177 if(tracks.length==1) {
178 type = MIDI_TYPE_0;
179 } else if(tracks.length>1) {
180 type = MIDI_TYPE_1;
181 } else {
182 return null;
183 }
327 ByteArrayInputStream tdbis = null;
328
329 SequenceInputStream fStream = null;
330
331 long currentTick = 0;
332 long deltaTick = 0;
333 long eventTick = 0;
334 int runningStatus = -1;
335
336 // -----------------------------
337 // Write each event in the track
338 // -----------------------------
339 for(int i=0; i<size; i++) {
340 MidiEvent event = track.get(i);
341
342 int status;
343 int eventtype;
344 int metatype;
345 int data1, data2;
346 int length;
347 byte[] data = null;
348 ShortMessage shortMessage = null;
349 MetaMessage metaMessage = null;
350 SysexMessage sysexMessage = null;
351
352 // get the tick
353 // $$jb: this gets easier if we change all system-wide time to delta ticks
354 eventTick = event.getTick();
355 deltaTick = event.getTick() - currentTick;
356 currentTick = event.getTick();
357
358 // get the status byte
359 status = event.getMessage().getStatus();
360 eventtype = getType( status );
361
362 switch( eventtype ) {
363 case ONE_BYTE:
364 shortMessage = (ShortMessage) event.getMessage();
365 data1 = shortMessage.getData1();
366 bytesWritten += writeVarInt( deltaTick );
367
|