Merged with mainline at revision 128810.
[official-gcc.git] / libjava / classpath / gnu / javax / sound / sampled / gstreamer / io / GstAudioFileReaderNativePeer.java
blob45ae4ff85889b6cd334a834f2564eed844aecbef
1 /*GstAudioFileReaderNativePeer -- GNU Classpath GStreamer AudioFileReader
2 native peer class.
3 Copyright (C) 2007 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
39 package gnu.javax.sound.sampled.gstreamer.io;
41 import gnu.javax.sound.sampled.gstreamer.GStreamerMixer;
43 import java.io.BufferedInputStream;
44 import java.io.File;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.net.URL;
48 import java.util.HashMap;
49 import java.util.Map;
51 import javax.sound.sampled.AudioFormat;
52 import javax.sound.sampled.AudioSystem;
53 import javax.sound.sampled.AudioFormat.Encoding;
55 /**
56 * GStreamer native peer for GstAudioFileReader.
58 * @author Mario Torre <neugens@limasoftware.net>
60 final class GstAudioFileReaderNativePeer
62 private static final String GST_ENCODING = "GStreamer Generic Audio Reader";
64 private static class GstHeader
66 /*
67 * NOTE: these properties are accessed by the native code, be careful
68 * if you change them.
69 * Not all the fields are necessarily set.
72 public String file = null;
74 public String suffix = null;
76 public String name = null;
78 public String mimetype = null;
80 public String endianness = null;
82 public String channels = null;
84 public String rate = null;
86 public String width = null;
88 public String depth = null;
90 public String isSigned = null;
92 public String layer = null;
93 public String bitrate = null;
94 public String framed = null;
95 public String type = null;
98 public static AudioFormat getAudioFormat(File file) throws Exception
100 GstHeader header = new GstHeader();
101 header.file = file.getAbsolutePath();
103 if (!gstreamer_get_audio_format_file(header))
104 return null;
106 return getAudioFormat(header);
109 public static AudioFormat getAudioFormat(InputStream is) throws Exception
111 GstHeader header = new GstHeader();
113 BufferedInputStream stream = new BufferedInputStream(is);
114 if(!stream.markSupported())
115 throw new IOException("Stream must support marking.");
117 stream.mark(0);
119 if (!gstreamer_get_audio_format_stream(header, stream))
120 return null;
122 return getAudioFormat(header);
125 public static AudioFormat getAudioFormat(URL url) throws Exception
127 GstHeader header = new GstHeader();
128 header.file = url.toExternalForm();
130 BufferedInputStream stream = new BufferedInputStream(url.openStream());
131 if(!stream.markSupported())
132 throw new IOException("Stream must support marking.");
134 stream.mark(0);
136 if (!gstreamer_get_audio_format_stream(header, stream))
137 return null;
139 return getAudioFormat(header);
142 private static Encoding getEncoding(GstHeader header)
144 StringBuilder buffer = new StringBuilder();
146 if (header.name == null)
148 buffer.append(GST_ENCODING);
149 if (header.mimetype != null)
151 buffer.append(" ");
152 buffer.append(header.mimetype);
155 header.name = buffer.toString();
157 else
159 // strip the "decoder" word from the name, if any
160 // this is a bit ugly, the alternative would be to still output the
161 // full name of the decoder/demuxer
162 String lowerCase = header.name.toLowerCase();
163 int index = lowerCase.indexOf("decoder");
164 if (index == -1)
166 index = lowerCase.indexOf("demuxer");
169 if (index == -1)
170 index = lowerCase.length();
172 buffer.append(header.name.substring(0, index));
176 return new Encoding(buffer.toString().trim());
179 private static AudioFormat getAudioFormat(GstHeader header)
180 throws Exception
182 int na = AudioSystem.NOT_SPECIFIED;
184 /* we use mimetype as an header, but this could have some side effects */
185 Encoding encoding = getEncoding(header);
187 float sampleRate = ((header.rate != null) ?
188 new Float(header.rate).floatValue() : na);
190 int sampleSizeInBits = ((header.depth != null) ?
191 new Integer(header.depth).intValue() : na);
193 int channels = ((header.channels != null) ?
194 new Integer(header.channels).intValue() : na);
196 boolean bigEndian = false;
197 if (header.endianness != null)
199 if (header.endianness.compareTo("4321") == 0)
200 bigEndian = true;
203 int frameSize = na;
204 float frameRate = na;
205 String lowerCase = header.name.toLowerCase();
207 // FIXME: frameRate = sampleRate in these cases under all the tests so far
208 // but I'm not sure if this is always correct...
209 if (lowerCase.contains("law") || lowerCase.contains("au") ||
210 lowerCase.contains("x-au"))
212 frameSize = (sampleSizeInBits >> 3) * channels;
213 frameRate = sampleRate;
215 else if (lowerCase.contains("wav"))
217 frameSize = ((sampleSizeInBits + 7) / 8) * channels;
218 frameRate = sampleRate;
220 else if (lowerCase.contains("iff"))
222 frameSize = (sampleSizeInBits * channels) / 8;
223 frameRate = sampleRate;
226 // write all the additional properties we got to identify
227 // the gstreamer plugin actually used to deal with this stream
228 Map<String, Object> properties = new HashMap<String, Object>();
229 properties.put(GStreamerMixer.GST_BACKEND, true);
230 properties.put(GStreamerMixer.GST_DECODER, header.name);
232 /* now we put in some of the additional properties if we have them */
233 if (header.type != null) properties.put("type", header.type);
234 if (header.framed != null) properties.put("framed", header.framed);
235 if (header.bitrate != null) properties.put("bitrate", header.bitrate);
236 if (header.isSigned != null) properties.put("isSigned", header.isSigned);
237 if (header.depth != null) properties.put("depth", header.depth);
238 if (header.mimetype != null) properties.put("mimetype", header.mimetype);
240 AudioFormat format = new AudioFormat(encoding,
241 sampleRate,
242 sampleSizeInBits,
243 channels,
244 frameSize,
245 frameRate,
246 bigEndian,
247 properties);
248 return format;
251 /* ***** native methods ***** */
254 * Retrieve header information about the file being played.
256 * @param info
257 * @return
259 native static final
260 protected boolean gstreamer_get_audio_format_stream(GstHeader info,
261 BufferedInputStream istream);
264 * Retrieve header information about the file being played.
266 * @param info
267 * @return
269 native static final
270 protected boolean gstreamer_get_audio_format_file(GstHeader info);
272 static
274 System.loadLibrary("gstreamerpeer"); //$NON-NLS-1$