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 24import javax.sound.sampled.AudioFormat; 25import javax.sound.sampled.AudioSystem; 26import javax.sound.sampled.DataLine; 27import javax.sound.sampled.LineUnavailableException; 28import javax.sound.sampled.Mixer; 29import javax.sound.sampled.TargetDataLine; 30 31/** 32 * @test 33 * @bug 4836433 34 * @summary Windows: TargetDataLine.flush() does not work. Since this test has 35 * some real-time variance, I disabled it by making it a manual test. 36 * @run main/manual TargetDataLineFlush 37 */ 38public class TargetDataLineFlush { 39 TargetDataLine inLine; 40 int SAMPLE_RATE = 11025; 41 int BUFFER_MILLIS = 1000; 42 int WAIT_MILLIS; 43 int BITS = 16; 44 int CHANNELS = 2; 45 int bufferSize; 46 AudioFormat format; 47 Mixer.Info[] mixers; 48 static boolean failed = false; 49 50 public TargetDataLineFlush() { 51 mixers = AudioSystem.getMixerInfo(); 52 } 53 54 private void init() { 55 // float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian 56 format = new AudioFormat( (float) SAMPLE_RATE, BITS, CHANNELS, true, false); 57 bufferSize = SAMPLE_RATE * BUFFER_MILLIS / 1000 * format.getFrameSize(); 58 } 59 60 boolean openInputLine(int num) throws LineUnavailableException { 61 init(); 62 DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // format is an AudioFormat object 63 // Obtain and open a outLine. 64 if (num < 0) { 65 if (!AudioSystem.isLineSupported(info)) { 66 System.out.println("TargetDataLine is not supported by default mixer."); 67 return false; 68 } 69 inLine = (TargetDataLine) AudioSystem.getLine(info); 70 } else { 71 Mixer mixer = AudioSystem.getMixer(mixers[num]); 72 if (!mixer.isLineSupported(info)) { 73 System.out.println("TargetDataLine is not supported by this mixer."); 74 return false; 75 } 76 inLine = (TargetDataLine) mixer.getLine(info); 77 } 78 inLine.open(format, bufferSize); 79 /*if (Math.abs(inLine.getBufferSize() - bufferSize) > 100) { 80 inLine.close(); 81 System.out.println("TargetDataLine does not support buffer size of "+bufferSize+" bytes!"); 82 return false; 83 }*/ 84 bufferSize = inLine.getBufferSize(); 85 /* 3/4 of buffer size ot wait */ 86 WAIT_MILLIS = (int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate()); 87 System.out.println("Buffer size: "+bufferSize+" bytes = " 88 +((int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate()))+" millis"); 89 return true; 90 } 91 92 private String available() { 93 int avail = inLine.available(); 94 int availMillis = (int) (avail / format.getFrameSize() * 1000 / format.getFrameRate()); 95 return "available "+avail+" bytes = "+availMillis+" millis"; 96 } 97 98 private boolean recordSound(int num) throws LineUnavailableException { 99 if (!openInputLine(num)) { 100 return false; 101 } 102 byte data[] = new byte[1000]; 103 try { 104 System.out.println("Got line: "+inLine); 105 System.out.println("Start recording" ); 106 inLine.start(); 107 System.out.print("Warm-up..."); 108 //System.out.print("Waiting 500 millis..."); 109 try { Thread.sleep(500); } catch (InterruptedException ie) {} 110 //System.out.println("done. "+available()); 111 //System.out.print("Reading all data..."); 112 int avail0 = inLine.available(); 113 if (avail0 == 0) { 114 System.out.println("Problem: TargetDataLine did not deliver any data!"); 115 System.out.println("Not a test failure, but serious failure nonetheless."); 116 } else { 117 while ((avail0 -= inLine.read(data, 0, Math.min(data.length, avail0))) > 0); 118 System.out.println("done. "+available()); 119 System.out.print("Waiting "+(WAIT_MILLIS)+" millis..."); 120 try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {} 121 int avail1 = inLine.available(); 122 System.out.println("done. "+available()); 123 124 System.out.print("Flushing..."); 125 inLine.flush(); 126 System.out.println("done. "+available()); 127 System.out.print("Waiting "+(WAIT_MILLIS)+" millis..."); 128 try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {} 129 int avail2 = inLine.available(); 130 System.out.println("done. "+available()); 131 if (avail2 > avail1) { 132 failed = true; 133 System.out.println("Failed: Flushing with native flush() should " 134 +"result in fewer bytes available."); 135 } 136 if (avail2 == 0) { 137 failed = true; 138 System.out.println("Failed: Recording after flush() did not work at all!"); 139 } 140 } 141 } finally { 142 System.out.print("Closing line...."); 143 inLine.close(); 144 System.out.println("done"); 145 } 146 return true; 147 } 148 149 public void runTests(int testRuns) { 150 if (mixers.length > 0) { 151 for (int num = -1; num < mixers.length; num++) { 152 try { 153 if (num<0) { 154 System.out.println("------Using default line...." ); 155 } else { 156 System.out.println("------Using line "+num+" from mixer "+mixers[num]+"..."); 157 } 158 for (int testRun = 0; testRun < testRuns; testRun++) { 159 if (testRuns>1) { 160 System.out.println("--Run "+(testRun+1)+"/"+testRuns+":"); 161 } 162 if (!recordSound(num)) { 163 break; 164 } 165 } 166 } catch (Exception ex) { 167 System.out.println("Caught " + ex ); 168 } 169 System.out.println("------------------------------------------------------"); 170 if (failed) { 171 break; 172 } 173 } 174 } else { 175 System.out.println("No mixers present. Cannot execute this test."); 176 } 177 } 178 179 180 public static void main(String[] args) throws Exception { 181 System.out.println("Test TargetDataLineFlush"); 182 System.out.println("This verifies that TargetDataLine.flush() actually"); 183 System.out.println("flushes the native buffers. This is done by"); 184 System.out.println("comparing a manual flush (i.e. just discarding"); 185 System.out.println("everything that is currently available in the TargetDataLine)"); 186 System.out.println("to a flushed line"); 187 TargetDataLineFlush app = new TargetDataLineFlush(); 188 int testRuns = 1; 189 if (args.length > 0) { 190 try { 191 testRuns = Integer.parseInt(args[0]); 192 } catch (NumberFormatException nfe) { 193 System.out.println("Usage: java TargetDataLineFlush [number of runs]"); 194 System.out.println("Parameters ignored."); 195 } 196 } 197 app.runTests(testRuns); 198 if (failed) { 199 throw new Exception("Test FAILED"); 200 } 201 // test always passes if it gets here 202 System.out.println("Test PASSED"); 203 } 204} 205