jdk/test/javax/sound/sampled/Recording/TargetDataLineFlush.java
changeset 41905 e8e5df013c6e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Recording/TargetDataLineFlush.java	Mon Oct 31 14:50:09 2016 +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");
+    }
+}