9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.sound.sampled; 27 28 import java.io.File; 29 import java.io.InputStream; 30 import java.io.IOException; 31 import java.io.OutputStream; 32 import java.net.URL; 33 34 import java.util.HashSet; 35 import java.util.List; 36 import java.util.Set; 37 import java.util.Vector; 38 import java.util.ArrayList; 39 40 import javax.sound.sampled.spi.AudioFileWriter; 41 import javax.sound.sampled.spi.AudioFileReader; 42 import javax.sound.sampled.spi.FormatConversionProvider; 43 import javax.sound.sampled.spi.MixerProvider; 44 45 import com.sun.media.sound.JDK13Services; 46 47 /* $fb TODO: 48 * - consistent usage of (typed) collections 49 */ 50 51 52 /** 53 * The {@code AudioSystem} class acts as the entry point to the sampled-audio 54 * system resources. This class lets you query and access the mixers that are 55 * installed on the system. {@code AudioSystem} includes a number of methods for 56 * converting audio data between different formats, and for translating between 57 * audio files and streams. It also provides a method for obtaining a 58 * {@link Line} directly from the {@code AudioSystem} without dealing explicitly 59 * with mixers. 60 * <p> 61 * Properties can be used to specify the default mixer for specific line types. 62 * Both system properties and a properties file are considered. The 63 * {@code sound.properties} properties file is read from an 64 * implementation-specific location (typically it is the {@code lib} directory 65 * in the Java installation directory). If a property exists both as a system 66 * property and in the properties file, the system property takes precedence. 67 * If none is specified, a suitable default is chosen among the available 68 * devices. The syntax of the properties file is specified in 69 * {@link java.util.Properties#load(InputStream) Properties.load}. The following 70 * table lists the available property keys and which methods consider them: 71 * 72 * <table border=0> 73 * <caption>Audio System Property Keys</caption> 74 * <tr> 75 * <th>Property Key</th> 76 * <th>Interface</th> 77 * <th>Affected Method(s)</th> 78 * </tr> 79 * <tr> 80 * <td>{@code javax.sound.sampled.Clip}</td> 81 * <td>{@link Clip}</td> 82 * <td>{@link #getLine}, {@link #getClip}</td> 83 * </tr> 84 * <tr> 85 * <td>{@code javax.sound.sampled.Port}</td> 86 * <td>{@link Port}</td> 87 * <td>{@link #getLine}</td> 88 * </tr> 89 * <tr> 90 * <td>{@code javax.sound.sampled.SourceDataLine}</td> 91 * <td>{@link SourceDataLine}</td> 92 * <td>{@link #getLine}, {@link #getSourceDataLine}</td> 93 * </tr> 94 * <tr> 95 * <td>{@code javax.sound.sampled.TargetDataLine}</td> 96 * <td>{@link TargetDataLine}</td> 97 * <td>{@link #getLine}, {@link #getTargetDataLine}</td> 98 * </tr> 99 * </table> 100 * 101 * The property value consists of the provider class name and the mixer name, 102 * separated by the hash mark ("#"). The provider class name is the 103 * fully-qualified name of a concrete 104 * {@link javax.sound.sampled.spi.MixerProvider mixer provider} class. The mixer 105 * name is matched against the {@code String} returned by the {@code getName} 106 * method of {@code Mixer.Info}. Either the class name, or the mixer name may be 107 * omitted. If only the class name is specified, the trailing hash mark is 108 * optional. 109 * <p> 110 * If the provider class is specified, and it can be successfully retrieved from 111 * the installed providers, the list of {@code Mixer.Info} objects is retrieved 112 * from the provider. Otherwise, or when these mixers do not provide a 113 * subsequent match, the list is retrieved from {@link #getMixerInfo} to contain 114 * all available {@code Mixer.Info} objects. 115 * <p> 116 * If a mixer name is specified, the resulting list of {@code Mixer.Info} 117 * objects is searched: the first one with a matching name, and whose 118 * {@code Mixer} provides the respective line interface, will be returned. If no 119 * matching {@code Mixer.Info} object is found, or the mixer name is not 120 * specified, the first mixer from the resulting list, which provides the 121 * respective line interface, will be returned. 122 * 123 * For example, the property {@code javax.sound.sampled.Clip} with a value 124 * {@code "com.sun.media.sound.MixerProvider#SunClip"} 125 * will have the following consequences when {@code getLine} is called 126 * requesting a {@code Clip} instance: if the class 127 * {@code com.sun.media.sound.MixerProvider} exists in the list of installed 128 * mixer providers, the first {@code Clip} from the first mixer with name 1307 throw new IllegalArgumentException("could not write audio file: file type not supported: " + fileType); 1308 } else { 1309 return bytesWritten; 1310 } 1311 } 1312 1313 // METHODS FOR INTERNAL IMPLEMENTATION USE 1314 1315 /** 1316 * Obtains the set of MixerProviders on the system. 1317 */ 1318 @SuppressWarnings("unchecked") 1319 private static List<MixerProvider> getMixerProviders() { 1320 return (List<MixerProvider>) getProviders(MixerProvider.class); 1321 } 1322 1323 /** 1324 * Obtains the set of format converters (codecs, transcoders, etc.) that are 1325 * currently installed on the system. 1326 * 1327 * @return an array of {@link javax.sound.sampled.spi.FormatConversionProvider 1328 * FormatConversionProvider} objects representing the available 1329 * format converters. If no format converters readers are available 1330 * on the system, an array of length 0 is returned. 1331 */ 1332 @SuppressWarnings("unchecked") 1333 private static List<FormatConversionProvider> getFormatConversionProviders() { 1334 return (List<FormatConversionProvider>) getProviders(FormatConversionProvider.class); 1335 } 1336 1337 /** 1338 * Obtains the set of audio file readers that are currently installed on the 1339 * system. 1340 * 1341 * @return a List of {@link javax.sound.sampled.spi.AudioFileReader 1342 * AudioFileReader} objects representing the installed audio file 1343 * readers. If no audio file readers are available on the system, an 1344 * empty List is returned. 1345 */ 1346 @SuppressWarnings("unchecked") 1347 private static List<AudioFileReader> getAudioFileReaders() { 1348 return (List<AudioFileReader>)getProviders(AudioFileReader.class); 1349 } 1350 1351 /** 1352 * Obtains the set of audio file writers that are currently installed on the 1353 * system. 1354 * 1355 * @return a List of {@link javax.sound.sampled.spi.AudioFileWriter 1356 * AudioFileWriter} objects representing the available audio file 1357 * writers. If no audio file writers are available on the system, an 1358 * empty List is returned. 1359 */ 1360 @SuppressWarnings("unchecked") 1361 private static List<AudioFileWriter> getAudioFileWriters() { 1362 return (List<AudioFileWriter>)getProviders(AudioFileWriter.class); 1363 } 1364 1365 /** 1366 * Attempts to locate and return a default Mixer that provides lines of the 1367 * specified type. 1368 * 1369 * @param providers the installed mixer providers 1370 * @param info The requested line type TargetDataLine.class, Clip.class or 1371 * Port.class 1372 * @return a Mixer that matches the requirements, or null if no default 1373 * mixer found 1374 */ 1375 private static Mixer getDefaultMixer(List<MixerProvider> providers, Line.Info info) { 1376 Class<?> lineClass = info.getLineClass(); 1377 String providerClassName = JDK13Services.getDefaultProviderClassName(lineClass); 1378 String instanceName = JDK13Services.getDefaultInstanceName(lineClass); | 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.sound.sampled; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.io.OutputStream; 32 import java.net.URL; 33 import java.util.ArrayList; 34 import java.util.HashSet; 35 import java.util.List; 36 import java.util.Properties; 37 import java.util.Set; 38 import java.util.Vector; 39 40 import javax.sound.sampled.spi.AudioFileReader; 41 import javax.sound.sampled.spi.AudioFileWriter; 42 import javax.sound.sampled.spi.FormatConversionProvider; 43 import javax.sound.sampled.spi.MixerProvider; 44 45 import com.sun.media.sound.JDK13Services; 46 47 /* $fb TODO: 48 * - consistent usage of (typed) collections 49 */ 50 51 52 /** 53 * The {@code AudioSystem} class acts as the entry point to the sampled-audio 54 * system resources. This class lets you query and access the mixers that are 55 * installed on the system. {@code AudioSystem} includes a number of methods for 56 * converting audio data between different formats, and for translating between 57 * audio files and streams. It also provides a method for obtaining a 58 * {@link Line} directly from the {@code AudioSystem} without dealing explicitly 59 * with mixers. 60 * <p> 61 * Properties can be used to specify the default mixer for specific line types. 62 * Both system properties and a properties file are considered. The 63 * "sound.properties" properties file is read from an implementation-specific 64 * location (typically it is the {@code lib} directory in the Java installation 65 * directory). If a property exists both as a system property and in the 66 * properties file, the system property takes precedence. If none is specified, 67 * a suitable default is chosen among the available devices. The syntax of the 68 * properties file is specified in 69 * {@link Properties#load(InputStream) Properties.load}. The following table 70 * lists the available property keys and which methods consider them: 71 * 72 * <table border=0> 73 * <caption>Audio System Property Keys</caption> 74 * <tr> 75 * <th>Property Key</th> 76 * <th>Interface</th> 77 * <th>Affected Method(s)</th> 78 * </tr> 79 * <tr> 80 * <td>{@code javax.sound.sampled.Clip}</td> 81 * <td>{@link Clip}</td> 82 * <td>{@link #getLine}, {@link #getClip}</td> 83 * </tr> 84 * <tr> 85 * <td>{@code javax.sound.sampled.Port}</td> 86 * <td>{@link Port}</td> 87 * <td>{@link #getLine}</td> 88 * </tr> 89 * <tr> 90 * <td>{@code javax.sound.sampled.SourceDataLine}</td> 91 * <td>{@link SourceDataLine}</td> 92 * <td>{@link #getLine}, {@link #getSourceDataLine}</td> 93 * </tr> 94 * <tr> 95 * <td>{@code javax.sound.sampled.TargetDataLine}</td> 96 * <td>{@link TargetDataLine}</td> 97 * <td>{@link #getLine}, {@link #getTargetDataLine}</td> 98 * </tr> 99 * </table> 100 * 101 * The property value consists of the provider class name and the mixer name, 102 * separated by the hash mark ("#"). The provider class name is the 103 * fully-qualified name of a concrete {@link MixerProvider mixer provider} 104 * class. The mixer name is matched against the {@code String} returned by the 105 * {@code getName} method of {@code Mixer.Info}. Either the class name, or the 106 * mixer name may be omitted. If only the class name is specified, the trailing 107 * hash mark is optional. 108 * <p> 109 * If the provider class is specified, and it can be successfully retrieved from 110 * the installed providers, the list of {@code Mixer.Info} objects is retrieved 111 * from the provider. Otherwise, or when these mixers do not provide a 112 * subsequent match, the list is retrieved from {@link #getMixerInfo} to contain 113 * all available {@code Mixer.Info} objects. 114 * <p> 115 * If a mixer name is specified, the resulting list of {@code Mixer.Info} 116 * objects is searched: the first one with a matching name, and whose 117 * {@code Mixer} provides the respective line interface, will be returned. If no 118 * matching {@code Mixer.Info} object is found, or the mixer name is not 119 * specified, the first mixer from the resulting list, which provides the 120 * respective line interface, will be returned. 121 * 122 * For example, the property {@code javax.sound.sampled.Clip} with a value 123 * {@code "com.sun.media.sound.MixerProvider#SunClip"} 124 * will have the following consequences when {@code getLine} is called 125 * requesting a {@code Clip} instance: if the class 126 * {@code com.sun.media.sound.MixerProvider} exists in the list of installed 127 * mixer providers, the first {@code Clip} from the first mixer with name 1306 throw new IllegalArgumentException("could not write audio file: file type not supported: " + fileType); 1307 } else { 1308 return bytesWritten; 1309 } 1310 } 1311 1312 // METHODS FOR INTERNAL IMPLEMENTATION USE 1313 1314 /** 1315 * Obtains the set of MixerProviders on the system. 1316 */ 1317 @SuppressWarnings("unchecked") 1318 private static List<MixerProvider> getMixerProviders() { 1319 return (List<MixerProvider>) getProviders(MixerProvider.class); 1320 } 1321 1322 /** 1323 * Obtains the set of format converters (codecs, transcoders, etc.) that are 1324 * currently installed on the system. 1325 * 1326 * @return an array of {@link FormatConversionProvider} objects representing 1327 * the available format converters. If no format converters readers 1328 * are available on the system, an array of length 0 is returned. 1329 */ 1330 @SuppressWarnings("unchecked") 1331 private static List<FormatConversionProvider> getFormatConversionProviders() { 1332 return (List<FormatConversionProvider>) getProviders(FormatConversionProvider.class); 1333 } 1334 1335 /** 1336 * Obtains the set of audio file readers that are currently installed on the 1337 * system. 1338 * 1339 * @return a List of {@link AudioFileReader} objects representing the 1340 * installed audio file readers. If no audio file readers are 1341 * available on the system, an empty List is returned. 1342 */ 1343 @SuppressWarnings("unchecked") 1344 private static List<AudioFileReader> getAudioFileReaders() { 1345 return (List<AudioFileReader>)getProviders(AudioFileReader.class); 1346 } 1347 1348 /** 1349 * Obtains the set of audio file writers that are currently installed on the 1350 * system. 1351 * 1352 * @return a List of {@link AudioFileWriter} objects representing the 1353 * available audio file writers. If no audio file writers are 1354 * available on the system, an empty List is returned. 1355 */ 1356 @SuppressWarnings("unchecked") 1357 private static List<AudioFileWriter> getAudioFileWriters() { 1358 return (List<AudioFileWriter>)getProviders(AudioFileWriter.class); 1359 } 1360 1361 /** 1362 * Attempts to locate and return a default Mixer that provides lines of the 1363 * specified type. 1364 * 1365 * @param providers the installed mixer providers 1366 * @param info The requested line type TargetDataLine.class, Clip.class or 1367 * Port.class 1368 * @return a Mixer that matches the requirements, or null if no default 1369 * mixer found 1370 */ 1371 private static Mixer getDefaultMixer(List<MixerProvider> providers, Line.Info info) { 1372 Class<?> lineClass = info.getLineClass(); 1373 String providerClassName = JDK13Services.getDefaultProviderClassName(lineClass); 1374 String instanceName = JDK13Services.getDefaultInstanceName(lineClass); |