< prev index next >

src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java

Print this page


   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 


< prev index next >