jdk/test/javax/sound/sampled/Recording/TargetDataLineFlush.java
changeset 41905 e8e5df013c6e
equal deleted inserted replaced
41904:524d908e49ea 41905:e8e5df013c6e
       
     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 javax.sound.sampled.AudioFormat;
       
    25 import javax.sound.sampled.AudioSystem;
       
    26 import javax.sound.sampled.DataLine;
       
    27 import javax.sound.sampled.LineUnavailableException;
       
    28 import javax.sound.sampled.Mixer;
       
    29 import 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  */
       
    38 public 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 }