jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftMidiAudioFileReader.java
changeset 32663 1279321775f1
parent 26037 508779ce6619
child 35683 d8a9be6bd7db
equal deleted inserted replaced
32497:64edba808ec4 32663:1279321775f1
     1 /*
     1 /*
     2  * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package com.sun.media.sound;
    26 package com.sun.media.sound;
    27 
    27 
    28 import java.io.File;
       
    29 import java.io.IOException;
    28 import java.io.IOException;
    30 import java.io.InputStream;
    29 import java.io.InputStream;
    31 import java.net.URL;
       
    32 
    30 
    33 import javax.sound.midi.InvalidMidiDataException;
    31 import javax.sound.midi.InvalidMidiDataException;
    34 import javax.sound.midi.MetaMessage;
    32 import javax.sound.midi.MetaMessage;
    35 import javax.sound.midi.MidiEvent;
    33 import javax.sound.midi.MidiEvent;
    36 import javax.sound.midi.MidiMessage;
    34 import javax.sound.midi.MidiMessage;
    42 import javax.sound.sampled.AudioFileFormat;
    40 import javax.sound.sampled.AudioFileFormat;
    43 import javax.sound.sampled.AudioFileFormat.Type;
    41 import javax.sound.sampled.AudioFileFormat.Type;
    44 import javax.sound.sampled.AudioFormat;
    42 import javax.sound.sampled.AudioFormat;
    45 import javax.sound.sampled.AudioInputStream;
    43 import javax.sound.sampled.AudioInputStream;
    46 import javax.sound.sampled.UnsupportedAudioFileException;
    44 import javax.sound.sampled.UnsupportedAudioFileException;
    47 import javax.sound.sampled.spi.AudioFileReader;
       
    48 
    45 
    49 /**
    46 /**
    50  * MIDI File Audio Renderer/Reader.
    47  * MIDI File Audio Renderer/Reader.
    51  *
    48  *
    52  * @author Karl Helgason
    49  * @author Karl Helgason
    53  */
    50  */
    54 public final class SoftMidiAudioFileReader extends AudioFileReader {
    51 public final class SoftMidiAudioFileReader extends SunFileReader {
    55 
    52 
    56     public static final Type MIDI = new Type("MIDI", "mid");
    53     private static final Type MIDI = new Type("MIDI", "mid");
    57     private static AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
       
    58 
    54 
    59     public AudioFileFormat getAudioFileFormat(Sequence seq)
    55     private static final AudioFormat format = new AudioFormat(44100, 16, 2,
    60             throws UnsupportedAudioFileException, IOException {
    56                                                               true, false);
    61 
    57 
       
    58     private static AudioFileFormat getAudioFileFormat(final Sequence seq) {
    62         long totallen = seq.getMicrosecondLength() / 1000000;
    59         long totallen = seq.getMicrosecondLength() / 1000000;
    63         long len = (long) (format.getFrameRate() * (totallen + 4));
    60         long len = (long) (format.getFrameRate() * (totallen + 4));
    64         return new AudioFileFormat(MIDI, format, (int) len);
    61         return new AudioFileFormat(MIDI, format, (int) len);
    65     }
    62     }
    66 
    63 
    67     public AudioInputStream getAudioInputStream(Sequence seq)
    64     private AudioInputStream getAudioInputStream(final Sequence seq)
    68             throws UnsupportedAudioFileException, IOException {
    65             throws InvalidMidiDataException {
    69         AudioSynthesizer synth = (AudioSynthesizer) new SoftSynthesizer();
    66         AudioSynthesizer synth = (AudioSynthesizer) new SoftSynthesizer();
    70         AudioInputStream stream;
    67         AudioInputStream stream;
    71         Receiver recv;
    68         Receiver recv;
    72         try {
    69         try {
    73             stream = synth.openStream(format, null);
    70             stream = synth.openStream(format, null);
    74             recv = synth.getReceiver();
    71             recv = synth.getReceiver();
    75         } catch (MidiUnavailableException e) {
    72         } catch (MidiUnavailableException e) {
    76             throw new IOException(e.toString());
    73             throw new InvalidMidiDataException(e.toString());
    77         }
    74         }
    78         float divtype = seq.getDivisionType();
    75         float divtype = seq.getDivisionType();
    79         Track[] tracks = seq.getTracks();
    76         Track[] tracks = seq.getTracks();
    80         int[] trackspos = new int[tracks.length];
    77         int[] trackspos = new int[tracks.length];
    81         int mpq = 500000;
    78         int mpq = 500000;
   109             if (msg instanceof MetaMessage) {
   106             if (msg instanceof MetaMessage) {
   110                 if (divtype == Sequence.PPQ) {
   107                 if (divtype == Sequence.PPQ) {
   111                     if (((MetaMessage) msg).getType() == 0x51) {
   108                     if (((MetaMessage) msg).getType() == 0x51) {
   112                         byte[] data = ((MetaMessage) msg).getData();
   109                         byte[] data = ((MetaMessage) msg).getData();
   113                         if (data.length < 3) {
   110                         if (data.length < 3) {
   114                             throw new UnsupportedAudioFileException();
   111                             throw new InvalidMidiDataException();
   115                         }
   112                         }
   116                         mpq = ((data[0] & 0xff) << 16)
   113                         mpq = ((data[0] & 0xff) << 16)
   117                                 | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
   114                                 | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
   118                     }
   115                     }
   119                 }
   116                 }
   126         long len = (long) (stream.getFormat().getFrameRate() * (totallen + 4));
   123         long len = (long) (stream.getFormat().getFrameRate() * (totallen + 4));
   127         stream = new AudioInputStream(stream, stream.getFormat(), len);
   124         stream = new AudioInputStream(stream, stream.getFormat(), len);
   128         return stream;
   125         return stream;
   129     }
   126     }
   130 
   127 
   131     public AudioInputStream getAudioInputStream(InputStream inputstream)
   128     @Override
       
   129     public AudioInputStream getAudioInputStream(final InputStream stream)
   132             throws UnsupportedAudioFileException, IOException {
   130             throws UnsupportedAudioFileException, IOException {
   133 
   131         stream.mark(200);
   134         inputstream.mark(200);
       
   135         Sequence seq;
       
   136         try {
   132         try {
   137             seq = MidiSystem.getSequence(inputstream);
   133             return getAudioInputStream(MidiSystem.getSequence(stream));
   138         } catch (InvalidMidiDataException e) {
   134         } catch (final InvalidMidiDataException ignored) {
   139             inputstream.reset();
   135             stream.reset();
   140             throw new UnsupportedAudioFileException();
       
   141         } catch (IOException e) {
       
   142             inputstream.reset();
       
   143             throw new UnsupportedAudioFileException();
   136             throw new UnsupportedAudioFileException();
   144         }
   137         }
   145         return getAudioInputStream(seq);
       
   146     }
   138     }
   147 
   139 
   148     public AudioFileFormat getAudioFileFormat(URL url)
   140     @Override
       
   141     AudioFileFormat getAudioFileFormatImpl(final InputStream stream)
   149             throws UnsupportedAudioFileException, IOException {
   142             throws UnsupportedAudioFileException, IOException {
   150         Sequence seq;
       
   151         try {
   143         try {
   152             seq = MidiSystem.getSequence(url);
   144             return getAudioFileFormat(MidiSystem.getSequence(stream));
   153         } catch (InvalidMidiDataException e) {
   145         } catch (final InvalidMidiDataException ignored) {
   154             throw new UnsupportedAudioFileException();
       
   155         } catch (IOException e) {
       
   156             throw new UnsupportedAudioFileException();
   146             throw new UnsupportedAudioFileException();
   157         }
   147         }
   158         return getAudioFileFormat(seq);
       
   159     }
       
   160 
       
   161     public AudioFileFormat getAudioFileFormat(File file)
       
   162             throws UnsupportedAudioFileException, IOException {
       
   163         Sequence seq;
       
   164         try {
       
   165             seq = MidiSystem.getSequence(file);
       
   166         } catch (InvalidMidiDataException e) {
       
   167             throw new UnsupportedAudioFileException();
       
   168         } catch (IOException e) {
       
   169             throw new UnsupportedAudioFileException();
       
   170         }
       
   171         return getAudioFileFormat(seq);
       
   172     }
       
   173 
       
   174     public AudioInputStream getAudioInputStream(URL url)
       
   175             throws UnsupportedAudioFileException, IOException {
       
   176         Sequence seq;
       
   177         try {
       
   178             seq = MidiSystem.getSequence(url);
       
   179         } catch (InvalidMidiDataException e) {
       
   180             throw new UnsupportedAudioFileException();
       
   181         } catch (IOException e) {
       
   182             throw new UnsupportedAudioFileException();
       
   183         }
       
   184         return getAudioInputStream(seq);
       
   185     }
       
   186 
       
   187     public AudioInputStream getAudioInputStream(File file)
       
   188             throws UnsupportedAudioFileException, IOException {
       
   189         if (!file.getName().toLowerCase().endsWith(".mid"))
       
   190             throw new UnsupportedAudioFileException();
       
   191         Sequence seq;
       
   192         try {
       
   193             seq = MidiSystem.getSequence(file);
       
   194         } catch (InvalidMidiDataException e) {
       
   195             throw new UnsupportedAudioFileException();
       
   196         } catch (IOException e) {
       
   197             throw new UnsupportedAudioFileException();
       
   198         }
       
   199         return getAudioInputStream(seq);
       
   200     }
       
   201 
       
   202     public AudioFileFormat getAudioFileFormat(InputStream inputstream)
       
   203             throws UnsupportedAudioFileException, IOException {
       
   204 
       
   205         inputstream.mark(200);
       
   206         Sequence seq;
       
   207         try {
       
   208             seq = MidiSystem.getSequence(inputstream);
       
   209         } catch (InvalidMidiDataException e) {
       
   210             inputstream.reset();
       
   211             throw new UnsupportedAudioFileException();
       
   212         } catch (IOException e) {
       
   213             inputstream.reset();
       
   214             throw new UnsupportedAudioFileException();
       
   215         }
       
   216         return getAudioFileFormat(seq);
       
   217     }
   148     }
   218 }
   149 }