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 |
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 } |