25669bb667
Reviewed-by: kizune, serb, aivanov
284 lines
10 KiB
Java
284 lines
10 KiB
Java
/*
|
|
* 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 java.io.File;
|
|
import java.util.Random;
|
|
|
|
import javax.sound.sampled.AudioFormat;
|
|
import javax.sound.sampled.AudioInputStream;
|
|
import javax.sound.sampled.AudioSystem;
|
|
import javax.sound.sampled.DataLine;
|
|
import javax.sound.sampled.LineUnavailableException;
|
|
import javax.sound.sampled.Mixer;
|
|
import javax.sound.sampled.SourceDataLine;
|
|
|
|
/**
|
|
* @test
|
|
* @key sound
|
|
* @bug 4828556
|
|
* @summary stopping and starting sampled audio plays small chunk in infinite
|
|
* loop
|
|
*/
|
|
public class StopStart implements Runnable {
|
|
|
|
static int sampleRate = 8000;
|
|
static double frequency = 2000.0;
|
|
static double RAD = 2.0 * Math.PI;
|
|
static Random random = new Random();
|
|
|
|
static byte[] audioData = new byte[sampleRate/2];
|
|
static SourceDataLine source;
|
|
|
|
static boolean terminated = false;
|
|
|
|
static int buffersWritten = 0;
|
|
static long bytesWritten = 0;
|
|
static int buffersWrittenAfter5Seconds;
|
|
|
|
static AudioInputStream ais = null;
|
|
static AudioFormat audioFormat;
|
|
static String filename;
|
|
|
|
static int executedTests=0;
|
|
static int successfulTests = 0;
|
|
|
|
public static void constructAIS() throws Exception {
|
|
ais = AudioSystem.getAudioInputStream(new File(filename));
|
|
}
|
|
|
|
public static void doStartStopTest1() throws Exception {
|
|
System.out.println("TEST 1: play for 3 seconds, stop/start/stop/start/play for 3 seconds...");
|
|
source.start();
|
|
Thread.sleep(100);
|
|
bytesWritten = 0;
|
|
System.out.println("Waiting for 3 seconds...");
|
|
Thread.sleep(3000);
|
|
buffersWrittenAfter5Seconds = buffersWritten;
|
|
System.out.println("Buffers Written: "+buffersWritten);
|
|
System.out.println("stop()->start()->stop()->start()");
|
|
source.stop();
|
|
//System.out.println("start()");
|
|
source.start();
|
|
//System.out.println("stop()2 ----------------------------------------------------------");
|
|
source.stop();
|
|
//System.out.println("start()");
|
|
source.start();
|
|
System.out.println("Buffers Written: "+buffersWritten);
|
|
System.out.println("Waiting for 3 seconds...");
|
|
Thread.sleep(3000);
|
|
System.out.println("Buffers Written: "+buffersWritten);
|
|
if (buffersWritten >= ((buffersWrittenAfter5Seconds * 2) - ((buffersWrittenAfter5Seconds / 4)))) {
|
|
successfulTests++;
|
|
}
|
|
}
|
|
|
|
private static int nextWaitTime() {
|
|
int waitTime = random.nextInt(25);
|
|
waitTime*=waitTime;
|
|
if (waitTime<20) waitTime = 0;
|
|
return waitTime;
|
|
}
|
|
|
|
|
|
public static void doStartStopTest2() throws Exception {
|
|
System.out.println("TEST 2: start and stop 100 times with random wait in between");
|
|
int max=100;
|
|
for (int i=0; i<max; i++) {
|
|
System.out.println("Round "+i);
|
|
System.out.println("Start....");
|
|
source.start();
|
|
int waitTime = nextWaitTime();
|
|
System.out.println("Waiting for "+waitTime+"ms...");
|
|
if (waitTime>0) {
|
|
Thread.sleep(waitTime);
|
|
}
|
|
System.out.println("stop()");
|
|
source.stop();
|
|
waitTime = nextWaitTime();
|
|
System.out.println("Waiting for "+waitTime+"ms...");
|
|
if (waitTime>0) {
|
|
Thread.sleep(waitTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void doStartStopTest3() throws Exception {
|
|
System.out.println("TEST 3: start and stop 100 times with random wait only every 10 rounds ");
|
|
int max=100;
|
|
for (int i=0; i<max; i++) {
|
|
System.out.println("Round "+i);
|
|
System.out.println("Start....");
|
|
source.start();
|
|
if (i % 10 == 9) {
|
|
int waitTime = nextWaitTime();
|
|
System.out.println("Waiting for "+waitTime+"ms...");
|
|
if (waitTime>0) {
|
|
Thread.sleep(waitTime);
|
|
}
|
|
}
|
|
System.out.println("stop()");
|
|
source.stop();
|
|
if (i % 13 == 12) {
|
|
int waitTime = nextWaitTime();
|
|
System.out.println("Waiting for "+waitTime+"ms...");
|
|
if (waitTime>0) {
|
|
Thread.sleep(waitTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void runTest(int testNum) {
|
|
terminated = false;
|
|
Thread thread = null;
|
|
buffersWrittenAfter5Seconds = 0;
|
|
// make the tests reproduceable by always seeding with same value
|
|
random.setSeed(1);
|
|
try {
|
|
executedTests++;
|
|
thread = new Thread(new StopStart());
|
|
thread.start();
|
|
switch (testNum) {
|
|
case 1: doStartStopTest1(); break;
|
|
case 2: doStartStopTest2(); break;
|
|
case 3: doStartStopTest3(); break;
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
source.stop();
|
|
source.close();
|
|
if (thread!=null) {
|
|
terminated = true;
|
|
System.out.println("Waiting for thread to die...");
|
|
try {
|
|
thread.join();
|
|
} catch (InterruptedException ie) {
|
|
ie.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
filename = null;
|
|
if (args.length>0) {
|
|
File f = new File(args[0]);
|
|
if (f.exists()) {
|
|
filename = args[0];
|
|
System.out.println("Opening "+filename);
|
|
constructAIS();
|
|
audioFormat = ais.getFormat();
|
|
}
|
|
}
|
|
if (filename == null) {
|
|
audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true);
|
|
for (int i=0; i<audioData.length; i++) {
|
|
audioData[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
|
|
}
|
|
}
|
|
long startTime = System.currentTimeMillis();
|
|
Mixer.Info[] mixers = AudioSystem.getMixerInfo();
|
|
for (int i=0; i<mixers.length; i++) {
|
|
try {
|
|
Mixer mixer = AudioSystem.getMixer(mixers[i]);
|
|
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
|
|
String mixerName = mixer.getMixerInfo().getName();
|
|
try {
|
|
source = (SourceDataLine) mixer.getLine(info);
|
|
source.open(audioFormat);
|
|
} catch (IllegalArgumentException iae) {
|
|
System.out.println("Mixer "+mixerName+" does not provide a SourceDataLine.");
|
|
continue;
|
|
} catch (LineUnavailableException lue) {
|
|
System.out.println("Mixer "+mixerName+": no lines available.");
|
|
continue;
|
|
}
|
|
System.out.println("***** Testing on Mixer "+mixerName+":");
|
|
//runTest(2);
|
|
//runTest(3);
|
|
runTest(1);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
if (mixers.length==0) {
|
|
System.out.println("No mixers available!");
|
|
} else {
|
|
long duration = System.currentTimeMillis() - startTime;
|
|
|
|
System.out.println("Test took "+(duration/1000)+"s and "+(duration % 1000)+"ms.");
|
|
}
|
|
|
|
System.out.println("Exiting main()");
|
|
if (executedTests>0) {
|
|
if (successfulTests == 0) {
|
|
if (args.length == 0) {
|
|
throw new Exception("Test FAILED");
|
|
}
|
|
System.out.println("test FAILED.");
|
|
} else {
|
|
System.out.println("test successful.");
|
|
}
|
|
} else {
|
|
System.out.println("Could not execute any tests - are soundcards correctly installed?");
|
|
System.out.println("Test NOT FAILED.");
|
|
}
|
|
}
|
|
|
|
public void run() {
|
|
int len = audioData.length;
|
|
int offset = len;
|
|
System.out.println("Thread: started. Beginning audio i/o");
|
|
while (!terminated) {
|
|
try {
|
|
//if (!source.isActive()) {
|
|
// Thread.sleep(50);
|
|
//}
|
|
if (offset >= len) {
|
|
offset = 0;
|
|
if (ais!=null) {
|
|
do {
|
|
len = ais.read(audioData, 0, audioData.length);
|
|
if (len < 0) {
|
|
constructAIS();
|
|
}
|
|
} while (len < 0);
|
|
}
|
|
}
|
|
int toWrite = len - offset;
|
|
int written = source.write(audioData, offset, toWrite);
|
|
offset+=written;
|
|
bytesWritten += written;
|
|
buffersWritten = (int) (bytesWritten / audioData.length);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
terminated = true;
|
|
}
|
|
}
|
|
System.out.println("Thread: closing line");
|
|
source.stop();
|
|
source.close();
|
|
System.out.println("Thread finished");
|
|
}
|
|
}
|