1/* 2 * Copyright (c) 2002, 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 24import javax.sound.sampled.AudioFormat; 25import javax.sound.sampled.AudioSystem; 26import javax.sound.sampled.DataLine; 27import javax.sound.sampled.LineEvent; 28import javax.sound.sampled.LineListener; 29import javax.sound.sampled.LineUnavailableException; 30import javax.sound.sampled.Mixer; 31import javax.sound.sampled.SourceDataLine; 32 33/** 34 * @test 35 * @bug 4498848 36 * @summary Sound causes crashes on Linux (part 2) 37 */ 38public class SDLLinuxCrash implements Runnable { 39 SourceDataLine sdl; 40 int size; 41 42 SDLLinuxCrash(SourceDataLine sdl, int size) { 43 this.sdl = sdl; 44 this.size = size - (size % 4); 45 } 46 47 public void run() { 48 int written=0; 49 //byte[] buffer = new byte[4096]; 50 byte[] buffer = data; 51 out(" starting data line feed thread."); 52 try { 53 while (written<size) { 54 int toWrite = buffer.length; 55 if (toWrite+written > size) { 56 toWrite = size-written; 57 } 58 toWrite -= (toWrite % 4); 59 //out(" writing "+toWrite+" bytes."); 60 int thisWritten = sdl.write(buffer, 0, toWrite); 61 if (thisWritten<toWrite) { 62 out(" only wrote "+thisWritten+" bytes instead of "+toWrite); 63 } 64 if (thisWritten<=0) { 65 break; 66 } 67 written += thisWritten; 68 } 69 } catch (Throwable t) { 70 t.printStackTrace(); 71 } 72 out(" leaving data line feed thread."); 73 } 74 75 public static long bytes2Ms(long bytes, AudioFormat format) { 76 return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize()); 77 } 78 79 static int staticLen=1000; 80 static boolean addLen=true; 81 82 public static SourceDataLine start() throws Exception { 83 AudioFormat format = new AudioFormat(44100, 16, 2, true, false); 84 if (addLen) { 85 staticLen+=(int) (staticLen/5)+1000; 86 } else { 87 staticLen-=(int) (staticLen/5)+1000; 88 } 89 if (staticLen>8*44100*4) { 90 staticLen = 8*44100*4; 91 addLen=!addLen; 92 } 93 if (staticLen<1000) { 94 staticLen = 1000; 95 addLen=!addLen; 96 } 97 int len = staticLen; 98 len -= (len % 4); 99 out(" preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio..."); 100 101 DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); 102 SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info); 103 sdl.addLineListener(new LineListener() { 104 public void update(LineEvent e) { 105 if (e.getType() == LineEvent.Type.STOP) { 106 out(" calling close() from event dispatcher thread"); 107 ((SourceDataLine) e.getSource()).close(); 108 } 109 else if (e.getType() == LineEvent.Type.CLOSE) { 110 } 111 } 112 }); 113 114 out(" opening..."); 115 sdl.open(); 116 out(" starting..."); 117 sdl.start(); 118 (new Thread(new SDLLinuxCrash(sdl, len))).start(); 119 return sdl; 120 } 121 122 public static void main(String[] args) throws Exception { 123 if (!isSoundcardInstalled()) { 124 return; 125 } 126 127 try { 128 int COUNT=10; 129 out(); 130 out("4498848 Sound causes crashes on Linux (testing with SourceDataLine)"); 131 if (args.length>0) { 132 COUNT=Integer.parseInt(args[0]); 133 } 134 for (int i=0; i<COUNT; i++) { 135 out(" trial "+(i+1)+"/"+COUNT); 136 SourceDataLine sdl = start(); 137 int waitTime = 500+(1000*(i % 2)); // every 2nd time wait 1500, rather than 500ms. 138 out(" waiting for "+waitTime+" ms for audio playback to stop..."); 139 Thread.sleep(waitTime); 140 out(" calling close() from main thread"); 141 sdl.close(); 142 // let the subsystem enough time to actually close the soundcard 143 out(" waiting for 2 seconds..."); 144 Thread.sleep(2000); 145 out(); 146 } 147 out(" waiting for 1 second..."); 148 Thread.sleep(1000); 149 } catch (Exception e) { 150 e.printStackTrace(); 151 out(" waiting for 1 second"); 152 try { 153 Thread.sleep(1000); 154 } catch (InterruptedException ie) {} 155 // do not fail if no audio device installed - bug 4742021 156 if (!(e instanceof LineUnavailableException)) { 157 throw e; 158 } 159 } 160 out("Test passed"); 161 } 162 163 static void out() { 164 out(""); 165 } 166 167 static void out(String s) { 168 System.out.println(s); System.out.flush(); 169 } 170 171 /** 172 * Returns true if at least one soundcard is correctly installed 173 * on the system. 174 */ 175 public static boolean isSoundcardInstalled() { 176 boolean result = false; 177 try { 178 Mixer.Info[] mixers = AudioSystem.getMixerInfo(); 179 if (mixers.length > 0) { 180 result = AudioSystem.getSourceDataLine(null) != null; 181 } 182 } catch (Exception e) { 183 System.err.println("Exception occured: "+e); 184 } 185 if (!result) { 186 System.err.println("Soundcard does not exist or sound drivers not installed!"); 187 System.err.println("This test requires sound drivers for execution."); 188 } 189 return result; 190 } 191 192 193 194 static final byte[] data = new byte[] { 195 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 196 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 197 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 198 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 199 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 200 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 201 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 202 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 203 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 204 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 205 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 206 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 207 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 208 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 209 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 210 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 211 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 212 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 213 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 214 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 215 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 216 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 217 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 218 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 219 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 220 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 221 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 222 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 223 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 224 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 225 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 226 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 227 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 228 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 229 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 230 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 231 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 232 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 233 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 234 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 235 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 236 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 237 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 238 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 239 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 240 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 241 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 242 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 243 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 244 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 245 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 246 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 247 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 248 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 249 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 250 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 251 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 252 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 253 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 254 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 255 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 256 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 257 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 258 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 259 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 260 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 261 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 262 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 263 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 264 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 265 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 266 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 267 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 268 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 269 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 270 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 271 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 272 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 273 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 274 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 275 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 276 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 277 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 278 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 279 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 280 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 281 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 282 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 283 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 284 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 285 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 286 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 287 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 288 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 289 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 290 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 291 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 292 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 293 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 294 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 295 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 296 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 297 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 298 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 299 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 300 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 301 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 302 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 303 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 304 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 305 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 306 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 307 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 308 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 309 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 310 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 311 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, 312 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 313 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 314 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 122, 122 315 }; 316 317} 318