Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 2007, 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
   23    * questions.
   24    */
   25   package com.sun.media.sound;
   26   
   27   import java.io.File;
   28   import java.io.IOException;
   29   import java.io.InputStream;
   30   import java.net.URL;
   31   
   32   import javax.sound.midi.InvalidMidiDataException;
   33   import javax.sound.midi.MetaMessage;
   34   import javax.sound.midi.MidiEvent;
   35   import javax.sound.midi.MidiMessage;
   36   import javax.sound.midi.MidiSystem;
   37   import javax.sound.midi.MidiUnavailableException;
   38   import javax.sound.midi.Receiver;
   39   import javax.sound.midi.Sequence;
   40   import javax.sound.midi.Track;
   41   import javax.sound.sampled.AudioFileFormat;
   42   import javax.sound.sampled.AudioFormat;
   43   import javax.sound.sampled.AudioInputStream;
   44   import javax.sound.sampled.UnsupportedAudioFileException;
   45   import javax.sound.sampled.AudioFileFormat.Type;
   46   import javax.sound.sampled.spi.AudioFileReader;
   47   
   48   /**
   49    * MIDI File Audio Renderer/Reader
   50    *
   51    * @author Karl Helgason
   52    */
   53   public class SoftMidiAudioFileReader extends AudioFileReader {
   54   
   55       public static final Type MIDI = new Type("MIDI", "mid");
   56       private static AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
   57   
   58       public AudioFileFormat getAudioFileFormat(Sequence seq)
   59               throws UnsupportedAudioFileException, IOException {
   60   
   61           long totallen = seq.getMicrosecondLength() / 1000000;
   62           long len = (long) (format.getFrameRate() * (totallen + 4));
   63           return new AudioFileFormat(MIDI, format, (int) len);
   64       }
   65   
   66       public AudioInputStream getAudioInputStream(Sequence seq)
   67               throws UnsupportedAudioFileException, IOException {
   68           AudioSynthesizer synth = (AudioSynthesizer) new SoftSynthesizer();
   69           AudioInputStream stream;
   70           Receiver recv;
   71           try {
   72               stream = synth.openStream(format, null);
   73               recv = synth.getReceiver();
   74           } catch (MidiUnavailableException e) {
   75               throw new IOException(e.toString());
   76           }
   77           float divtype = seq.getDivisionType();
   78           Track[] tracks = seq.getTracks();
   79           int[] trackspos = new int[tracks.length];
   80           int mpq = 500000;
   81           int seqres = seq.getResolution();
   82           long lasttick = 0;
   83           long curtime = 0;
   84           while (true) {
   85               MidiEvent selevent = null;
   86               int seltrack = -1;
   87               for (int i = 0; i < tracks.length; i++) {
   88                   int trackpos = trackspos[i];
   89                   Track track = tracks[i];
   90                   if (trackpos < track.size()) {
   91                       MidiEvent event = track.get(trackpos);
   92                       if (selevent == null || event.getTick() < selevent.getTick()) {
   93                           selevent = event;
   94                           seltrack = i;
   95                       }
   96                   }
   97               }
   98               if (seltrack == -1)
   99                   break;
  100               trackspos[seltrack]++;
  101               long tick = selevent.getTick();
  102               if (divtype == Sequence.PPQ)
  103                   curtime += ((tick - lasttick) * mpq) / seqres;
  104               else
  105                   curtime = (long) ((tick * 1000000.0 * divtype) / seqres);
  106               lasttick = tick;
  107               MidiMessage msg = selevent.getMessage();
  108               if (msg instanceof MetaMessage) {
  109                   if (divtype == Sequence.PPQ) {
  110                       if (((MetaMessage) msg).getType() == 0x51) {
  111                           byte[] data = ((MetaMessage) msg).getData();
  112                           mpq = ((data[0] & 0xff) << 16)
  113                                   | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
  114                       }
  115                   }
  116               } else {
  117                   recv.send(msg, curtime);
  118               }
  119           }
  120   
  121           long totallen = curtime / 1000000;
  122           long len = (long) (stream.getFormat().getFrameRate() * (totallen + 4));
  123           stream = new AudioInputStream(stream, stream.getFormat(), len);
  124           return stream;
  125       }
  126   
  127       public AudioInputStream getAudioInputStream(InputStream inputstream)
  128               throws UnsupportedAudioFileException, IOException {
  129   
  130           inputstream.mark(200);
  131           Sequence seq;
  132           try {
  133               seq = MidiSystem.getSequence(inputstream);
  134           } catch (InvalidMidiDataException e) {
  135               inputstream.reset();
  136               throw new UnsupportedAudioFileException();
  137           } catch (IOException e) {
  138               inputstream.reset();
  139               throw new UnsupportedAudioFileException();
  140           }
  141           return getAudioInputStream(seq);
  142       }
  143   
  144       public AudioFileFormat getAudioFileFormat(URL url)
  145               throws UnsupportedAudioFileException, IOException {
  146           Sequence seq;
  147           try {
  148               seq = MidiSystem.getSequence(url);
  149           } catch (InvalidMidiDataException e) {
  150               throw new UnsupportedAudioFileException();
  151           } catch (IOException e) {
  152               throw new UnsupportedAudioFileException();
  153           }
  154           return getAudioFileFormat(seq);
  155       }
  156   
  157       public AudioFileFormat getAudioFileFormat(File file)
  158               throws UnsupportedAudioFileException, IOException {
  159           Sequence seq;
  160           try {
  161               seq = MidiSystem.getSequence(file);
  162           } catch (InvalidMidiDataException e) {
  163               throw new UnsupportedAudioFileException();
  164           } catch (IOException e) {
  165               throw new UnsupportedAudioFileException();
  166           }
  167           return getAudioFileFormat(seq);
  168       }
  169   
  170       public AudioInputStream getAudioInputStream(URL url)
  171               throws UnsupportedAudioFileException, IOException {
  172           Sequence seq;
  173           try {
  174               seq = MidiSystem.getSequence(url);
  175           } catch (InvalidMidiDataException e) {
  176               throw new UnsupportedAudioFileException();
  177           } catch (IOException e) {
  178               throw new UnsupportedAudioFileException();
  179           }
  180           return getAudioInputStream(seq);
  181       }
  182   
  183       public AudioInputStream getAudioInputStream(File file)
  184               throws UnsupportedAudioFileException, IOException {
  185           if (!file.getName().toLowerCase().endsWith(".mid"))
  186               throw new UnsupportedAudioFileException();
  187           Sequence seq;
  188           try {
  189               seq = MidiSystem.getSequence(file);
  190           } catch (InvalidMidiDataException e) {
  191               throw new UnsupportedAudioFileException();
  192           } catch (IOException e) {
  193               throw new UnsupportedAudioFileException();
  194           }
  195           return getAudioInputStream(seq);
  196       }
  197   
  198       public AudioFileFormat getAudioFileFormat(InputStream inputstream)
  199               throws UnsupportedAudioFileException, IOException {
  200   
  201           inputstream.mark(200);
  202           Sequence seq;
  203           try {
  204               seq = MidiSystem.getSequence(inputstream);
  205           } catch (InvalidMidiDataException e) {
  206               inputstream.reset();
  207               throw new UnsupportedAudioFileException();
  208           } catch (IOException e) {
  209               inputstream.reset();
  210               throw new UnsupportedAudioFileException();
  211           }
  212           return getAudioFileFormat(seq);
  213       }
  214   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]