|
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 } |