--- /dev/null 2016-10-24 21:41:34.000000000 +0300 +++ new/test/javax/sound/sampled/Recording/TargetDataLineFlush.java 2016-10-24 21:41:34.000000000 +0300 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.TargetDataLine; + +/** + * @test + * @bug 4836433 + * @summary Windows: TargetDataLine.flush() does not work. Since this test has + * some real-time variance, I disabled it by making it a manual test. + * @run main/manual TargetDataLineFlush + */ +public class TargetDataLineFlush { + TargetDataLine inLine; + int SAMPLE_RATE = 11025; + int BUFFER_MILLIS = 1000; + int WAIT_MILLIS; + int BITS = 16; + int CHANNELS = 2; + int bufferSize; + AudioFormat format; + Mixer.Info[] mixers; + static boolean failed = false; + + public TargetDataLineFlush() { + mixers = AudioSystem.getMixerInfo(); + } + + private void init() { + // float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian + format = new AudioFormat( (float) SAMPLE_RATE, BITS, CHANNELS, true, false); + bufferSize = SAMPLE_RATE * BUFFER_MILLIS / 1000 * format.getFrameSize(); + } + + boolean openInputLine(int num) throws LineUnavailableException { + init(); + DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // format is an AudioFormat object + // Obtain and open a outLine. + if (num < 0) { + if (!AudioSystem.isLineSupported(info)) { + System.out.println("TargetDataLine is not supported by default mixer."); + return false; + } + inLine = (TargetDataLine) AudioSystem.getLine(info); + } else { + Mixer mixer = AudioSystem.getMixer(mixers[num]); + if (!mixer.isLineSupported(info)) { + System.out.println("TargetDataLine is not supported by this mixer."); + return false; + } + inLine = (TargetDataLine) mixer.getLine(info); + } + inLine.open(format, bufferSize); + /*if (Math.abs(inLine.getBufferSize() - bufferSize) > 100) { + inLine.close(); + System.out.println("TargetDataLine does not support buffer size of "+bufferSize+" bytes!"); + return false; + }*/ + bufferSize = inLine.getBufferSize(); + /* 3/4 of buffer size ot wait */ + WAIT_MILLIS = (int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate()); + System.out.println("Buffer size: "+bufferSize+" bytes = " + +((int) (bufferSize / format.getFrameSize() * 750 / format.getFrameRate()))+" millis"); + return true; + } + + private String available() { + int avail = inLine.available(); + int availMillis = (int) (avail / format.getFrameSize() * 1000 / format.getFrameRate()); + return "available "+avail+" bytes = "+availMillis+" millis"; + } + + private boolean recordSound(int num) throws LineUnavailableException { + if (!openInputLine(num)) { + return false; + } + byte data[] = new byte[1000]; + try { + System.out.println("Got line: "+inLine); + System.out.println("Start recording" ); + inLine.start(); + System.out.print("Warm-up..."); + //System.out.print("Waiting 500 millis..."); + try { Thread.sleep(500); } catch (InterruptedException ie) {} + //System.out.println("done. "+available()); + //System.out.print("Reading all data..."); + int avail0 = inLine.available(); + if (avail0 == 0) { + System.out.println("Problem: TargetDataLine did not deliver any data!"); + System.out.println("Not a test failure, but serious failure nonetheless."); + } else { + while ((avail0 -= inLine.read(data, 0, Math.min(data.length, avail0))) > 0); + System.out.println("done. "+available()); + System.out.print("Waiting "+(WAIT_MILLIS)+" millis..."); + try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {} + int avail1 = inLine.available(); + System.out.println("done. "+available()); + + System.out.print("Flushing..."); + inLine.flush(); + System.out.println("done. "+available()); + System.out.print("Waiting "+(WAIT_MILLIS)+" millis..."); + try { Thread.sleep(WAIT_MILLIS); } catch (InterruptedException ie) {} + int avail2 = inLine.available(); + System.out.println("done. "+available()); + if (avail2 > avail1) { + failed = true; + System.out.println("Failed: Flushing with native flush() should " + +"result in fewer bytes available."); + } + if (avail2 == 0) { + failed = true; + System.out.println("Failed: Recording after flush() did not work at all!"); + } + } + } finally { + System.out.print("Closing line...."); + inLine.close(); + System.out.println("done"); + } + return true; + } + + public void runTests(int testRuns) { + if (mixers.length > 0) { + for (int num = -1; num < mixers.length; num++) { + try { + if (num<0) { + System.out.println("------Using default line...." ); + } else { + System.out.println("------Using line "+num+" from mixer "+mixers[num]+"..."); + } + for (int testRun = 0; testRun < testRuns; testRun++) { + if (testRuns>1) { + System.out.println("--Run "+(testRun+1)+"/"+testRuns+":"); + } + if (!recordSound(num)) { + break; + } + } + } catch (Exception ex) { + System.out.println("Caught " + ex ); + } + System.out.println("------------------------------------------------------"); + if (failed) { + break; + } + } + } else { + System.out.println("No mixers present. Cannot execute this test."); + } + } + + + public static void main(String[] args) throws Exception { + System.out.println("Test TargetDataLineFlush"); + System.out.println("This verifies that TargetDataLine.flush() actually"); + System.out.println("flushes the native buffers. This is done by"); + System.out.println("comparing a manual flush (i.e. just discarding"); + System.out.println("everything that is currently available in the TargetDataLine)"); + System.out.println("to a flushed line"); + TargetDataLineFlush app = new TargetDataLineFlush(); + int testRuns = 1; + if (args.length > 0) { + try { + testRuns = Integer.parseInt(args[0]); + } catch (NumberFormatException nfe) { + System.out.println("Usage: java TargetDataLineFlush [number of runs]"); + System.out.println("Parameters ignored."); + } + } + app.runTests(testRuns); + if (failed) { + throw new Exception("Test FAILED"); + } + // test always passes if it gets here + System.out.println("Test PASSED"); + } +}