/* * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.sound.sampled; import java.io.File;import java.io.InputStream;import java.io.IOException;import java.io.OutputStream;import java.net.URL; import java.util.HashSet;import java.util.List;import java.util.Set;import java.util.Vector;import java.util.ArrayList; import javax.sound.sampled.spi.AudioFileWriter;import javax.sound.sampled.spi.AudioFileReader;import javax.sound.sampled.spi.FormatConversionProvider;import javax.sound.sampled.spi.MixerProvider; import com.sun.media.sound.JDK13Services; /* $fb TODO: * - consistent usage of (typed) collections */ /** * The <code>AudioSystem</code> class acts as the entry point to the * sampled-audio system resources. This class lets you query and * access the mixers that are installed on the system. * <code>AudioSystem</code> includes a number of * methods for converting audio data between different formats, and for * translating between audio files and streams. It also provides a method * for obtaining a <code>{@link Line}</code> directly from the * <code>AudioSystem</code> without dealing explicitly * with mixers. * * <p>Properties can be used to specify the default mixer * for specific line types. * Both system properties and a properties file are considered. * In the Oracle reference implementation, the properties file is * "lib/sound.properties" in the JRE * directory. If a property exists both as a system property and in the * properties file, the system property takes precedence. If none is * specified, a suitable default is chosen among the available devices. * The syntax of the properties file is specified in * {@link java.util.Properties#load(InputStream) Properties.load}. The * following table lists the available property keys and which methods * consider them: * * <table border=0> * <tr> * <th>Property Key</th> * <th>Interface</th> * <th>Affected Method(s)</th> * </tr> * <tr> * <td><code>javax.sound.sampled.Clip</code></td> * <td>{@link Clip}</td> * <td>{@link #getLine}, {@link #getClip}</td> * </tr> * <tr> * <td><code>javax.sound.sampled.Port</code></td> * <td>{@link Port}</td> * <td>{@link #getLine}</td> * </tr> * <tr> * <td><code>javax.sound.sampled.SourceDataLine</code></td> * <td>{@link SourceDataLine}</td> * <td>{@link #getLine}, {@link #getSourceDataLine}</td> * </tr> * <tr> * <td><code>javax.sound.sampled.TargetDataLine</code></td> * <td>{@link TargetDataLine}</td> * <td>{@link #getLine}, {@link #getTargetDataLine}</td> * </tr> * </table> * * The property value consists of the provider class name * and the mixer name, separated by the hash mark ("#"). * The provider class name is the fully-qualified * name of a concrete {@link javax.sound.sampled.spi.MixerProvider * mixer provider} class. The mixer name is matched against * the <code>String</code> returned by the <code>getName</code> * method of <code>Mixer.Info</code>. * Either the class name, or the mixer name may be omitted. * If only the class name is specified, the trailing hash mark * is optional. * * <p>If the provider class is specified, and it can be * successully retrieved from the installed providers, the list of * <code>Mixer.Info</code> objects is retrieved * from the provider. Otherwise, or when these mixers * do not provide a subsequent match, the list is retrieved * from {@link #getMixerInfo} to contain * all available <code>Mixer.Info</code> objects. * * <p>If a mixer name is specified, the resulting list of * <code>Mixer.Info</code> objects is searched: * the first one with a matching name, and whose * <code>Mixer</code> provides the * respective line interface, will be returned. * If no matching <code>Mixer.Info</code> object * is found, or the mixer name is not specified, * the first mixer from the resulting * list, which provides the respective line * interface, will be returned. * * For example, the property <code>javax.sound.sampled.Clip</code> * with a value * <code>"com.sun.media.sound.MixerProvider#SunClip"</code> * will have the following consequences when * <code>getLine</code> is called requesting a <code>Clip</code> * instance: * if the class <code>com.sun.media.sound.MixerProvider</code> exists * in the list of installed mixer providers, * the first <code>Clip</code> from the first mixer with name * <code>"SunClip"</code> will be returned. If it cannot * be found, the first <code>Clip</code> from the first mixer * of the specified provider will be returned, regardless of name. * If there is none, the first <code>Clip</code> from the first * <code>Mixer</code> with name * <code>"SunClip"</code> in the list of all mixers * (as returned by <code>getMixerInfo</code>) will be returned, * or, if not found, the first <code>Clip</code> of the first * <code>Mixer</code>that can be found in the list of all * mixers is returned. * If that fails, too, an <code>IllegalArgumentException</code> * is thrown. * * @author Kara Kytle * @author Florian Bomers * @author Matthias Pfisterer * @author Kevin P. Smith * * @see AudioFormat * @see AudioInputStream * @see Mixer * @see Line * @see Line.Info * @since 1.3 */public class AudioSystem { /** * An integer that stands for an unknown numeric value. * This value is appropriate only for signed quantities that do not * normally take negative values. Examples include file sizes, frame * sizes, buffer sizes, and sample rates. * A number of Java Sound constructors accept * a value of <code>NOT_SPECIFIED</code> for such parameters. Other * methods may also accept or return this value, as documented. */ public static final int NOT_SPECIFIED = -1; /** * Private no-args constructor for ensuring against instantiation. */ private AudioSystem() { } /** * Obtains an array of mixer info objects that represents * the set of audio mixers that are currently installed on the system. * @return an array of info objects for the currently installed mixers. If no mixers * are available on the system, an array of length 0 is returned. * @see #getMixer */ public static Mixer.Info[] getMixerInfo() { List infos = getMixerInfoList(); Mixer.Info[] allInfos = (Mixer.Info[]) infos.toArray(new Mixer.Info[infos.size()]); return allInfos; } /** * Obtains the requested audio mixer. * @param info a <code>Mixer.Info</code> object representing the desired * mixer, or <code>null</code> for the system default mixer * @return the requested mixer * @throws SecurityException if the requested mixer * is unavailable because of security restrictions * @throws IllegalArgumentException if the info object does not represent * a mixer installed on the system * @see #getMixerInfo */ public static Mixer getMixer(Mixer.Info info) { Mixer mixer = null; List providers = getMixerProviders(); for(int i = 0; i < providers.size(); i++ ) { try { return ((MixerProvider)providers.get(i)).getMixer(info); } catch (IllegalArgumentException e) { } catch (NullPointerException e) { // $$jb 08.20.99: If the strings in the info object aren't // set, then Netscape (using jdk1.1.5) tends to throw // NPE's when doing some string manipulation. This is // probably not the best fix, but is solves the problem // of the NPE in Netscape using local classes // $$jb 11.01.99: Replacing this patch. } } //$$fb if looking for default mixer, and not found yet, add a round of looking if (info == null) { for(int i = 0; i < providers.size(); i++ ) { try { MixerProvider provider = (MixerProvider) providers.get(i); Mixer.Info[] infos = provider.getMixerInfo(); // start from 0 to last device (do not reverse this order) for (int ii = 0; ii < infos.length; ii++) { try { return provider.getMixer(infos[ii]); } catch (IllegalArgumentException e) { // this is not a good default device :) } } } catch (IllegalArgumentException e) { } catch (NullPointerException e) { } } } throw new IllegalArgumentException("Mixer not supported: " + (info!=null?info.toString():"null")); } //$$fb 2002-11-26: fix for 4757930: DOC: AudioSystem.getTarget/SourceLineInfo() is ambiguous /** * Obtains information about all source lines of a particular type that are supported * by the installed mixers. * @param info a <code>Line.Info</code> object that specifies the kind of * lines about which information is requested * @return an array of <code>Line.Info</code> objects describing source lines matching * the type requested. If no matching source lines are supported, an array of length 0 * is returned. * * @see Mixer#getSourceLineInfo(Line.Info) */ public static Line.Info[] getSourceLineInfo(Line.Info info) { Vector vector = new Vector(); Line.Info[] currentInfoArray; Mixer mixer; Line.Info fullInfo = null; Mixer.Info[] infoArray = getMixerInfo(); for (int i = 0; i < infoArray.length; i++) { mixer = getMixer(infoArray[i]); currentInfoArray = mixer.getSourceLineInfo(info); for (int j = 0; j < currentInfoArray.length; j++) { vector.addElement(currentInfoArray[j]); } } Line.Info[] returnedArray = new Line.Info[vector.size()]; for (int i = 0; i < returnedArray.length; i++) { returnedArray[i] = (Line.Info)vector.get(i); } return returnedArray; } /** * Obtains information about all target lines of a particular type that are supported * by the installed mixers. * @param info a <code>Line.Info</code> object that specifies the kind of * lines about which information is requested * @return an array of <code>Line.Info</code> objects describing target lines matching * the type requested. If no matching target lines are supported, an array of length 0 * is returned. * * @see Mixer#getTargetLineInfo(Line.Info) */ public static Line.Info[] getTargetLineInfo(Line.Info info) { Vector vector = new Vector(); Line.Info[] currentInfoArray; Mixer mixer; Line.Info fullInfo = null; Mixer.Info[] infoArray = getMixerInfo(); for (int i = 0; i < infoArray.length; i++) { mixer = getMixer(infoArray[i]); currentInfoArray = mixer.getTargetLineInfo(info); for (int j = 0; j < currentInfoArray.length; j++) { vector.addElement(currentInfoArray[j]); } } Line.Info[] returnedArray = new Line.Info[vector.size()]; for (int i = 0; i < returnedArray.length; i++) { returnedArray[i] = (Line.Info)vector.get(i); } return returnedArray; } /** * Indicates whether the system supports any lines that match * the specified <code>Line.Info</code> object. A line is supported if * any installed mixer supports it. * @param info a <code>Line.Info</code> object describing the line for which support is queried * @return <code>true</code> if at least one matching line is * supported, otherwise <code>false</code> * * @see Mixer#isLineSupported(Line.Info) */ public static boolean isLineSupported(Line.Info info) { Mixer mixer; Mixer.Info[] infoArray = getMixerInfo(); for (int i = 0; i < infoArray.length; i++) { if( infoArray[i] != null ) { mixer = getMixer(infoArray[i]); if (mixer.isLineSupported(info)) { return true; } } } return false; } /** * Obtains a line that matches the description in the specified * <code>Line.Info</code> object. * * <p>If a <code>DataLine</code> is requested, and <code>info</code> * is an instance of <code>DataLine.Info</code> specifying at least * one fully qualified audio format, the last one * will be used as the default format of the returned * <code>DataLine</code>. * * <p>If system properties * <code>javax.sound.sampled.Clip</code>, * <code>javax.sound.sampled.Port</code>, * <code>javax.sound.sampled.SourceDataLine</code> and * <code>javax.sound.sampled.TargetDataLine</code> are defined * or they are defined in the file "sound.properties", * they are used to retrieve default lines. * For details, refer to the {@link AudioSystem class description}. * * If the respective property is not set, or the mixer * requested in the property is not installed or does not provide the * requested line, all installed mixers are queried for the * requested line type. A Line will be returned from the first mixer * providing the requested line type. * * @param info a <code>Line.Info</code> object describing the desired kind of line * @return a line of the requested kind * * @throws LineUnavailableException if a matching line * is not available due to resource restrictions * @throws SecurityException if a matching line * is not available due to security restrictions * @throws IllegalArgumentException if the system does not * support at least one line matching the specified * <code>Line.Info</code> object * through any installed mixer */ public static Line getLine(Line.Info info) throws LineUnavailableException { LineUnavailableException lue = null; List providers = getMixerProviders(); // 1: try from default mixer for this line class try { Mixer mixer = getDefaultMixer(providers, info); if (mixer != null && mixer.isLineSupported(info)) { return mixer.getLine(info); } } catch (LineUnavailableException e) { lue = e; } catch (IllegalArgumentException iae) { // must not happen... but better to catch it here, // if plug-ins are badly written } // 2: if that doesn't work, try to find any mixing mixer for(int i = 0; i < providers.size(); i++) { MixerProvider provider = (MixerProvider) providers.get(i); Mixer.Info[] infos = provider.getMixerInfo(); for (int j = 0; j < infos.length; j++) { try { Mixer mixer = provider.getMixer(infos[j]); // see if this is an appropriate mixer which can mix if (isAppropriateMixer(mixer, info, true)) { return mixer.getLine(info); } } catch (LineUnavailableException e) { lue = e; } catch (IllegalArgumentException iae) { // must not happen... but better to catch it here, // if plug-ins are badly written } } } // 3: if that didn't work, try to find any non-mixing mixer for(int i = 0; i < providers.size(); i++) { MixerProvider provider = (MixerProvider) providers.get(i); Mixer.Info[] infos = provider.getMixerInfo(); for (int j = 0; j < infos.length; j++) { try { Mixer mixer = provider.getMixer(infos[j]); // see if this is an appropriate mixer which can mix if (isAppropriateMixer(mixer, info, false)) { return mixer.getLine(info); } } catch (LineUnavailableException e) { lue = e; } catch (IllegalArgumentException iae) { // must not happen... but better to catch it here, // if plug-ins are badly written } } } // if this line was supported but was not available, throw the last // LineUnavailableException we got (??). if (lue != null) { throw lue; } // otherwise, the requested line was not supported, so throw // an Illegal argument exception throw new IllegalArgumentException("No line matching " + info.toString() + " is supported."); } /** * Obtains a clip that can be used for playing back * an audio file or an audio stream. The returned clip * will be provided by the default system mixer, or, * if not possible, by any other mixer installed in the * system that supports a <code>Clip</code> * object. * * <p>The returned clip must be opened with the * <code>open(AudioFormat)</code> or * <code>open(AudioInputStream)</code> method. * * <p>This is a high-level method that uses <code>getMixer</code> * and <code>getLine</code> internally. * * <p>If the system property * <code>javax.sound.sampled.Clip</code> * is defined or it is defined in the file "sound.properties", * it is used to retrieve the default clip. * For details, refer to the {@link AudioSystem class description}.Lines 1–500 of 1631. Load more
/* * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.sound.sampled; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; import java.util.ArrayList; import javax.sound.sampled.spi.AudioFileWriter; import javax.sound.sampled.spi.AudioFileReader; import javax.sound.sampled.spi.FormatConversionProvider; import javax.sound.sampled.spi.MixerProvider; import com.sun.media.sound.JDK13Services; /* $fb TODO: * - consistent usage of (typed) collections */ /** * The <code>AudioSystem</code> class acts as the entry point to the * sampled-audio system resources. This class lets you query and * access the mixers that are installed on the system. * <code>AudioSystem</code> includes a number of * methods for converting audio data between different formats, and for * translating between audio files and streams. It also provides a method * for obtaining a <code>{@link Line}</code> directly from the * <code>AudioSystem</code> without dealing explicitly * with mixers. * * <p>Properties can be used to specify the default mixer * for specific line types. * Both system properties and a properties file are considered. * In the Oracle reference implementation, the properties file is * "lib/sound.properties" in the JRE * directory. If a property exists both as a system property and in the * properties file, the system property takes precedence. If none is * specified, a suitable default is chosen among the available devices. * The syntax of the properties file is specified in * {@link java.util.Properties#load(InputStream) Properties.load}. The * following table lists the available property keys and which methods * consider them: * * <table border=0> * <tr> * <th>Property Key</th> * <th>Interface</th> * <th>Affected Method(s)</th> * </tr> * <tr> * <td><code>javax.sound.sampled.Clip</code></td> * <td>{@link Clip}</td> * <td>{@link #getLine}, {@link #getClip}</td> * </tr> * <tr> * <td><code>javax.sound.sampled.Port</code></td> * <td>{@link Port}</td> * <td>{@link #getLine}</td> * </tr> * <tr> * <td><code>javax.sound.sampled.SourceDataLine</code></td> * <td>{@link SourceDataLine}</td> * <td>{@link #getLine}, {@link #getSourceDataLine}</td> * </tr> * <tr> * <td><code>javax.sound.sampled.TargetDataLine</code></td> * <td>{@link TargetDataLine}</td> * <td>{@link #getLine}, {@link #getTargetDataLine}</td> * </tr> * </table> * * The property value consists of the provider class name * and the mixer name, separated by the hash mark ("#"). * The provider class name is the fully-qualified * name of a concrete {@link javax.sound.sampled.spi.MixerProvider * mixer provider} class. The mixer name is matched against * the <code>String</code> returned by the <code>getName</code> * method of <code>Mixer.Info</code>. * Either the class name, or the mixer name may be omitted. * If only the class name is specified, the trailing hash mark * is optional. * * <p>If the provider class is specified, and it can be * successully retrieved from the installed providers, the list of * <code>Mixer.Info</code> objects is retrieved * from the provider. Otherwise, or when these mixers * do not provide a subsequent match, the list is retrieved * from {@link #getMixerInfo} to contain * all available <code>Mixer.Info</code> objects. * * <p>If a mixer name is specified, the resulting list of * <code>Mixer.Info</code> objects is searched: * the first one with a matching name, and whose * <code>Mixer</code> provides the * respective line interface, will be returned. * If no matching <code>Mixer.Info</code> object * is found, or the mixer name is not specified, * the first mixer from the resulting * list, which provides the respective line * interface, will be returned. * * For example, the property <code>javax.sound.sampled.Clip</code> * with a value * <code>"com.sun.media.sound.MixerProvider#SunClip"</code> * will have the following consequences when * <code>getLine</code> is called requesting a <code>Clip</code> * instance: * if the class <code>com.sun.media.sound.MixerProvider</code> exists * in the list of installed mixer providers, * the first <code>Clip</code> from the first mixer with name * <code>"SunClip"</code> will be returned. If it cannot * be found, the first <code>Clip</code> from the first mixer * of the specified provider will be returned, regardless of name. * If there is none, the first <code>Clip</code> from the first * <code>Mixer</code> with name * <code>"SunClip"</code> in the list of all mixers * (as returned by <code>getMixerInfo</code>) will be returned, * or, if not found, the first <code>Clip</code> of the first * <code>Mixer</code>that can be found in the list of all * mixers is returned. * If that fails, too, an <code>IllegalArgumentException</code> * is thrown. * * @author Kara Kytle * @author Florian Bomers * @author Matthias Pfisterer * @author Kevin P. Smith * * @see AudioFormat * @see AudioInputStream * @see Mixer * @see Line * @see Line.Info * @since 1.3 */ public class AudioSystem { /** * An integer that stands for an unknown numeric value. * This value is appropriate only for signed quantities that do not * normally take negative values. Examples include file sizes, frame * sizes, buffer sizes, and sample rates. * A number of Java Sound constructors accept * a value of <code>NOT_SPECIFIED</code> for such parameters. Other * methods may also accept or return this value, as documented. */ public static final int NOT_SPECIFIED = -1; /** * Private no-args constructor for ensuring against instantiation. */ private AudioSystem() { } /** * Obtains an array of mixer info objects that represents * the set of audio mixers that are currently installed on the system. * @return an array of info objects for the currently installed mixers. If no mixers * are available on the system, an array of length 0 is returned. * @see #getMixer */ public static Mixer.Info[] getMixerInfo() { List infos = getMixerInfoList(); Mixer.Info[] allInfos = (Mixer.Info[]) infos.toArray(new Mixer.Info[infos.size()]); return allInfos; } /** * Obtains the requested audio mixer. * @param info a <code>Mixer.Info</code> object representing the desired * mixer, or <code>null</code> for the system default mixer * @return the requested mixer * @throws SecurityException if the requested mixer * is unavailable because of security restrictions * @throws IllegalArgumentException if the info object does not represent * a mixer installed on the system * @see #getMixerInfo */ public static Mixer getMixer(Mixer.Info info) { Mixer mixer = null; List providers = getMixerProviders(); for(int i = 0; i < providers.size(); i++ ) { try { return ((MixerProvider)providers.get(i)).getMixer(info); } catch (IllegalArgumentException e) { } catch (NullPointerException e) { // $$jb 08.20.99: If the strings in the info object aren't // set, then Netscape (using jdk1.1.5) tends to throw // NPE's when doing some string manipulation. This is // probably not the best fix, but is solves the problem // of the NPE in Netscape using local classes // $$jb 11.01.99: Replacing this patch. } } //$$fb if looking for default mixer, and not found yet, add a round of looking if (info == null) { for(int i = 0; i < providers.size(); i++ ) { try { MixerProvider provider = (MixerProvider) providers.get(i); Mixer.Info[] infos = provider.getMixerInfo(); // start from 0 to last device (do not reverse this order) for (int ii = 0; ii < infos.length; ii++) { try { return provider.getMixer(infos[ii]); } catch (IllegalArgumentException e) { // this is not a good default device :) } } } catch (IllegalArgumentException e) { } catch (NullPointerException e) { } } } throw new IllegalArgumentException("Mixer not supported: " + (info!=null?info.toString():"null")); } //$$fb 2002-11-26: fix for 4757930: DOC: AudioSystem.getTarget/SourceLineInfo() is ambiguous /** * Obtains information about all source lines of a particular type that are supported * by the installed mixers. * @param info a <code>Line.Info</code> object that specifies the kind of * lines about which information is requested * @return an array of <code>Line.Info</code> objects describing source lines matching * the type requested. If no matching source lines are supported, an array of length 0 * is returned. * * @see Mixer#getSourceLineInfo(Line.Info) */ public static Line.Info[] getSourceLineInfo(Line.Info info) { Vector vector = new Vector(); Line.Info[] currentInfoArray; Mixer mixer; Line.Info fullInfo = null; Mixer.Info[] infoArray = getMixerInfo(); for (int i = 0; i < infoArray.length; i++) { mixer = getMixer(infoArray[i]); currentInfoArray = mixer.getSourceLineInfo(info); for (int j = 0; j < currentInfoArray.length; j++) { vector.addElement(currentInfoArray[j]); } } Line.Info[] returnedArray = new Line.Info[vector.size()]; for (int i = 0; i < returnedArray.length; i++) { returnedArray[i] = (Line.Info)vector.get(i); } return returnedArray; } /** * Obtains information about all target lines of a particular type that are supported * by the installed mixers. * @param info a <code>Line.Info</code> object that specifies the kind of * lines about which information is requested * @return an array of <code>Line.Info</code> objects describing target lines matching * the type requested. If no matching target lines are supported, an array of length 0 * is returned. * * @see Mixer#getTargetLineInfo(Line.Info) */ public static Line.Info[] getTargetLineInfo(Line.Info info) { Vector vector = new Vector(); Line.Info[] currentInfoArray; Mixer mixer; Line.Info fullInfo = null; Mixer.Info[] infoArray = getMixerInfo(); for (int i = 0; i < infoArray.length; i++) { mixer = getMixer(infoArray[i]); currentInfoArray = mixer.getTargetLineInfo(info); for (int j = 0; j < currentInfoArray.length; j++) { vector.addElement(currentInfoArray[j]); } } Line.Info[] returnedArray = new Line.Info[vector.size()]; for (int i = 0; i < returnedArray.length; i++) { returnedArray[i] = (Line.Info)vector.get(i); } return returnedArray; } /** * Indicates whether the system supports any lines that match * the specified <code>Line.Info</code> object. A line is supported if * any installed mixer supports it. * @param info a <code>Line.Info</code> object describing the line for which support is queried * @return <code>true</code> if at least one matching line is * supported, otherwise <code>false</code> * * @see Mixer#isLineSupported(Line.Info) */ public static boolean isLineSupported(Line.Info info) { Mixer mixer; Mixer.Info[] infoArray = getMixerInfo(); for (int i = 0; i < infoArray.length; i++) { if( infoArray[i] != null ) { mixer = getMixer(infoArray[i]); if (mixer.isLineSupported(info)) { return true; } } } return false; } /** * Obtains a line that matches the description in the specified * <code>Line.Info</code> object. * * <p>If a <code>DataLine</code> is requested, and <code>info</code> * is an instance of <code>DataLine.Info</code> specifying at least * one fully qualified audio format, the last one * will be used as the default format of the returned * <code>DataLine</code>. * * <p>If system properties * <code>javax.sound.sampled.Clip</code>, * <code>javax.sound.sampled.Port</code>, * <code>javax.sound.sampled.SourceDataLine</code> and * <code>javax.sound.sampled.TargetDataLine</code> are defined * or they are defined in the file "sound.properties", * they are used to retrieve default lines. * For details, refer to the {@link AudioSystem class description}. * * If the respective property is not set, or the mixer * requested in the property is not installed or does not provide the * requested line, all installed mixers are queried for the * requested line type. A Line will be returned from the first mixer * providing the requested line type. * * @param info a <code>Line.Info</code> object describing the desired kind of line * @return a line of the requested kind * * @throws LineUnavailableException if a matching line * is not available due to resource restrictions * @throws SecurityException if a matching line * is not available due to security restrictions * @throws IllegalArgumentException if the system does not * support at least one line matching the specified * <code>Line.Info</code> object * through any installed mixer */ public static Line getLine(Line.Info info) throws LineUnavailableException { LineUnavailableException lue = null; List providers = getMixerProviders(); // 1: try from default mixer for this line class try { Mixer mixer = getDefaultMixer(providers, info); if (mixer != null && mixer.isLineSupported(info)) { return mixer.getLine(info); } } catch (LineUnavailableException e) { lue = e; } catch (IllegalArgumentException iae) { // must not happen... but better to catch it here, // if plug-ins are badly written } // 2: if that doesn't work, try to find any mixing mixer for(int i = 0; i < providers.size(); i++) { MixerProvider provider = (MixerProvider) providers.get(i); Mixer.Info[] infos = provider.getMixerInfo(); for (int j = 0; j < infos.length; j++) { try { Mixer mixer = provider.getMixer(infos[j]); // see if this is an appropriate mixer which can mix if (isAppropriateMixer(mixer, info, true)) { return mixer.getLine(info); } } catch (LineUnavailableException e) { lue = e; } catch (IllegalArgumentException iae) { // must not happen... but better to catch it here, // if plug-ins are badly written } } } // 3: if that didn't work, try to find any non-mixing mixer for(int i = 0; i < providers.size(); i++) { MixerProvider provider = (MixerProvider) providers.get(i); Mixer.Info[] infos = provider.getMixerInfo(); for (int j = 0; j < infos.length; j++) { try { Mixer mixer = provider.getMixer(infos[j]); // see if this is an appropriate mixer which can mix if (isAppropriateMixer(mixer, info, false)) { return mixer.getLine(info); } } catch (LineUnavailableException e) { lue = e; } catch (IllegalArgumentException iae) { // must not happen... but better to catch it here, // if plug-ins are badly written } } } // if this line was supported but was not available, throw the last // LineUnavailableException we got (??). if (lue != null) { throw lue; } // otherwise, the requested line was not supported, so throw // an Illegal argument exception throw new IllegalArgumentException("No line matching " + info.toString() + " is supported."); } /** * Obtains a clip that can be used for playing back * an audio file or an audio stream. The returned clip * will be provided by the default system mixer, or, * if not possible, by any other mixer installed in the * system that supports a <code>Clip</code> * object. * * <p>The returned clip must be opened with the * <code>open(AudioFormat)</code> or * <code>open(AudioInputStream)</code> method. * * <p>This is a high-level method that uses <code>getMixer</code> * and <code>getLine</code> internally. * * <p>If the system property * <code>javax.sound.sampled.Clip</code> * is defined or it is defined in the file "sound.properties", * it is used to retrieve the default clip. * For details, refer to the {@link AudioSystem class description}.