1 /* 2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.util.List; 25 26 import javax.sound.sampled.AudioFormat; 27 import javax.sound.sampled.AudioSystem; 28 import javax.sound.sampled.Clip; 29 import javax.sound.sampled.DataLine; 30 import javax.sound.sampled.Line; 31 import javax.sound.sampled.Mixer; 32 import javax.sound.sampled.Port; 33 import javax.sound.sampled.SourceDataLine; 34 import javax.sound.sampled.TargetDataLine; 35 import javax.sound.sampled.spi.MixerProvider; 36 37 import com.sun.media.sound.JDK13Services; 38 39 /** 40 * @test 41 * @bug 4776511 42 * @summary RFE: Setting the default MixerProvider. Test the retrieving of lines 43 * with defaut mixer properties. 44 * @modules java.desktop/com.sun.media.sound 45 */ 46 public class DefaultMixers { 47 48 private static final String ERROR_PROVIDER_CLASS_NAME = "abc"; 49 private static final String ERROR_INSTANCE_NAME = "def"; 50 51 private static final Class[] lineClasses = { 52 SourceDataLine.class, 53 TargetDataLine.class, 54 Clip.class, 55 Port.class, 56 }; 57 58 public static void main(String[] args) throws Exception { 59 boolean allOk = true; 60 Mixer.Info[] infos; 61 62 out("Testing Mixers retrieved via AudioSystem"); 63 infos = AudioSystem.getMixerInfo(); 64 allOk &= testMixers(infos, null); 65 66 out("Testing MixerProviders"); 67 List providers = JDK13Services.getProviders(MixerProvider.class); 68 for (int i = 0; i < providers.size(); i++) { 69 MixerProvider provider = (MixerProvider) providers.get(i); 70 infos = provider.getMixerInfo(); 71 allOk &= testMixers(infos, provider.getClass().getName()); 72 } 73 74 if (! allOk) { 75 throw new Exception("Test failed"); 76 } else { 77 out("Test passed"); 78 } 79 } 80 81 private static boolean testMixers(Mixer.Info[] infos, 82 String providerClassName) { 83 boolean allOk = true; 84 85 for (int i = 0; i < infos.length; i++) { 86 Mixer mixer = null; 87 try { 88 mixer = AudioSystem.getMixer(infos[i]); 89 } catch (NullPointerException e) { 90 out("Exception thrown; Test NOT failed."); 91 e.printStackTrace(); 92 } 93 for (int j = 0; j < lineClasses.length; j++) { 94 if (mixer.isLineSupported(new Line.Info(lineClasses[j]))) { 95 allOk &= testMixer(mixer, lineClasses[j], 96 providerClassName); 97 } 98 } 99 } 100 return allOk; 101 } 102 103 private static boolean testMixer(Mixer mixer, Class lineType, 104 String providerClassName) { 105 boolean allOk = true; 106 String instanceName = mixer.getMixerInfo().getName(); 107 108 // no error 109 allOk &= testMixer(mixer, lineType, 110 providerClassName, instanceName); 111 112 // erroneous provider class name, correct instance name 113 allOk &= testMixer(mixer, lineType, 114 ERROR_PROVIDER_CLASS_NAME, instanceName); 115 116 // erroneous provider class name, no instance name 117 allOk &= testMixer(mixer, lineType, 118 ERROR_PROVIDER_CLASS_NAME, ""); 119 120 // erroneous provider class name, erroneous instance name 121 allOk &= testMixer(mixer, lineType, 122 ERROR_PROVIDER_CLASS_NAME, ERROR_INSTANCE_NAME); 123 124 return allOk; 125 } 126 127 private static boolean testMixer(Mixer mixer, Class lineType, 128 String providerClassName, 129 String instanceName) { 130 boolean allOk = true; 131 132 try { 133 String propertyValue = (providerClassName != null) ? providerClassName: "" ; 134 propertyValue += "#" + instanceName; 135 out("property value: " + propertyValue); 136 System.setProperty(lineType.getName(), propertyValue); 137 Line line = null; 138 Line.Info info = null; 139 Line.Info[] infos; 140 AudioFormat format = null; 141 if (lineType == SourceDataLine.class || lineType == Clip.class) { 142 infos = mixer.getSourceLineInfo(); 143 format = getFirstLinearFormat(infos); 144 info = new DataLine.Info(lineType, format); 145 } else if (lineType == TargetDataLine.class) { 146 infos = mixer.getTargetLineInfo(); 147 format = getFirstLinearFormat(infos); 148 info = new DataLine.Info(lineType, format); 149 } else if (lineType == Port.class) { 150 /* Actually, a Ports Mixer commonly has source infos 151 as well as target infos. We ignore this here, since we 152 just need a random one. */ 153 infos = mixer.getSourceLineInfo(); 154 for (int i = 0; i < infos.length; i++) { 155 if (infos[i] instanceof Port.Info) { 156 info = infos[i]; 157 break; 158 } 159 } 160 } 161 out("Line.Info: " + info); 162 line = AudioSystem.getLine(info); 163 out("line: " + line); 164 if (! lineType.isInstance(line)) { 165 out("type " + lineType + " failed: class should be '" + 166 lineType + "' but is '" + line.getClass() + "'!"); 167 allOk = false; 168 } 169 } catch (Exception e) { 170 out("Exception thrown; Test NOT failed."); 171 e.printStackTrace(); 172 } 173 return allOk; 174 } 175 176 private static AudioFormat getFirstLinearFormat(Line.Info[] infos) { 177 for (int i = 0; i < infos.length; i++) { 178 if (infos[i] instanceof DataLine.Info) { 179 AudioFormat[] formats = ((DataLine.Info) infos[i]).getFormats(); 180 for (int j = 0; j < formats.length; j++) { 181 AudioFormat.Encoding encoding = formats[j].getEncoding(); 182 int sampleSizeInBits = formats[j].getSampleSizeInBits(); 183 if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED) && 184 sampleSizeInBits == 16 || 185 encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED) && 186 sampleSizeInBits == 16) { 187 return formats[j]; 188 } 189 } 190 } 191 } 192 return null; 193 } 194 195 private static void out(String message) { 196 System.out.println(message); 197 } 198 }