Source Code Cross Referenced for AudioSystem.java in  » 6.0-JDK-Core » sound » javax » sound » sampled » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » sound » javax.sound.sampled 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.sound.sampled;
0027
0028        import java.io.File;
0029        import java.io.InputStream;
0030        import java.io.IOException;
0031        import java.io.OutputStream;
0032        import java.net.URL;
0033
0034        import java.util.HashSet;
0035        import java.util.List;
0036        import java.util.Set;
0037        import java.util.Vector;
0038        import java.util.ArrayList;
0039
0040        import javax.sound.sampled.spi.AudioFileWriter;
0041        import javax.sound.sampled.spi.AudioFileReader;
0042        import javax.sound.sampled.spi.FormatConversionProvider;
0043        import javax.sound.sampled.spi.MixerProvider;
0044
0045        import com.sun.media.sound.JDK13Services;
0046
0047        /* $fb TODO:
0048         * - consistent usage of (typed) collections
0049         */
0050
0051        /**
0052         * The <code>AudioSystem</code> class acts as the entry point to the
0053         * sampled-audio system resources. This class lets you query and
0054         * access the mixers that are installed on the system.
0055         * <code>AudioSystem</code> includes a number of
0056         * methods for converting audio data between different formats, and for
0057         * translating between audio files and streams. It also provides a method
0058         * for obtaining a <code>{@link Line}</code> directly from the
0059         * <code>AudioSystem</code> without dealing explicitly
0060         * with mixers.
0061         *
0062         * <p>Properties can be used to specify the default mixer
0063         * for specific line types.
0064         * Both system properties and a properties file are considered.
0065         * In the Sun reference implementation, the properties file is
0066         * &quot;lib/sound.properties&quot; in the JRE
0067         * directory. If a property exists both as a system property and in the
0068         * properties file, the system property takes precedence. If none is
0069         * specified, a suitable default is chosen among the available devices.
0070         * The syntax of the properties file is specified in
0071         * {@link java.util.Properties#load(InputStream) Properties.load}. The
0072         * following table lists the available property keys and which methods
0073         * consider them:
0074         *
0075         * <table border=0>
0076         *  <tr>
0077         *   <th>Property Key</th>
0078         *   <th>Interface</th>
0079         *   <th>Affected Method(s)</th>
0080         *  </tr>
0081         *  <tr>
0082         *   <td><code>javax.sound.sampled.Clip</code></td>
0083         *   <td>{@link Clip}</td>
0084         *   <td>{@link #getLine}, {@link #getClip}</td>
0085         *  </tr>
0086         *  <tr>
0087         *   <td><code>javax.sound.sampled.Port</code></td>
0088         *   <td>{@link Port}</td>
0089         *   <td>{@link #getLine}</td>
0090         *  </tr>
0091         *  <tr>
0092         *   <td><code>javax.sound.sampled.SourceDataLine</code></td>
0093         *   <td>{@link SourceDataLine}</td>
0094         *   <td>{@link #getLine}, {@link #getSourceDataLine}</td>
0095         *  </tr>
0096         *  <tr>
0097         *   <td><code>javax.sound.sampled.TargetDataLine</code></td>
0098         *   <td>{@link TargetDataLine}</td>
0099         *   <td>{@link #getLine}, {@link #getTargetDataLine}</td>
0100         *  </tr>
0101         * </table>
0102         *
0103         * The property value consists of the provider class name
0104         * and the mixer name, separated by the hash mark (&quot;#&quot;).
0105         * The provider class name is the fully-qualified
0106         * name of a concrete {@link javax.sound.sampled.spi.MixerProvider
0107         * mixer provider} class. The mixer name is matched against
0108         * the <code>String</code> returned by the <code>getName</code>
0109         * method of <code>Mixer.Info</code>.
0110         * Either the class name, or the mixer name may be omitted.
0111         * If only the class name is specified, the trailing hash mark
0112         * is optional.
0113         *
0114         * <p>If the provider class is specified, and it can be
0115         * successully retrieved from the installed providers, the list of
0116         * <code>Mixer.Info</code> objects is retrieved
0117         * from the provider. Otherwise, or when these mixers
0118         * do not provide a subsequent match, the list is retrieved
0119         * from {@link #getMixerInfo} to contain
0120         * all available <code>Mixer.Info</code> objects.
0121         *
0122         * <p>If a mixer name is specified, the resulting list of
0123         * <code>Mixer.Info</code> objects is searched:
0124         * the first one with a matching name, and whose
0125         * <code>Mixer</code> provides the
0126         * respective line interface, will be returned.
0127         * If no matching <code>Mixer.Info</code> object
0128         * is found, or the mixer name is not specified,
0129         * the first mixer from the resulting
0130         * list, which provides the respective line
0131         * interface, will be returned.
0132         *
0133         * For example, the property <code>javax.sound.sampled.Clip</code>
0134         * with a value
0135         * <code>&quot;com.sun.media.sound.MixerProvider#SunClip&quot;</code>
0136         * will have the following consequences when
0137         * <code>getLine</code> is called requesting a <code>Clip</code>
0138         * instance:
0139         * if the class <code>com.sun.media.sound.MixerProvider</code> exists
0140         * in the list of installed mixer providers,
0141         * the first <code>Clip</code> from the first mixer with name
0142         * <code>&quot;SunClip&quot;</code> will be returned. If it cannot
0143         * be found, the first <code>Clip</code> from the first mixer
0144         * of the specified provider will be returned, regardless of name.
0145         * If there is none, the first <code>Clip</code> from the first
0146         * <code>Mixer</code> with name
0147         * <code>&quot;SunClip&quot;</code> in the list of all mixers
0148         * (as returned by <code>getMixerInfo</code>) will be returned,
0149         * or, if not found, the first <code>Clip</code> of the first
0150         * <code>Mixer</code>that can be found in the list of all
0151         * mixers is returned.
0152         * If that fails, too, an <code>IllegalArgumentException</code>
0153         * is thrown.
0154         *
0155         * @author Kara Kytle
0156         * @author Florian Bomers
0157         * @author Matthias Pfisterer
0158         * @author Kevin P. Smith
0159         * @version 1.89, 07/05/05
0160         *
0161         * @see AudioFormat
0162         * @see AudioInputStream
0163         * @see Mixer
0164         * @see Line
0165         * @see Line.Info
0166         * @since 1.3
0167         */
0168        public class AudioSystem {
0169
0170            /**
0171             * An integer that stands for an unknown numeric value.
0172             * This value is appropriate only for signed quantities that do not
0173             * normally take negative values.  Examples include file sizes, frame
0174             * sizes, buffer sizes, and sample rates.
0175             * A number of Java Sound constructors accept
0176             * a value of <code>NOT_SPECIFIED</code> for such parameters.  Other
0177             * methods may also accept or return this value, as documented.
0178             */
0179            public static final int NOT_SPECIFIED = -1;
0180
0181            /**
0182             * Private no-args constructor for ensuring against instantiation.
0183             */
0184            private AudioSystem() {
0185            }
0186
0187            /**
0188             * Obtains an array of mixer info objects that represents
0189             * the set of audio mixers that are currently installed on the system.
0190             * @return an array of info objects for the currently installed mixers.  If no mixers
0191             * are available on the system, an array of length 0 is returned.
0192             * @see #getMixer
0193             */
0194            public static Mixer.Info[] getMixerInfo() {
0195
0196                List infos = getMixerInfoList();
0197                Mixer.Info[] allInfos = (Mixer.Info[]) infos
0198                        .toArray(new Mixer.Info[infos.size()]);
0199                return allInfos;
0200            }
0201
0202            /**
0203             * Obtains the requested audio mixer.
0204             * @param info a <code>Mixer.Info</code> object representing the desired
0205             * mixer, or <code>null</code> for the system default mixer
0206             * @return the requested mixer
0207             * @throws SecurityException if the requested mixer
0208             * is unavailable because of security restrictions
0209             * @throws IllegalArgumentException if the info object does not represent
0210             * a mixer installed on the system
0211             * @see #getMixerInfo
0212             */
0213            public static Mixer getMixer(Mixer.Info info) {
0214
0215                Mixer mixer = null;
0216                List providers = getMixerProviders();
0217
0218                for (int i = 0; i < providers.size(); i++) {
0219
0220                    try {
0221                        return ((MixerProvider) providers.get(i))
0222                                .getMixer(info);
0223
0224                    } catch (IllegalArgumentException e) {
0225                    } catch (NullPointerException e) {
0226                        // $$jb 08.20.99:  If the strings in the info object aren't
0227                        // set, then Netscape (using jdk1.1.5) tends to throw
0228                        // NPE's when doing some string manipulation.  This is
0229                        // probably not the best fix, but is solves the problem
0230                        // of the NPE in Netscape using local classes
0231                        // $$jb 11.01.99: Replacing this patch.
0232                    }
0233                }
0234
0235                //$$fb if looking for default mixer, and not found yet, add a round of looking
0236                if (info == null) {
0237                    for (int i = 0; i < providers.size(); i++) {
0238                        try {
0239                            MixerProvider provider = (MixerProvider) providers
0240                                    .get(i);
0241                            Mixer.Info[] infos = provider.getMixerInfo();
0242                            // start from 0 to last device (do not reverse this order)
0243                            for (int ii = 0; ii < infos.length; ii++) {
0244                                try {
0245                                    return provider.getMixer(infos[ii]);
0246                                } catch (IllegalArgumentException e) {
0247                                    // this is not a good default device :)
0248                                }
0249                            }
0250                        } catch (IllegalArgumentException e) {
0251                        } catch (NullPointerException e) {
0252                        }
0253                    }
0254                }
0255
0256                throw new IllegalArgumentException("Mixer not supported: "
0257                        + (info != null ? info.toString() : "null"));
0258            }
0259
0260            //$$fb 2002-11-26: fix for 4757930: DOC: AudioSystem.getTarget/SourceLineInfo() is ambiguous
0261            /**
0262             * Obtains information about all source lines of a particular type that are supported
0263             * by the installed mixers.
0264             * @param info a <code>Line.Info</code> object that specifies the kind of
0265             * lines about which information is requested
0266             * @return an array of <code>Line.Info</code> objects describing source lines matching
0267             * the type requested.  If no matching source lines are supported, an array of length 0
0268             * is returned.
0269             *
0270             * @see Mixer#getSourceLineInfo(Line.Info)
0271             */
0272            public static Line.Info[] getSourceLineInfo(Line.Info info) {
0273
0274                Vector vector = new Vector();
0275                Line.Info[] currentInfoArray;
0276
0277                Mixer mixer;
0278                Line.Info fullInfo = null;
0279                Mixer.Info[] infoArray = getMixerInfo();
0280
0281                for (int i = 0; i < infoArray.length; i++) {
0282
0283                    mixer = getMixer(infoArray[i]);
0284
0285                    currentInfoArray = mixer.getSourceLineInfo(info);
0286                    for (int j = 0; j < currentInfoArray.length; j++) {
0287                        vector.addElement(currentInfoArray[j]);
0288                    }
0289                }
0290
0291                Line.Info[] returnedArray = new Line.Info[vector.size()];
0292
0293                for (int i = 0; i < returnedArray.length; i++) {
0294                    returnedArray[i] = (Line.Info) vector.get(i);
0295                }
0296
0297                return returnedArray;
0298            }
0299
0300            /**
0301             * Obtains information about all target lines of a particular type that are supported
0302             * by the installed mixers.
0303             * @param info a <code>Line.Info</code> object that specifies the kind of
0304             * lines about which information is requested
0305             * @return an array of <code>Line.Info</code> objects describing target lines matching
0306             * the type requested.  If no matching target lines are supported, an array of length 0
0307             * is returned.
0308             *
0309             * @see Mixer#getTargetLineInfo(Line.Info)
0310             */
0311            public static Line.Info[] getTargetLineInfo(Line.Info info) {
0312
0313                Vector vector = new Vector();
0314                Line.Info[] currentInfoArray;
0315
0316                Mixer mixer;
0317                Line.Info fullInfo = null;
0318                Mixer.Info[] infoArray = getMixerInfo();
0319
0320                for (int i = 0; i < infoArray.length; i++) {
0321
0322                    mixer = getMixer(infoArray[i]);
0323
0324                    currentInfoArray = mixer.getTargetLineInfo(info);
0325                    for (int j = 0; j < currentInfoArray.length; j++) {
0326                        vector.addElement(currentInfoArray[j]);
0327                    }
0328                }
0329
0330                Line.Info[] returnedArray = new Line.Info[vector.size()];
0331
0332                for (int i = 0; i < returnedArray.length; i++) {
0333                    returnedArray[i] = (Line.Info) vector.get(i);
0334                }
0335
0336                return returnedArray;
0337            }
0338
0339            /**
0340             * Indicates whether the system supports any lines that match
0341             * the specified <code>Line.Info</code> object.  A line is supported if
0342             * any installed mixer supports it.
0343             * @param info a <code>Line.Info</code> object describing the line for which support is queried
0344             * @return <code>true</code> if at least one matching line is
0345             * supported, otherwise <code>false</code>
0346             *
0347             * @see Mixer#isLineSupported(Line.Info)
0348             */
0349            public static boolean isLineSupported(Line.Info info) {
0350
0351                Mixer mixer;
0352                Mixer.Info[] infoArray = getMixerInfo();
0353
0354                for (int i = 0; i < infoArray.length; i++) {
0355
0356                    if (infoArray[i] != null) {
0357                        mixer = getMixer(infoArray[i]);
0358                        if (mixer.isLineSupported(info)) {
0359                            return true;
0360                        }
0361                    }
0362                }
0363
0364                return false;
0365            }
0366
0367            /**
0368             * Obtains a line that matches the description in the specified
0369             * <code>Line.Info</code> object.
0370             *
0371             * <p>If a <code>DataLine</code> is requested, and <code>info</code>
0372             * is an instance of <code>DataLine.Info</code> specifying at least
0373             * one fully qualified audio format, the last one
0374             * will be used as the default format of the returned
0375             * <code>DataLine</code>.
0376             *
0377             * <p>If system properties
0378             * <code>javax.sound.sampled.Clip</code>,
0379             * <code>javax.sound.sampled.Port</code>,
0380             * <code>javax.sound.sampled.SourceDataLine</code> and
0381             * <code>javax.sound.sampled.TargetDataLine</code> are defined
0382             * or they are defined in the file &quot;sound.properties&quot;,
0383             * they are used to retrieve default lines.
0384             * For details, refer to the {@link AudioSystem class description}.
0385             *
0386             * If the respective property is not set, or the mixer
0387             * requested in the property is not installed or does not provide the
0388             * requested line, all installed mixers are queried for the
0389             * requested line type. A Line will be returned from the first mixer
0390             * providing the requested line type.
0391             *
0392             * @param info a <code>Line.Info</code> object describing the desired kind of line
0393             * @return a line of the requested kind
0394             *
0395             * @throws LineUnavailableException if a matching line
0396             * is not available due to resource restrictions
0397             * @throws SecurityException if a matching line
0398             * is not available due to security restrictions
0399             * @throws IllegalArgumentException if the system does not
0400             * support at least one line matching the specified
0401             * <code>Line.Info</code> object
0402             * through any installed mixer
0403             */
0404            public static Line getLine(Line.Info info)
0405                    throws LineUnavailableException {
0406                LineUnavailableException lue = null;
0407                List providers = getMixerProviders();
0408
0409                // 1: try from default mixer for this line class
0410                try {
0411                    Mixer mixer = getDefaultMixer(providers, info);
0412                    if (mixer != null && mixer.isLineSupported(info)) {
0413                        return mixer.getLine(info);
0414                    }
0415                } catch (LineUnavailableException e) {
0416                    lue = e;
0417                } catch (IllegalArgumentException iae) {
0418                    // must not happen... but better to catch it here,
0419                    // if plug-ins are badly written
0420                }
0421
0422                // 2: if that doesn't work, try to find any mixing mixer
0423                for (int i = 0; i < providers.size(); i++) {
0424                    MixerProvider provider = (MixerProvider) providers.get(i);
0425                    Mixer.Info[] infos = provider.getMixerInfo();
0426
0427                    for (int j = 0; j < infos.length; j++) {
0428                        try {
0429                            Mixer mixer = provider.getMixer(infos[j]);
0430                            // see if this is an appropriate mixer which can mix
0431                            if (isAppropriateMixer(mixer, info, true)) {
0432                                return mixer.getLine(info);
0433                            }
0434                        } catch (LineUnavailableException e) {
0435                            lue = e;
0436                        } catch (IllegalArgumentException iae) {
0437                            // must not happen... but better to catch it here,
0438                            // if plug-ins are badly written
0439                        }
0440                    }
0441                }
0442
0443                // 3: if that didn't work, try to find any non-mixing mixer
0444                for (int i = 0; i < providers.size(); i++) {
0445                    MixerProvider provider = (MixerProvider) providers.get(i);
0446                    Mixer.Info[] infos = provider.getMixerInfo();
0447                    for (int j = 0; j < infos.length; j++) {
0448                        try {
0449                            Mixer mixer = provider.getMixer(infos[j]);
0450                            // see if this is an appropriate mixer which can mix
0451                            if (isAppropriateMixer(mixer, info, false)) {
0452                                return mixer.getLine(info);
0453                            }
0454                        } catch (LineUnavailableException e) {
0455                            lue = e;
0456                        } catch (IllegalArgumentException iae) {
0457                            // must not happen... but better to catch it here,
0458                            // if plug-ins are badly written
0459                        }
0460                    }
0461                }
0462
0463                // if this line was supported but was not available, throw the last
0464                // LineUnavailableException we got (??).
0465                if (lue != null) {
0466                    throw lue;
0467                }
0468
0469                // otherwise, the requested line was not supported, so throw
0470                // an Illegal argument exception
0471                throw new IllegalArgumentException("No line matching "
0472                        + info.toString() + " is supported.");
0473            }
0474
0475            /**
0476             * Obtains a clip that can be used for playing back
0477             * an audio file or an audio stream. The returned clip
0478             * will be provided by the default system mixer, or,
0479             * if not possible, by any other mixer installed in the
0480             * system that supports a <code>Clip</code>
0481             * object.
0482             *
0483             * <p>The returned clip must be opened with the
0484             * <code>open(AudioFormat)</code> or
0485             * <code>open(AudioInputStream)</code> method.
0486             *
0487             * <p>This is a high-level method that uses <code>getMixer</code>
0488             * and <code>getLine</code> internally.
0489             *
0490             * <p>If the system property
0491             * <code>javax.sound.sampled.Clip</code>
0492             * is defined or it is defined in the file &quot;sound.properties&quot;,
0493             * it is used to retrieve the default clip.
0494             * For details, refer to the {@link AudioSystem class description}.
0495             *
0496             * @return the desired clip object
0497             *
0498             * @throws LineUnavailableException if a clip object
0499             * is not available due to resource restrictions
0500             * @throws SecurityException if a clip object
0501             * is not available due to security restrictions
0502             * @throws IllegalArgumentException if the system does not
0503             * support at least one clip instance through any installed mixer
0504             *
0505             * @see #getClip(Mixer.Info)
0506             * @since 1.5
0507             */
0508            public static Clip getClip() throws LineUnavailableException {
0509                AudioFormat format = new AudioFormat(
0510                        AudioFormat.Encoding.PCM_SIGNED,
0511                        AudioSystem.NOT_SPECIFIED, 16, 2, 4,
0512                        AudioSystem.NOT_SPECIFIED, true);
0513                DataLine.Info info = new DataLine.Info(Clip.class, format);
0514                return (Clip) AudioSystem.getLine(info);
0515            }
0516
0517            /**
0518             * Obtains a clip from the specified mixer that can be
0519             * used for playing back an audio file or an audio stream.
0520             *
0521             * <p>The returned clip must be opened with the
0522             * <code>open(AudioFormat)</code> or
0523             * <code>open(AudioInputStream)</code> method.
0524             *
0525             * <p>This is a high-level method that uses <code>getMixer</code>
0526             * and <code>getLine</code> internally.
0527             *
0528             * @param mixerInfo a <code>Mixer.Info</code> object representing the
0529             * desired mixer, or <code>null</code> for the system default mixer
0530             * @return a clip object from the specified mixer
0531             *
0532             * @throws LineUnavailableException if a clip
0533             * is not available from this mixer due to resource restrictions
0534             * @throws SecurityException if a clip
0535             * is not available from this mixer due to security restrictions
0536             * @throws IllegalArgumentException if the system does not
0537             * support at least one clip through the specified mixer
0538             *
0539             * @see #getClip()
0540             * @since 1.5
0541             */
0542            public static Clip getClip(Mixer.Info mixerInfo)
0543                    throws LineUnavailableException {
0544                AudioFormat format = new AudioFormat(
0545                        AudioFormat.Encoding.PCM_SIGNED,
0546                        AudioSystem.NOT_SPECIFIED, 16, 2, 4,
0547                        AudioSystem.NOT_SPECIFIED, true);
0548                DataLine.Info info = new DataLine.Info(Clip.class, format);
0549                Mixer mixer = AudioSystem.getMixer(mixerInfo);
0550                return (Clip) mixer.getLine(info);
0551            }
0552
0553            /**
0554             * Obtains a source data line that can be used for playing back
0555             * audio data in the format specified by the
0556             * <code>AudioFormat</code> object. The returned line
0557             * will be provided by the default system mixer, or,
0558             * if not possible, by any other mixer installed in the
0559             * system that supports a matching
0560             * <code>SourceDataLine</code> object.
0561             *
0562             * <p>The returned line should be opened with the
0563             * <code>open(AudioFormat)</code> or
0564             * <code>open(AudioFormat, int)</code> method.
0565             *
0566             * <p>This is a high-level method that uses <code>getMixer</code>
0567             * and <code>getLine</code> internally.
0568             *
0569             * <p>The returned <code>SourceDataLine</code>'s default
0570             * audio format will be initialized with <code>format</code>.
0571             *
0572             * <p>If the system property
0573             * <code>javax.sound.sampled.SourceDataLine</code>
0574             * is defined or it is defined in the file &quot;sound.properties&quot;,
0575             * it is used to retrieve the default source data line.
0576             * For details, refer to the {@link AudioSystem class description}.
0577             *
0578             * @param format an <code>AudioFormat</code> object specifying
0579             *        the supported audio format of the returned line,
0580             *        or <code>null</code> for any audio format
0581             * @return the desired <code>SourceDataLine</code> object
0582             *
0583             * @throws LineUnavailableException if a matching source data line
0584             *         is not available due to resource restrictions
0585             * @throws SecurityException if a matching source data line
0586             *         is not available due to security restrictions
0587             * @throws IllegalArgumentException if the system does not
0588             *         support at least one source data line supporting the
0589             *         specified audio format through any installed mixer
0590             *
0591             * @see #getSourceDataLine(AudioFormat, Mixer.Info)
0592             * @since 1.5
0593             */
0594            public static SourceDataLine getSourceDataLine(AudioFormat format)
0595                    throws LineUnavailableException {
0596                DataLine.Info info = new DataLine.Info(SourceDataLine.class,
0597                        format);
0598                return (SourceDataLine) AudioSystem.getLine(info);
0599            }
0600
0601            /**
0602             * Obtains a source data line that can be used for playing back
0603             * audio data in the format specified by the
0604             * <code>AudioFormat</code> object, provided by the mixer
0605             * specified by the <code>Mixer.Info</code> object.
0606             *
0607             * <p>The returned line should be opened with the
0608             * <code>open(AudioFormat)</code> or
0609             * <code>open(AudioFormat, int)</code> method.
0610             *
0611             * <p>This is a high-level method that uses <code>getMixer</code>
0612             * and <code>getLine</code> internally.
0613             *
0614             * <p>The returned <code>SourceDataLine</code>'s default
0615             * audio format will be initialized with <code>format</code>.
0616             *
0617             * @param format an <code>AudioFormat</code> object specifying
0618             *        the supported audio format of the returned line,
0619             *        or <code>null</code> for any audio format
0620             * @param mixerinfo a <code>Mixer.Info</code> object representing
0621             *        the desired mixer, or <code>null</code> for the system
0622             *        default mixer
0623             * @return the desired <code>SourceDataLine</code> object
0624             *
0625             * @throws LineUnavailableException if a matching source data
0626             *         line is not available from the specified mixer due
0627             *         to resource restrictions
0628             * @throws SecurityException if a matching source data line
0629             *         is not available from the specified mixer due to
0630             *         security restrictions
0631             * @throws IllegalArgumentException if the specified mixer does
0632             *         not support at least one source data line supporting
0633             *         the specified audio format
0634             *
0635             * @see #getSourceDataLine(AudioFormat)
0636             * @since 1.5
0637             */
0638            public static SourceDataLine getSourceDataLine(AudioFormat format,
0639                    Mixer.Info mixerinfo) throws LineUnavailableException {
0640                DataLine.Info info = new DataLine.Info(SourceDataLine.class,
0641                        format);
0642                Mixer mixer = AudioSystem.getMixer(mixerinfo);
0643                return (SourceDataLine) mixer.getLine(info);
0644            }
0645
0646            /**
0647             * Obtains a target data line that can be used for recording
0648             * audio data in the format specified by the
0649             * <code>AudioFormat</code> object. The returned line
0650             * will be provided by the default system mixer, or,
0651             * if not possible, by any other mixer installed in the
0652             * system that supports a matching
0653             * <code>TargetDataLine</code> object.
0654             *
0655             * <p>The returned line should be opened with the
0656             * <code>open(AudioFormat)</code> or
0657             * <code>open(AudioFormat, int)</code> method.
0658             *
0659             * <p>This is a high-level method that uses <code>getMixer</code>
0660             * and <code>getLine</code> internally.
0661             *
0662             * <p>The returned <code>TargetDataLine</code>'s default
0663             * audio format will be initialized with <code>format</code>.
0664             *
0665             * @param format an <code>AudioFormat</code> object specifying
0666             *        the supported audio format of the returned line,
0667             *        or <code>null</code> for any audio format
0668             * @return the desired <code>TargetDataLine</code> object
0669             *
0670             * @throws LineUnavailableException if a matching target data line
0671             *         is not available due to resource restrictions
0672             * @throws SecurityException if a matching target data line
0673             *         is not available due to security restrictions
0674             * @throws IllegalArgumentException if the system does not
0675             *         support at least one target data line supporting the
0676             *         specified audio format through any installed mixer
0677             *
0678             * @see #getTargetDataLine(AudioFormat, Mixer.Info)
0679             * @see AudioPermission
0680             * @since 1.5
0681             */
0682            public static TargetDataLine getTargetDataLine(AudioFormat format)
0683                    throws LineUnavailableException {
0684
0685                DataLine.Info info = new DataLine.Info(TargetDataLine.class,
0686                        format);
0687                return (TargetDataLine) AudioSystem.getLine(info);
0688            }
0689
0690            /**
0691             * Obtains a target data line that can be used for recording
0692             * audio data in the format specified by the
0693             * <code>AudioFormat</code> object, provided by the mixer
0694             * specified by the <code>Mixer.Info</code> object.
0695             *
0696             * <p>The returned line should be opened with the
0697             * <code>open(AudioFormat)</code> or
0698             * <code>open(AudioFormat, int)</code> method.
0699             *
0700             * <p>This is a high-level method that uses <code>getMixer</code>
0701             * and <code>getLine</code> internally.
0702             *
0703             * <p>The returned <code>TargetDataLine</code>'s default
0704             * audio format will be initialized with <code>format</code>.
0705             *
0706             * <p>If the system property
0707             * <code>javax.sound.sampled.TargetDataLine</code>
0708             * is defined or it is defined in the file &quot;sound.properties&quot;,
0709             * it is used to retrieve the default target data line.
0710             * For details, refer to the {@link AudioSystem class description}.
0711             *
0712             * @param format an <code>AudioFormat</code> object specifying
0713             *        the supported audio format of the returned line,
0714             *        or <code>null</code> for any audio format
0715             * @param mixerinfo a <code>Mixer.Info</code> object representing the
0716             *        desired mixer, or <code>null</code> for the system default mixer
0717             * @return the desired <code>TargetDataLine</code> object
0718             *
0719             * @throws LineUnavailableException if a matching target data
0720             *         line is not available from the specified mixer due
0721             *         to resource restrictions
0722             * @throws SecurityException if a matching target data line
0723             *         is not available from the specified mixer due to
0724             *         security restrictions
0725             * @throws IllegalArgumentException if the specified mixer does
0726             *         not support at least one target data line supporting
0727             *         the specified audio format
0728             *
0729             * @see #getTargetDataLine(AudioFormat)
0730             * @see AudioPermission
0731             * @since 1.5
0732             */
0733            public static TargetDataLine getTargetDataLine(AudioFormat format,
0734                    Mixer.Info mixerinfo) throws LineUnavailableException {
0735
0736                DataLine.Info info = new DataLine.Info(TargetDataLine.class,
0737                        format);
0738                Mixer mixer = AudioSystem.getMixer(mixerinfo);
0739                return (TargetDataLine) mixer.getLine(info);
0740            }
0741
0742            // $$fb 2002-04-12: fix for 4662082: behavior of AudioSystem.getTargetEncodings() methods doesn't match the spec
0743            /**
0744             * Obtains the encodings that the system can obtain from an
0745             * audio input stream with the specified encoding using the set
0746             * of installed format converters.
0747             * @param sourceEncoding the encoding for which conversion support
0748             * is queried
0749             * @return array of encodings.  If <code>sourceEncoding</code>is not supported,
0750             * an array of length 0 is returned. Otherwise, the array will have a length
0751             * of at least 1, representing <code>sourceEncoding</code> (no conversion).
0752             */
0753            public static AudioFormat.Encoding[] getTargetEncodings(
0754                    AudioFormat.Encoding sourceEncoding) {
0755
0756                List codecs = getFormatConversionProviders();
0757                Vector encodings = new Vector();
0758
0759                AudioFormat.Encoding encs[] = null;
0760
0761                // gather from all the codecs
0762                for (int i = 0; i < codecs.size(); i++) {
0763                    FormatConversionProvider codec = (FormatConversionProvider) codecs
0764                            .get(i);
0765                    if (codec.isSourceEncodingSupported(sourceEncoding)) {
0766                        encs = codec.getTargetEncodings();
0767                        for (int j = 0; j < encs.length; j++) {
0768                            encodings.addElement(encs[j]);
0769                        }
0770                    }
0771                }
0772                AudioFormat.Encoding encs2[] = (AudioFormat.Encoding[]) encodings
0773                        .toArray(new AudioFormat.Encoding[0]);
0774                return encs2;
0775            }
0776
0777            // $$fb 2002-04-12: fix for 4662082: behavior of AudioSystem.getTargetEncodings() methods doesn't match the spec
0778            /**
0779             * Obtains the encodings that the system can obtain from an
0780             * audio input stream with the specified format using the set
0781             * of installed format converters.
0782             * @param sourceFormat the audio format for which conversion
0783             * is queried
0784             * @return array of encodings. If <code>sourceFormat</code>is not supported,
0785             * an array of length 0 is returned. Otherwise, the array will have a length
0786             * of at least 1, representing the encoding of <code>sourceFormat</code> (no conversion).
0787             */
0788            public static AudioFormat.Encoding[] getTargetEncodings(
0789                    AudioFormat sourceFormat) {
0790
0791                List codecs = getFormatConversionProviders();
0792                Vector encodings = new Vector();
0793
0794                int size = 0;
0795                int index = 0;
0796                AudioFormat.Encoding encs[] = null;
0797
0798                // gather from all the codecs
0799
0800                for (int i = 0; i < codecs.size(); i++) {
0801                    encs = ((FormatConversionProvider) codecs.get(i))
0802                            .getTargetEncodings(sourceFormat);
0803                    size += encs.length;
0804                    encodings.addElement(encs);
0805                }
0806
0807                // now build a new array
0808
0809                AudioFormat.Encoding encs2[] = new AudioFormat.Encoding[size];
0810                for (int i = 0; i < encodings.size(); i++) {
0811                    encs = (AudioFormat.Encoding[]) (encodings.get(i));
0812                    for (int j = 0; j < encs.length; j++) {
0813                        encs2[index++] = encs[j];
0814                    }
0815                }
0816                return encs2;
0817            }
0818
0819            /**
0820             * Indicates whether an audio input stream of the specified encoding
0821             * can be obtained from an audio input stream that has the specified
0822             * format.
0823             * @param targetEncoding the desired encoding after conversion
0824             * @param sourceFormat the audio format before conversion
0825             * @return <code>true</code> if the conversion is supported,
0826             * otherwise <code>false</code>
0827             */
0828            public static boolean isConversionSupported(
0829                    AudioFormat.Encoding targetEncoding,
0830                    AudioFormat sourceFormat) {
0831
0832                List codecs = getFormatConversionProviders();
0833
0834                for (int i = 0; i < codecs.size(); i++) {
0835                    FormatConversionProvider codec = (FormatConversionProvider) codecs
0836                            .get(i);
0837                    if (codec.isConversionSupported(targetEncoding,
0838                            sourceFormat)) {
0839                        return true;
0840                    }
0841                }
0842                return false;
0843            }
0844
0845            /**
0846             * Obtains an audio input stream of the indicated encoding, by converting the
0847             * provided audio input stream.
0848             * @param targetEncoding the desired encoding after conversion
0849             * @param sourceStream the stream to be converted
0850             * @return an audio input stream of the indicated encoding
0851             * @throws IllegalArgumentException if the conversion is not supported
0852             * @see #getTargetEncodings(AudioFormat.Encoding)
0853             * @see #getTargetEncodings(AudioFormat)
0854             * @see #isConversionSupported(AudioFormat.Encoding, AudioFormat)
0855             * @see #getAudioInputStream(AudioFormat, AudioInputStream)
0856             */
0857            public static AudioInputStream getAudioInputStream(
0858                    AudioFormat.Encoding targetEncoding,
0859                    AudioInputStream sourceStream) {
0860
0861                List codecs = getFormatConversionProviders();
0862
0863                for (int i = 0; i < codecs.size(); i++) {
0864                    FormatConversionProvider codec = (FormatConversionProvider) codecs
0865                            .get(i);
0866                    if (codec.isConversionSupported(targetEncoding,
0867                            sourceStream.getFormat())) {
0868                        return codec.getAudioInputStream(targetEncoding,
0869                                sourceStream);
0870                    }
0871                }
0872                // we ran out of options, throw an exception
0873                throw new IllegalArgumentException("Unsupported conversion: "
0874                        + targetEncoding + " from " + sourceStream.getFormat());
0875            }
0876
0877            /**
0878             * Obtains the formats that have a particular encoding and that the system can
0879             * obtain from a stream of the specified format using the set of
0880             * installed format converters.
0881             * @param targetEncoding the desired encoding after conversion
0882             * @param sourceFormat the audio format before conversion
0883             * @return array of formats.  If no formats of the specified
0884             * encoding are supported, an array of length 0 is returned.
0885             */
0886            public static AudioFormat[] getTargetFormats(
0887                    AudioFormat.Encoding targetEncoding,
0888                    AudioFormat sourceFormat) {
0889
0890                List codecs = getFormatConversionProviders();
0891                Vector formats = new Vector();
0892
0893                int size = 0;
0894                int index = 0;
0895                AudioFormat fmts[] = null;
0896
0897                // gather from all the codecs
0898
0899                for (int i = 0; i < codecs.size(); i++) {
0900                    FormatConversionProvider codec = (FormatConversionProvider) codecs
0901                            .get(i);
0902                    fmts = codec.getTargetFormats(targetEncoding, sourceFormat);
0903                    size += fmts.length;
0904                    formats.addElement(fmts);
0905                }
0906
0907                // now build a new array
0908
0909                AudioFormat fmts2[] = new AudioFormat[size];
0910                for (int i = 0; i < formats.size(); i++) {
0911                    fmts = (AudioFormat[]) (formats.get(i));
0912                    for (int j = 0; j < fmts.length; j++) {
0913                        fmts2[index++] = fmts[j];
0914                    }
0915                }
0916                return fmts2;
0917            }
0918
0919            /**
0920             * Indicates whether an audio input stream of a specified format
0921             * can be obtained from an audio input stream of another specified format.
0922             * @param targetFormat the desired audio format after conversion
0923             * @param sourceFormat the audio format before conversion
0924             * @return <code>true</code> if the conversion is supported,
0925             * otherwise <code>false</code>
0926             */
0927
0928            public static boolean isConversionSupported(
0929                    AudioFormat targetFormat, AudioFormat sourceFormat) {
0930
0931                List codecs = getFormatConversionProviders();
0932
0933                for (int i = 0; i < codecs.size(); i++) {
0934                    FormatConversionProvider codec = (FormatConversionProvider) codecs
0935                            .get(i);
0936                    if (codec.isConversionSupported(targetFormat, sourceFormat)) {
0937                        return true;
0938                    }
0939                }
0940                return false;
0941            }
0942
0943            /**
0944             * Obtains an audio input stream of the indicated format, by converting the
0945             * provided audio input stream.
0946             * @param targetFormat the desired audio format after conversion
0947             * @param sourceStream the stream to be converted
0948             * @return an audio input stream of the indicated format
0949             * @throws IllegalArgumentException if the conversion is not supported
0950             * #see #getTargetEncodings(AudioFormat)
0951             * @see #getTargetFormats(AudioFormat.Encoding, AudioFormat)
0952             * @see #isConversionSupported(AudioFormat, AudioFormat)
0953             * @see #getAudioInputStream(AudioFormat.Encoding, AudioInputStream)
0954             */
0955            public static AudioInputStream getAudioInputStream(
0956                    AudioFormat targetFormat, AudioInputStream sourceStream) {
0957
0958                if (sourceStream.getFormat().matches(targetFormat)) {
0959                    return sourceStream;
0960                }
0961
0962                List codecs = getFormatConversionProviders();
0963
0964                for (int i = 0; i < codecs.size(); i++) {
0965                    FormatConversionProvider codec = (FormatConversionProvider) codecs
0966                            .get(i);
0967                    if (codec.isConversionSupported(targetFormat, sourceStream
0968                            .getFormat())) {
0969                        return codec.getAudioInputStream(targetFormat,
0970                                sourceStream);
0971                    }
0972                }
0973
0974                // we ran out of options...
0975                throw new IllegalArgumentException("Unsupported conversion: "
0976                        + targetFormat + " from " + sourceStream.getFormat());
0977            }
0978
0979            /**
0980             * Obtains the audio file format of the provided input stream.  The stream must
0981             * point to valid audio file data.  The implementation of this method may require
0982             * multiple parsers to examine the stream to determine whether they support it.
0983             * These parsers must be able to mark the stream, read enough data to determine whether they
0984             * support the stream, and, if not, reset the stream's read pointer to its original
0985             * position.  If the input stream does not support these operations, this method may fail
0986             * with an <code>IOException</code>.
0987             * @param stream the input stream from which file format information should be
0988             * extracted
0989             * @return an <code>AudioFileFormat</code> object describing the stream's audio file format
0990             * @throws UnsupportedAudioFileException if the stream does not point to valid audio
0991             * file data recognized by the system
0992             * @throws IOException if an input/output exception occurs
0993             * @see InputStream#markSupported
0994             * @see InputStream#mark
0995             */
0996            public static AudioFileFormat getAudioFileFormat(InputStream stream)
0997                    throws UnsupportedAudioFileException, IOException {
0998
0999                List providers = getAudioFileReaders();
1000                AudioFileFormat format = null;
1001
1002                for (int i = 0; i < providers.size(); i++) {
1003                    AudioFileReader reader = (AudioFileReader) providers.get(i);
1004                    try {
1005                        format = reader.getAudioFileFormat(stream); // throws IOException
1006                        break;
1007                    } catch (UnsupportedAudioFileException e) {
1008                        continue;
1009                    }
1010                }
1011
1012                if (format == null) {
1013                    throw new UnsupportedAudioFileException(
1014                            "file is not a supported file type");
1015                } else {
1016                    return format;
1017                }
1018            }
1019
1020            /**
1021             * Obtains the audio file format of the specified URL.  The URL must
1022             * point to valid audio file data.
1023             * @param url the URL from which file format information should be
1024             * extracted
1025             * @return an <code>AudioFileFormat</code> object describing the audio file format
1026             * @throws UnsupportedAudioFileException if the URL does not point to valid audio
1027             * file data recognized by the system
1028             * @throws IOException if an input/output exception occurs
1029             */
1030            public static AudioFileFormat getAudioFileFormat(URL url)
1031                    throws UnsupportedAudioFileException, IOException {
1032
1033                List providers = getAudioFileReaders();
1034                AudioFileFormat format = null;
1035
1036                for (int i = 0; i < providers.size(); i++) {
1037                    AudioFileReader reader = (AudioFileReader) providers.get(i);
1038                    try {
1039                        format = reader.getAudioFileFormat(url); // throws IOException
1040                        break;
1041                    } catch (UnsupportedAudioFileException e) {
1042                        continue;
1043                    }
1044                }
1045
1046                if (format == null) {
1047                    throw new UnsupportedAudioFileException(
1048                            "file is not a supported file type");
1049                } else {
1050                    return format;
1051                }
1052            }
1053
1054            /**
1055             * Obtains the audio file format of the specified <code>File</code>.  The <code>File</code> must
1056             * point to valid audio file data.
1057             * @param file the <code>File</code> from which file format information should be
1058             * extracted
1059             * @return an <code>AudioFileFormat</code> object describing the audio file format
1060             * @throws UnsupportedAudioFileException if the <code>File</code> does not point to valid audio
1061             * file data recognized by the system
1062             * @throws IOException if an I/O exception occurs
1063             */
1064            public static AudioFileFormat getAudioFileFormat(File file)
1065                    throws UnsupportedAudioFileException, IOException {
1066
1067                List providers = getAudioFileReaders();
1068                AudioFileFormat format = null;
1069
1070                for (int i = 0; i < providers.size(); i++) {
1071                    AudioFileReader reader = (AudioFileReader) providers.get(i);
1072                    try {
1073                        format = reader.getAudioFileFormat(file); // throws IOException
1074                        break;
1075                    } catch (UnsupportedAudioFileException e) {
1076                        continue;
1077                    }
1078                }
1079
1080                if (format == null) {
1081                    throw new UnsupportedAudioFileException(
1082                            "file is not a supported file type");
1083                } else {
1084                    return format;
1085                }
1086            }
1087
1088            /**
1089             * Obtains an audio input stream from the provided input stream.  The stream must
1090             * point to valid audio file data.  The implementation of this method may
1091             * require multiple parsers to
1092             * examine the stream to determine whether they support it.  These parsers must
1093             * be able to mark the stream, read enough data to determine whether they
1094             * support the stream, and, if not, reset the stream's read pointer to its original
1095             * position.  If the input stream does not support these operation, this method may fail
1096             * with an <code>IOException</code>.
1097             * @param stream the input stream from which the <code>AudioInputStream</code> should be
1098             * constructed
1099             * @return an <code>AudioInputStream</code> object based on the audio file data contained
1100             * in the input stream.
1101             * @throws UnsupportedAudioFileException if the stream does not point to valid audio
1102             * file data recognized by the system
1103             * @throws IOException if an I/O exception occurs
1104             * @see InputStream#markSupported
1105             * @see InputStream#mark
1106             */
1107            public static AudioInputStream getAudioInputStream(
1108                    InputStream stream) throws UnsupportedAudioFileException,
1109                    IOException {
1110
1111                List providers = getAudioFileReaders();
1112                AudioInputStream audioStream = null;
1113
1114                for (int i = 0; i < providers.size(); i++) {
1115                    AudioFileReader reader = (AudioFileReader) providers.get(i);
1116                    try {
1117                        audioStream = reader.getAudioInputStream(stream); // throws IOException
1118                        break;
1119                    } catch (UnsupportedAudioFileException e) {
1120                        continue;
1121                    }
1122                }
1123
1124                if (audioStream == null) {
1125                    throw new UnsupportedAudioFileException(
1126                            "could not get audio input stream from input stream");
1127                } else {
1128                    return audioStream;
1129                }
1130            }
1131
1132            /**
1133             * Obtains an audio input stream from the URL provided.  The URL must
1134             * point to valid audio file data.
1135             * @param url the URL for which the <code>AudioInputStream</code> should be
1136             * constructed
1137             * @return an <code>AudioInputStream</code> object based on the audio file data pointed
1138             * to by the URL
1139             * @throws UnsupportedAudioFileException if the URL does not point to valid audio
1140             * file data recognized by the system
1141             * @throws IOException if an I/O exception occurs
1142             */
1143            public static AudioInputStream getAudioInputStream(URL url)
1144                    throws UnsupportedAudioFileException, IOException {
1145
1146                List providers = getAudioFileReaders();
1147                AudioInputStream audioStream = null;
1148
1149                for (int i = 0; i < providers.size(); i++) {
1150                    AudioFileReader reader = (AudioFileReader) providers.get(i);
1151                    try {
1152                        audioStream = reader.getAudioInputStream(url); // throws IOException
1153                        break;
1154                    } catch (UnsupportedAudioFileException e) {
1155                        continue;
1156                    }
1157                }
1158
1159                if (audioStream == null) {
1160                    throw new UnsupportedAudioFileException(
1161                            "could not get audio input stream from input URL");
1162                } else {
1163                    return audioStream;
1164                }
1165            }
1166
1167            /**
1168             * Obtains an audio input stream from the provided <code>File</code>.  The <code>File</code> must
1169             * point to valid audio file data.
1170             * @param file the <code>File</code> for which the <code>AudioInputStream</code> should be
1171             * constructed
1172             * @return an <code>AudioInputStream</code> object based on the audio file data pointed
1173             * to by the <code>File</code>
1174             * @throws UnsupportedAudioFileException if the <code>File</code> does not point to valid audio
1175             * file data recognized by the system
1176             * @throws IOException if an I/O exception occurs
1177             */
1178            public static AudioInputStream getAudioInputStream(File file)
1179                    throws UnsupportedAudioFileException, IOException {
1180
1181                List providers = getAudioFileReaders();
1182                AudioInputStream audioStream = null;
1183
1184                for (int i = 0; i < providers.size(); i++) {
1185                    AudioFileReader reader = (AudioFileReader) providers.get(i);
1186                    try {
1187                        audioStream = reader.getAudioInputStream(file); // throws IOException
1188                        break;
1189                    } catch (UnsupportedAudioFileException e) {
1190                        continue;
1191                    }
1192                }
1193
1194                if (audioStream == null) {
1195                    throw new UnsupportedAudioFileException(
1196                            "could not get audio input stream from input file");
1197                } else {
1198                    return audioStream;
1199                }
1200            }
1201
1202            /**
1203             * Obtains the file types for which file writing support is provided by the system.
1204             * @return array of unique file types.  If no file types are supported,
1205             * an array of length 0 is returned.
1206             */
1207            public static AudioFileFormat.Type[] getAudioFileTypes() {
1208                List providers = getAudioFileWriters();
1209                Set returnTypesSet = new HashSet();
1210
1211                for (int i = 0; i < providers.size(); i++) {
1212                    AudioFileWriter writer = (AudioFileWriter) providers.get(i);
1213                    AudioFileFormat.Type[] fileTypes = writer
1214                            .getAudioFileTypes();
1215                    for (int j = 0; j < fileTypes.length; j++) {
1216                        returnTypesSet.add(fileTypes[j]);
1217                    }
1218                }
1219                AudioFileFormat.Type returnTypes[] = (AudioFileFormat.Type[]) returnTypesSet
1220                        .toArray(new AudioFileFormat.Type[0]);
1221                return returnTypes;
1222            }
1223
1224            /**
1225             * Indicates whether file writing support for the specified file type is provided
1226             * by the system.
1227             * @param fileType the file type for which write capabilities are queried
1228             * @return <code>true</code> if the file type is supported,
1229             * otherwise <code>false</code>
1230             */
1231            public static boolean isFileTypeSupported(
1232                    AudioFileFormat.Type fileType) {
1233
1234                List providers = getAudioFileWriters();
1235
1236                for (int i = 0; i < providers.size(); i++) {
1237                    AudioFileWriter writer = (AudioFileWriter) providers.get(i);
1238                    if (writer.isFileTypeSupported(fileType)) {
1239                        return true;
1240                    }
1241                }
1242                return false;
1243            }
1244
1245            /**
1246             * Obtains the file types that the system can write from the
1247             * audio input stream specified.
1248             * @param stream the audio input stream for which audio file type support
1249             * is queried
1250             * @return array of file types.  If no file types are supported,
1251             * an array of length 0 is returned.
1252             */
1253            public static AudioFileFormat.Type[] getAudioFileTypes(
1254                    AudioInputStream stream) {
1255                List providers = getAudioFileWriters();
1256                Set returnTypesSet = new HashSet();
1257
1258                for (int i = 0; i < providers.size(); i++) {
1259                    AudioFileWriter writer = (AudioFileWriter) providers.get(i);
1260                    AudioFileFormat.Type[] fileTypes = writer
1261                            .getAudioFileTypes(stream);
1262                    for (int j = 0; j < fileTypes.length; j++) {
1263                        returnTypesSet.add(fileTypes[j]);
1264                    }
1265                }
1266                AudioFileFormat.Type returnTypes[] = (AudioFileFormat.Type[]) returnTypesSet
1267                        .toArray(new AudioFileFormat.Type[0]);
1268                return returnTypes;
1269            }
1270
1271            /**
1272             * Indicates whether an audio file of the specified file type can be written
1273             * from the indicated audio input stream.
1274             * @param fileType the file type for which write capabilities are queried
1275             * @param stream the stream for which file-writing support is queried
1276             * @return <code>true</code> if the file type is supported for this audio input stream,
1277             * otherwise <code>false</code>
1278             */
1279            public static boolean isFileTypeSupported(
1280                    AudioFileFormat.Type fileType, AudioInputStream stream) {
1281
1282                List providers = getAudioFileWriters();
1283
1284                for (int i = 0; i < providers.size(); i++) {
1285                    AudioFileWriter writer = (AudioFileWriter) providers.get(i);
1286                    if (writer.isFileTypeSupported(fileType, stream)) {
1287                        return true;
1288                    }
1289                }
1290                return false;
1291            }
1292
1293            /**
1294             * Writes a stream of bytes representing an audio file of the specified file type
1295             * to the output stream provided.  Some file types require that
1296             * the length be written into the file header; such files cannot be written from
1297             * start to finish unless the length is known in advance.  An attempt
1298             * to write a file of such a type will fail with an IOException if the length in
1299             * the audio file type is <code>AudioSystem.NOT_SPECIFIED</code>.
1300             *
1301             * @param stream the audio input stream containing audio data to be
1302             * written to the file
1303             * @param fileType the kind of audio file to write
1304             * @param out the stream to which the file data should be written
1305             * @return the number of bytes written to the output stream
1306             * @throws IOException if an input/output exception occurs
1307             * @throws IllegalArgumentException if the file type is not supported by
1308             * the system
1309             * @see #isFileTypeSupported
1310             * @see	#getAudioFileTypes
1311             */
1312            public static int write(AudioInputStream stream,
1313                    AudioFileFormat.Type fileType, OutputStream out)
1314                    throws IOException {
1315
1316                List providers = getAudioFileWriters();
1317                int bytesWritten = 0;
1318                boolean flag = false;
1319
1320                for (int i = 0; i < providers.size(); i++) {
1321                    AudioFileWriter writer = (AudioFileWriter) providers.get(i);
1322                    try {
1323                        bytesWritten = writer.write(stream, fileType, out); // throws IOException
1324                        flag = true;
1325                        break;
1326                    } catch (IllegalArgumentException e) {
1327                        // thrown if this provider cannot write the sequence, try the next
1328                        continue;
1329                    }
1330                }
1331                if (!flag) {
1332                    throw new IllegalArgumentException(
1333                            "could not write audio file: file type not supported: "
1334                                    + fileType);
1335                } else {
1336                    return bytesWritten;
1337                }
1338            }
1339
1340            /**
1341             * Writes a stream of bytes representing an audio file of the specified file type
1342             * to the external file provided.
1343             * @param stream the audio input stream containing audio data to be
1344             * written to the file
1345             * @param fileType the kind of audio file to write
1346             * @param out the external file to which the file data should be written
1347             * @return the number of bytes written to the file
1348             * @throws IOException if an I/O exception occurs
1349             * @throws IllegalArgumentException if the file type is not supported by
1350             * the system
1351             * @see #isFileTypeSupported
1352             * @see	#getAudioFileTypes
1353             */
1354            public static int write(AudioInputStream stream,
1355                    AudioFileFormat.Type fileType, File out) throws IOException {
1356
1357                List providers = getAudioFileWriters();
1358                int bytesWritten = 0;
1359                boolean flag = false;
1360
1361                for (int i = 0; i < providers.size(); i++) {
1362                    AudioFileWriter writer = (AudioFileWriter) providers.get(i);
1363                    try {
1364                        bytesWritten = writer.write(stream, fileType, out); // throws IOException
1365                        flag = true;
1366                        break;
1367                    } catch (IllegalArgumentException e) {
1368                        // thrown if this provider cannot write the sequence, try the next
1369                        continue;
1370                    }
1371                }
1372                if (!flag) {
1373                    throw new IllegalArgumentException(
1374                            "could not write audio file: file type not supported: "
1375                                    + fileType);
1376                } else {
1377                    return bytesWritten;
1378                }
1379            }
1380
1381            // METHODS FOR INTERNAL IMPLEMENTATION USE
1382
1383            /**
1384             * Obtains the set of MixerProviders on the system.
1385             */
1386            private static List getMixerProviders() {
1387                return getProviders(MixerProvider.class);
1388            }
1389
1390            /**
1391             * Obtains the set of format converters (codecs, transcoders, etc.)
1392             * that are currently installed on the system.
1393             * @return an array of
1394             * {@link javax.sound.sampled.spi.FormatConversionProvider
1395             * FormatConversionProvider}
1396             * objects representing the available format converters.  If no format
1397             * converters readers are available on the system, an array of length 0 is
1398             * returned.
1399             */
1400            private static List getFormatConversionProviders() {
1401                return getProviders(FormatConversionProvider.class);
1402            }
1403
1404            /**
1405             * Obtains the set of audio file readers that are currently installed on the system.
1406             * @return a List of
1407             * {@link javax.sound.sampled.spi.AudioFileReader
1408             * AudioFileReader}
1409             * objects representing the installed audio file readers.  If no audio file
1410             * readers are available on the system, an empty List is returned.
1411             */
1412            private static List getAudioFileReaders() {
1413                return getProviders(AudioFileReader.class);
1414            }
1415
1416            /**
1417             * Obtains the set of audio file writers that are currently installed on the system.
1418             * @return a List of
1419             * {@link javax.sound.samples.spi.AudioFileWriter AudioFileWriter}
1420             * objects representing the available audio file writers.  If no audio file
1421             * writers are available on the system, an empty List is returned.
1422             */
1423            private static List getAudioFileWriters() {
1424                return getProviders(AudioFileWriter.class);
1425            }
1426
1427            /** Attempts to locate and return a default Mixer that provides lines
1428             * of the specified type.
1429             *
1430             * @param providers the installed mixer providers
1431             * @param info The requested line type
1432             * TargetDataLine.class, Clip.class or Port.class.
1433             * @return a Mixer that matches the requirements, or null if no default mixer found
1434             */
1435            private static Mixer getDefaultMixer(List providers, Line.Info info) {
1436                Class lineClass = info.getLineClass();
1437                String providerClassName = JDK13Services
1438                        .getDefaultProviderClassName(lineClass);
1439                String instanceName = JDK13Services
1440                        .getDefaultInstanceName(lineClass);
1441                Mixer mixer;
1442
1443                if (providerClassName != null) {
1444                    MixerProvider defaultProvider = getNamedProvider(
1445                            providerClassName, providers);
1446                    if (defaultProvider != null) {
1447                        if (instanceName != null) {
1448                            mixer = getNamedMixer(instanceName,
1449                                    defaultProvider, info);
1450                            if (mixer != null) {
1451                                return mixer;
1452                            }
1453                        } else {
1454                            mixer = getFirstMixer(defaultProvider, info, false /* mixing not required*/);
1455                            if (mixer != null) {
1456                                return mixer;
1457                            }
1458                        }
1459
1460                    }
1461                }
1462
1463                /* Provider class not specified or
1464                   provider class cannot be found, or
1465                   provider class and instance specified and instance cannot be found or is not appropriate */
1466                if (instanceName != null) {
1467                    mixer = getNamedMixer(instanceName, providers, info);
1468                    if (mixer != null) {
1469                        return mixer;
1470                    }
1471                }
1472
1473                /* No default are specified, or if something is specified, everything
1474                   failed. */
1475                return null;
1476            }
1477
1478            /** Return a MixerProvider of a given class from the list of
1479            MixerProviders.
1480
1481            This method never requires the returned Mixer to do mixing.
1482            @param providerClassName The class name of the provider to be returned.
1483            @param providers The list of MixerProviders that is searched.
1484            @return A MixerProvider of the requested class, or null if none is
1485            found.
1486             */
1487            private static MixerProvider getNamedProvider(
1488                    String providerClassName, List providers) {
1489                for (int i = 0; i < providers.size(); i++) {
1490                    MixerProvider provider = (MixerProvider) providers.get(i);
1491                    if (provider.getClass().getName().equals(providerClassName)) {
1492                        return provider;
1493                    }
1494                }
1495                return null;
1496            }
1497
1498            /** Return a Mixer with a given name from a given MixerProvider.
1499              This method never requires the returned Mixer to do mixing.
1500              @param mixerName The name of the Mixer to be returned.
1501              @param provider The MixerProvider to check for Mixers.
1502              @param info The type of line the returned Mixer is required to
1503              support.
1504
1505              @return A Mixer matching the requirements, or null if none is found.
1506             */
1507            private static Mixer getNamedMixer(String mixerName,
1508                    MixerProvider provider, Line.Info info) {
1509                Mixer.Info[] infos = provider.getMixerInfo();
1510                for (int i = 0; i < infos.length; i++) {
1511                    if (infos[i].getName().equals(mixerName)) {
1512                        Mixer mixer = provider.getMixer(infos[i]);
1513                        if (isAppropriateMixer(mixer, info, false)) {
1514                            return mixer;
1515                        }
1516                    }
1517                }
1518                return null;
1519            }
1520
1521            /** From a List of MixerProviders, return a Mixer with a given name.
1522            This method never requires the returned Mixer to do mixing.
1523            @param mixerName The name of the Mixer to be returned.
1524            @param providers The List of MixerProviders to check for Mixers.
1525            @param info The type of line the returned Mixer is required to
1526            support.
1527            @return A Mixer matching the requirements, or null if none is found.
1528             */
1529            private static Mixer getNamedMixer(String mixerName,
1530                    List providers, Line.Info info) {
1531                for (int i = 0; i < providers.size(); i++) {
1532                    MixerProvider provider = (MixerProvider) providers.get(i);
1533                    Mixer mixer = getNamedMixer(mixerName, provider, info);
1534                    if (mixer != null) {
1535                        return mixer;
1536                    }
1537                }
1538                return null;
1539            }
1540
1541            /** From a given MixerProvider, return the first appropriate Mixer.
1542            @param provider The MixerProvider to check for Mixers.
1543            @param info The type of line the returned Mixer is required to
1544            support.
1545            @param isMixingRequired If true, only Mixers that support mixing are
1546            returned for line types of SourceDataLine and Clip.
1547
1548            @return A Mixer that is considered appropriate, or null
1549            if none is found.
1550             */
1551            private static Mixer getFirstMixer(MixerProvider provider,
1552                    Line.Info info, boolean isMixingRequired) {
1553                Mixer.Info[] infos = provider.getMixerInfo();
1554                for (int j = 0; j < infos.length; j++) {
1555                    Mixer mixer = provider.getMixer(infos[j]);
1556                    if (isAppropriateMixer(mixer, info, isMixingRequired)) {
1557                        return mixer;
1558                    }
1559                }
1560                return null;
1561            }
1562
1563            /** Checks if a Mixer is appropriate.
1564            A Mixer is considered appropriate if it support the given line type.
1565            If isMixingRequired is true and the line type is an output one
1566            (SourceDataLine, Clip), the mixer is appropriate if it supports
1567            at least 2 (concurrent) lines of the given type.
1568
1569            @return true if the mixer is considered appropriate according to the
1570            rules given above, false otherwise.
1571             */
1572            private static boolean isAppropriateMixer(Mixer mixer,
1573                    Line.Info lineInfo, boolean isMixingRequired) {
1574                if (!mixer.isLineSupported(lineInfo)) {
1575                    return false;
1576                }
1577                Class lineClass = lineInfo.getLineClass();
1578                if (isMixingRequired
1579                        && (SourceDataLine.class.isAssignableFrom(lineClass) || Clip.class
1580                                .isAssignableFrom(lineClass))) {
1581                    int maxLines = mixer.getMaxLines(lineInfo);
1582                    return ((maxLines == NOT_SPECIFIED) || (maxLines > 1));
1583                }
1584                return true;
1585            }
1586
1587            /**
1588             * Like getMixerInfo, but return List
1589             */
1590            private static List getMixerInfoList() {
1591                List providers = getMixerProviders();
1592                return getMixerInfoList(providers);
1593            }
1594
1595            /**
1596             * Like getMixerInfo, but return List
1597             */
1598            private static List getMixerInfoList(List providers) {
1599                List infos = new ArrayList();
1600
1601                Mixer.Info[] someInfos; // per-mixer
1602                Mixer.Info[] allInfos; // for all mixers
1603
1604                for (int i = 0; i < providers.size(); i++) {
1605                    someInfos = (Mixer.Info[]) ((MixerProvider) providers
1606                            .get(i)).getMixerInfo();
1607
1608                    for (int j = 0; j < someInfos.length; j++) {
1609                        infos.add(someInfos[j]);
1610                    }
1611                }
1612
1613                return infos;
1614            }
1615
1616            /**
1617             * Obtains the set of services currently installed on the system
1618             * using sun.misc.Service, the SPI mechanism in 1.3.
1619             * @return a List of instances of providers for the requested service.
1620             * If no providers are available, a vector of length 0 will be returned.
1621             */
1622            private static List getProviders(Class providerClass) {
1623                return JDK13Services.getProviders(providerClass);
1624            }
1625        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.