--- old/test/ProblemList.txt 2016-10-24 21:40:20.000000000 +0300 +++ new/test/ProblemList.txt 2016-10-24 21:40:20.000000000 +0300 @@ -166,7 +166,7 @@ java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all -java/net/httpclient/SplitResponse.java 8157533 generic-all +java/net/httpclient/SplitResponse.java 8157533 generic-all java/net/httpclient/http2/BasicTest.java 8157408 linux-all java/net/httpclient/http2/ErrorTest.java 8158127 solaris-all,windows-all @@ -223,6 +223,13 @@ ############################################################################ # jdk_sound +javax/sound/sampled/DirectAudio/bug6372428.java 8055097 generic-all +javax/sound/sampled/Clip/bug5070081.java 8055097 generic-all +javax/sound/sampled/DataLine/LongFramePosition.java 8055097 generic-all + +javax/sound/sampled/Clip/Drain/ClipDrain.java 7062792 generic-all + +javax/sound/sampled/Mixers/DisabledAssertionCrash.java 7067310 generic-all ############################################################################ --- /dev/null 2016-10-24 21:40:21.000000000 +0300 +++ new/test/javax/sound/midi/Devices/ClosedReceiver.java 2016-10-24 21:40:21.000000000 +0300 @@ -0,0 +1,184 @@ +/* + * 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.midi.InvalidMidiDataException; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4616517 + * @summary Receiver.send() does not work properly + */ +public class ClosedReceiver { + + public static void main(String[] args) throws Exception { + out("#4616517: Receiver.send() does not work properly"); + if (!isMidiInstalled()) { + out("Soundcard does not exist or sound drivers not installed!"); + out("This test requires sound drivers for execution."); + return; + } + + boolean passed = true; + + passed &= testReceiverSend(); + passed &= testClosedReceivers(); + if (passed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + + /** + * Execute Receiver.send() and expect that there is no exception. + */ + private static boolean testReceiverSend() { + boolean result = true; + + Receiver receiver; + ShortMessage shMsg = new ShortMessage(); + + try { + receiver = MidiSystem.getReceiver(); + shMsg.setMessage(ShortMessage.NOTE_ON, 0,60, 93); + try { + receiver.send( shMsg, -1 ); + } catch(IllegalStateException ilEx) { + ilEx.printStackTrace(System.out); + out("IllegalStateException was thrown incorrectly!"); + result = false; + } + receiver.close(); + } catch(MidiUnavailableException e) { + out("Midi unavailable, cannot test."); + } catch(InvalidMidiDataException ine) { + out("InvalidMidiDataException, cannot test."); + } + return result; + } + + private static boolean testClosedReceivers() { + boolean result = true; + Receiver receiver; + Synthesizer synt = null; + + // test Synthesizer's Receiver + try { + synt = MidiSystem.getSynthesizer(); + synt.open(); + } catch(MidiUnavailableException e) { + out("Midi unavailable, cannot test."); + return result; + } + try { + receiver = synt.getReceiver(); + } catch (MidiUnavailableException e) { + out("unable to get Receiver from synthesizer, cannot test."); + return result; + } + result &= testClosedReceiver(receiver); + synt.close(); + + // test all MidiDevices' Receivers + + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + if (device.getMaxReceivers() != 0) { + receiver = device.getReceiver(); + result &= testClosedReceiver(receiver); + } + } catch (Exception e) { + out(e); + out("cannot test."); + return result; + } + } + return result; + } + + /** + * Execute send() on a closed Receivers and expect IllegalStateException. + */ + private static boolean testClosedReceiver(Receiver receiver) { + boolean result = true; + out("testing Receiver: " + receiver); + ShortMessage shMsg = new ShortMessage(); + try { + shMsg.setMessage(ShortMessage.NOTE_ON, 0,60, 93); + } catch(InvalidMidiDataException e) { + out(e); + out("unable to construct ShortMessage, cannot test."); + return result; + } + + // begin of test + receiver.close(); + try { + receiver.send( shMsg, -1 ); + out("IllegalStateException was not thrown " + + "on Receiver.send()!"); + result = false; + } catch(IllegalStateException e) { + out("IllegalStateException was thrown. Ok."); + } + return result; + } + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } + + /** + * Returns true if at least one MIDI (port) device is correctly installed on + * the system. + */ + private static boolean isMidiInstalled() { + boolean result = false; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + result = !(device instanceof Sequencer) + && !(device instanceof Synthesizer); + } catch (Exception e1) { + System.err.println(e1); + } + if (result) + break; + } + return result; + } +} --- /dev/null 2016-10-24 21:40:21.000000000 +0300 +++ new/test/javax/sound/midi/Devices/IOLoop.java 2016-10-24 21:40:21.000000000 +0300 @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2002, 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.ByteArrayOutputStream; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Receiver; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.SysexMessage; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4782924 + * @bug 4812168 + * @bug 4356787 + * @summary MIDI i/o. This is an interactive test! Start it and follow the + * instructions. + * @run main/manual IOLoop + */ +public class IOLoop { + private static final int LONG_SYSEX_LENGTH = 2000; + + private static Receiver receiver; + private static Transmitter transmitter; + private static MidiMessage receivedMessage; + private static ByteArrayOutputStream baos; + private static int expectedBytes; + private static int receivedBytes; + private static Object lock = new Object(); + private static long lastTimestamp; + + public static void main(String[] args) throws Exception { + ShortMessage sMsg = new ShortMessage(); + SysexMessage syMsg = new SysexMessage(); + boolean isTestPassed = true; + boolean sysExTestPassed = true; + boolean isTestExecuted = true; + + out("To run this test successfully, you need to have attached"); + out(" your MIDI out port with the MIDI in port."); + + MidiDevice inDev = null; + MidiDevice outDev = null; + + // setup + try { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + + int devNum = Integer.decode(args[0]).intValue(); + out("-> opening Transmitter from "+infos[devNum]); + inDev = MidiSystem.getMidiDevice(infos[devNum]); + inDev.open(); + transmitter = inDev.getTransmitter(); + Receiver testReceiver = new TestReceiver(); + transmitter.setReceiver(testReceiver); + + devNum = Integer.decode(args[1]).intValue(); + out("-> opening Receiver from "+infos[devNum]); + outDev = MidiSystem.getMidiDevice(infos[devNum]); + outDev.open(); + receiver = outDev.getReceiver(); + + } catch (Exception e) { + System.out.println(e); + System.out.println("Cannot test!"); + return; + } + + // test + sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 27, 100); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_OFF | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_OFF | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_ON | 4, 27, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_ON | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.NOTE_ON | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.POLY_PRESSURE | 11, 98, 99); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.POLY_PRESSURE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.POLY_PRESSURE | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 13, 1, 63); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTROL_CHANGE | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 2, 120, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PROGRAM_CHANGE | 15, 127, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 6, 30, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CHANNEL_PRESSURE | 15, 127, 0); + isTestPassed &= testMessage(sMsg); + + sMsg.setMessage(ShortMessage.PITCH_BEND | 6, 56, 4); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PITCH_BEND | 0, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.PITCH_BEND | 15, 127, 127); + isTestPassed &= testMessage(sMsg); + + sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.MIDI_TIME_CODE, 127, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 1, 77); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_POSITION_POINTER, 127, 127); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_SELECT, 51, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_SELECT, 0, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SONG_SELECT, 127, 0); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.TUNE_REQUEST); + isTestPassed &= testMessage(sMsg); + + sMsg.setMessage(ShortMessage.TIMING_CLOCK); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.START); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.CONTINUE); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.STOP); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.ACTIVE_SENSING); + isTestPassed &= testMessage(sMsg); + sMsg.setMessage(ShortMessage.SYSTEM_RESET); + isTestPassed &= testMessage(sMsg); + + syMsg.setMessage(new byte[]{(byte) 0xF0, (byte) 0xF7}, 2); + isTestPassed &= testMessage(syMsg); + syMsg.setMessage(new byte[]{(byte) 0xF0, 0x01, (byte) 0xF7}, 3); + isTestPassed &= testMessage(syMsg); + syMsg.setMessage(new byte[]{(byte) 0xF0, 0x02, 0x03, (byte) 0xF7}, 4); + isTestPassed &= testMessage(syMsg); + syMsg.setMessage(new byte[]{(byte) 0xF0, 0x04, 0x05, 0x06, (byte) 0xF7}, 5); + isTestPassed &= testMessage(syMsg); + + if (isTestPassed) { + byte[] sysexArray = new byte[LONG_SYSEX_LENGTH]; + sysexArray[0] = (byte) 0xF0; + for (int i = 1; i < sysexArray.length; i++) { + sysexArray[i] = (byte) (i % 0x80); + } +// syMsg.setMessage(new byte[]{(byte) 0xF7, (byte) ShortMessage.START}, 2); +// sMsg.setMessage(ShortMessage.START); +// isTestPassed &= testMessage(syMsg, sMsg, DEFAULT_SLEEP_INTERVALL); + for (int trial = sysexArray.length; trial > 4; trial -= 1234) { + sleep(500); + sysexArray[trial - 1] = (byte) 0xF7; + syMsg.setMessage(sysexArray, trial); + sysExTestPassed &= testMessage(syMsg); + break; + } + } + + // cleanup + receiver.close(); + transmitter.close(); + inDev.close(); + outDev.close(); + + if (isTestExecuted) { + if (isTestPassed && sysExTestPassed) { + + out("Test PASSED."); + } else { + if (isTestPassed + && !sysExTestPassed + && (System.getProperty("os.name").startsWith("Windows"))) { + out("Some Windows MIDI i/o drivers have a problem with larger "); + out("sys ex messages. The failing sys ex cases are OK, therefore."); + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + } else { + out("Test NOT FAILED"); + } + } + + private static boolean testMessage(MidiMessage message) { + receivedMessage = null; + baos = new ByteArrayOutputStream(); + expectedBytes = message.getLength(); + receivedBytes = 0; + System.out.print("Sending message " + getMessageString(message.getMessage())+"..."); + receiver.send(message, -1); + /* sending 3 bytes can roughly be done in 1 millisecond, + * so this estimate waits at max 3 times longer than the message takes, + * plus a little offset to allow the MIDI subsystem some processing time + */ + int offset = 300; // standard offset 100 millis + if (message instanceof SysexMessage) { + // add a little processing time to sysex messages + offset += 1000; + } + if (receivedBytes < expectedBytes) { + sleep(expectedBytes + offset); + } + boolean equal; + byte[] data = baos.toByteArray(); + if (data.length > 0) { + equal = messagesEqual(message.getMessage(), data); + } else { + equal = messagesEqual(message, receivedMessage); + if (receivedMessage != null) { + data = receivedMessage.getMessage(); + } else { + data = null; + } + } + if (!equal) { + if ((message.getStatus() & 0xF0) == ShortMessage.PITCH_BEND) { + out("NOT failed (may expose a bug in ALSA)"); + equal = true; + sleep(100); + } + if ((message.getStatus() == 0xF6) && (message.getLength() == 1)) { + out("NOT failed (may expose an issue on Solaris)"); + equal = true; + sleep(100); + } + else if ((message.getStatus()) == 0xF0 && message.getLength() < 4) { + out("NOT failed (not a correct sys ex message)"); + equal = true; + sleep(200); + } else { + out("FAILED:"); + out(" received as " + getMessageString(data)); + } + } else { + System.out.println("OK"); + } + return equal; + } + + private static void sleep(int milliseconds) { + synchronized(lock) { + try { + lock.wait(milliseconds); + } catch (InterruptedException e) { + } + } + } + + private static String getMessageString(byte[] data) { + String s; + if (data == null) { + s = ""; + } else if (data.length == 0) { + s = "0-sized array"; + } else { + int status = data[0] & 0xFF; + if (data.length <= 3) { + if (status < 240) { + s = "command 0x" + Integer.toHexString(status & 0xF0) + " channel " + (status & 0x0F); + } else { + s = "status 0x" + Integer.toHexString(status); + } + if (data.length > 1) { + s += " data 0x" + Integer.toHexString(data[1] & 0xFF); + if (data.length > 2) { + s += " 0x" + Integer.toHexString(data[2] & 0xFF); + } + } + } else { + s = "status " + Integer.toHexString(status)+" and length "+data.length+" bytes"; + } + } + return s; + } + + private static boolean messagesEqual(MidiMessage m1, MidiMessage m2) { + if (m1 == null || m2 == null) { + return false; + } + if (m1.getLength() != m2.getLength()) { + return false; + } + byte[] array1 = m1.getMessage(); + byte[] array2 = m2.getMessage(); + return messagesEqual(array1, array2); + } + + private static boolean messagesEqual(byte[] a1, byte[] a2) { + if (a1.length != a2.length) return false; + for (int i = 0; i < a1.length; i++) { + if (a1[i] != a2[i]) { + return false; + } + } + return true; + } + + private static void out(String s) { + System.out.println(s); + System.out.flush(); + } + + private static String canIn(MidiDevice dev) { + if (dev.getMaxTransmitters() != 0) { + return "IN "; + } + return " "; + } + + private static String canOut(MidiDevice dev) { + if (dev.getMaxReceivers() != 0) { + return "OUT "; + } + return " "; + } + + + private static void checkTimestamp(long timestamp) { + // out("checking timestamp..."); + if (timestamp < 1) { + out("timestamp 0 or negative!"); + } + if (timestamp < lastTimestamp) { + out("timestamp not progressive!"); + } + lastTimestamp = timestamp; + } + + private static class TestReceiver implements Receiver { + public void send(MidiMessage message, long timestamp) { + //System.out.print(""+message.getLength()+".."); + checkTimestamp(timestamp); + try { + receivedMessage = message; + if (message.getStatus() == 0xF0 + || (message.getLength() > 3 && message.getStatus() != 0xF7)) { + // sys ex message + byte[] data = message.getMessage(); + baos.write(data); + receivedBytes += data.length; + } + else if (message.getStatus() == 0xF7) { + // sys ex cont'd message + byte[] data = message.getMessage(); + // ignore the prepended 0xF7 + baos.write(data, 1, data.length-1); + receivedBytes += (data.length - 1); + } else { + receivedBytes += message.getLength(); + } + if (receivedBytes >= expectedBytes) { + synchronized(lock) { + lock.notify(); + } + } + System.out.print(""+receivedBytes+".."); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void close() { + } + } +} --- /dev/null 2016-10-24 21:40:22.000000000 +0300 +++ new/test/javax/sound/midi/Devices/MidiDeviceGetReceivers.java 2016-10-24 21:40:22.000000000 +0300 @@ -0,0 +1,187 @@ +/* + * 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.util.List; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4931387 + * @summary Add methods to MidiDevice to get list of Transmitters and Receivers + */ +public class MidiDeviceGetReceivers { + + private static boolean executed = false; + private static boolean failed = false; + + public static void main(String[] args) throws Exception { + out("unit test 4931387: Add methods to MidiDevice to get list of Transmitters and Receivers"); + doAllTests(); + if (executed) { + if (failed) throw new Exception("Test FAILED!"); + out("Test PASSED."); + } else { + out("Test NOT failed."); + } + } + + private static void doAllTests() { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < infos.length; i++) { + MidiDevice device = null; + try { + device = MidiSystem.getMidiDevice(infos[i]); + doTest(device); + } catch (MidiUnavailableException e) { + out("Exception occured when retrieving device "+infos[i]+": "+e); + } + } + if (infos.length == 0) { + out("No MIDI devices exist or sound drivers not installed!"); + } + } + + private static boolean containsReceiver(MidiDevice dev, Receiver rec) { + List recvs = dev.getReceivers(); + return recvs.contains(rec); + } + + private static boolean containsTransmitter(MidiDevice dev, Transmitter tra) { + List tras = dev.getTransmitters(); + return tras.contains(tra); + } + + private static void doTest(MidiDevice device) { + boolean thisFailed = false; + out1("Testing: " + device+"..."); + try { + device.open(); + } catch (Exception e) { + out2("device.open threw exception: "+e); + out2("cannot test this device."); + return; + } + if (device.getMaxReceivers() != 0) { + // device offers receivers + try { + List origList = device.getReceivers(); + Receiver rec = device.getReceiver(); + if (!containsReceiver(device, rec)) { + out2("Getting a receiver did not add it to device list!"); + thisFailed = true; + } + if (origList.contains(rec)) { + out2("Original unmodifiable list was modified by adding a receiver!"); + thisFailed = true; + } + rec.close(); + if (containsReceiver(device, rec)) { + out2("Closing a receiver did not remove it from device list!"); + thisFailed = true; + } + // add a new receiver so that the device.close will really test + // that the receiver is removed + rec = device.getReceiver(); + if (!containsReceiver(device, rec)) { + out2("Getting a receiver again did not add it to device list!"); + thisFailed = true; + } + } catch (MidiUnavailableException e) { + out2("Exception on getting Receiver: " + e); + } + } + if (device.getMaxTransmitters() != 0) { + // device offers transmitters + try { + List origList = device.getTransmitters(); + Transmitter tra = device.getTransmitter(); + if (!containsTransmitter(device, tra)) { + out2("Getting a transmitter did not add it to device list!"); + thisFailed = true; + } + if (origList.contains(tra)) { + out2("Original unmodifiable list was modified by adding a transmitter!"); + thisFailed = true; + } + tra.close(); + if (containsTransmitter(device, tra)) { + out2("Closing a transmitter did not remove it from device list!"); + thisFailed = true; + } + tra = device.getTransmitter(); + if (!containsTransmitter(device, tra)) { + out2("Getting a transmitter again did not add it to device list!"); + thisFailed = true; + } + } catch (MidiUnavailableException e) { + out("Exception on getting Transmitter: " + e); + } + } + try { + device.close(); + if (device.getTransmitters().size() > 0) { + out2(" Device still has transmitters after close() was called!"); + thisFailed = true; + } + if (device.getReceivers().size() > 0) { + out2(" Device still has receivers after close() was called!"); + thisFailed = true; + } + } catch (Exception e) { + out2("device.close threw exception: "+e); + } + if (!thisFailed) { + out("OK"); + } else { + failed = true; + } + executed = true; + } + + static boolean lfMissing = false; + + private static void out(String message) { + lfMissing = true; + System.out.println(message); + } + + /* don't print LF at end */ + private static void out1(String message) { + System.out.print(message); + lfMissing = true; + } + + /* print at a new line, indented */ + private static void out2(String message) { + if (lfMissing) { + System.out.println(); + lfMissing = false; + } + System.out.println(" "+message); + } +} --- /dev/null 2016-10-24 21:40:23.000000000 +0300 +++ new/test/javax/sound/midi/Devices/MidiIO.java 2016-10-24 21:40:23.000000000 +0300 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2002, 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.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; + +/** + * @test + * @bug 4356787 + * @summary MIDI device I/O is not working + */ +public class MidiIO { + + public static void main(String[] args) throws Exception { + out("4356787: MIDI device I/O is not working (windows)"); + + if (System.getProperty("os.name").startsWith("Windows")) { + boolean forInput=true; + boolean forOutput=true; + int outOnlyCount=0; + int inOnlyCount=0; + out(" available MIDI devices:"); + MidiDevice.Info[] aInfos = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < aInfos.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(aInfos[i]); + boolean bAllowsInput = (device.getMaxTransmitters() != 0); + boolean bAllowsOutput = (device.getMaxReceivers() != 0); + if (bAllowsInput && !bAllowsOutput) { + inOnlyCount++; + } + if (!bAllowsInput && bAllowsOutput) { + outOnlyCount++; + } + if ((bAllowsInput && forInput) || (bAllowsOutput && forOutput)) { + out(""+i+" " + +(bAllowsInput?"IN ":" ") + +(bAllowsOutput?"OUT ":" ") + +aInfos[i].getName()+", " + +aInfos[i].getVendor()+", " + +aInfos[i].getVersion()+", " + +aInfos[i].getDescription()); + } + } + catch (MidiUnavailableException e) { + // device is obviously not available... + } + } + if (aInfos.length == 0) { + out("No devices available. Test should be run on systems with MIDI drivers installed."); + } else { + if (outOnlyCount>1) { + if (inOnlyCount==0) { + //throw new Exception("No input devices! test fails."); + out("System provides out devices, but no input devices. This means either"); + out("a bug in Java Sound, or the drivers are not set up correctly."); + } + out("Test passed."); + } else { + out("no MIDI I/O installed. Test should be run on systems with MIDI drivers installed."); + } + } + } else { + out(" -- not on Windows. Test doesn't apply."); + } + } + + static void out(String s) { + System.out.println(s); System.out.flush(); + } +} --- /dev/null 2016-10-24 21:40:24.000000000 +0300 +++ new/test/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java 2016-10-24 21:40:23.000000000 +0300 @@ -0,0 +1,135 @@ +/* + * 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.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4903786 + * @summary MIDI OUT does not implement getMicrosecondPosition() consistently + */ +public class MidiOutGetMicrosecondPositionBug { + static int successfulTests = 0; + + private static void testDevice(MidiDevice device) throws Exception { + boolean timestampsAvailable = false; + boolean timestampPrecisionOk = false; + try { + // expected behaviour if not opened? + device.open(); + /* First, we're testing if timestamps are provided at all. + Returning -1 (unsupported), while allowed by the API + specification, is not sufficient to pass this test. */ + long timestamp = device.getMicrosecondPosition(); + timestampsAvailable = (timestamp != -1); + + /* Then, we're testing the precision. Note that the system time + is measured in milliseconds, while the device time is measured + in microseconds. */ + + long systemTime1 = System.currentTimeMillis(); + long deviceTime1 = device.getMicrosecondPosition(); + // rest for 5 seconds + Thread.sleep(5000); + long systemTime2 = System.currentTimeMillis(); + long deviceTime2 = device.getMicrosecondPosition(); + + // now both period measurements are calculated in milliseconds. + long systemDuration = systemTime2 - systemTime1; + long deviceDuration = (deviceTime2 - deviceTime1) / 1000; + long delta = Math.abs(systemDuration - deviceDuration); + // a deviation of 0.5 seconds (= 500 ms) is allowed. + timestampPrecisionOk = (delta <= 500); + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - " + t.toString()); + return; + } finally { + device.close(); + } + if (! timestampsAvailable) { + throw new Exception("timestamps are not supported"); + } + if (! timestampPrecisionOk) { + throw new Exception("device timer not precise enough"); + } + successfulTests++; + } + + private static void doAll() throws Exception { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int i=0; i < infos.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + if ((! (device instanceof Sequencer)) && + (! (device instanceof Synthesizer)) && + (device.getMaxReceivers() > 0 || device.getMaxReceivers() == -1)) { + + System.out.println("--------------"); + System.out.println("Testing MIDI device: " + infos[i]); + testDevice(device); + } + if (infos.length==0) { + System.out.println("No MIDI devices available!"); + } + } + } + + public static void main(String[] args) throws Exception { + if (!isMidiInstalled()) { + return; + } + doAll(); + if (successfulTests==0) { + System.out.println("Could not execute any of the tests. Test NOT failed."); + } else { + System.out.println("Test PASSED."); + } + } + + /** + * Returns true if at least one MIDI (port) device is correctly installed on + * the system. + */ + public static boolean isMidiInstalled() { + boolean result = false; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer); + } catch (Exception e1) { + System.err.println(e1); + } + if (result) + break; + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:40:24.000000000 +0300 +++ new/test/javax/sound/midi/Devices/OpenClose.java 2016-10-24 21:40:24.000000000 +0300 @@ -0,0 +1,611 @@ +/* + * 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.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4616517 + * @summary Receiver.send() does not work properly. Tests open/close behaviour + * of MidiDevices. For this test, it is essential that the MidiDevice + * picked from the list of devices (MidiSystem.getMidiDeviceInfo()) is + * the same as the one used by + * MidiSystem.getReceiver()/getTransmitter(). To achieve this, default + * provider properties for Receivers/Transmitters are used. + */ +public class OpenClose { + + private static boolean isTestExecuted; + private static boolean isTestPassed; + + public static void main(String[] args) throws Exception { + boolean failed = false; + out("#4616517: Receiver.send() does not work properly"); + if (!isMidiInstalled()) { + out("Soundcard does not exist or sound drivers not installed!"); + out("This test requires sound drivers for execution."); + return; + } + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + MidiDevice outDevice = null; + MidiDevice inDevice = null; + for (int i = 0; i < infos.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + if (! (device instanceof Synthesizer) && + ! (device instanceof Sequencer)) { + if (device.getMaxReceivers() != 0) { + outDevice = device; + } + if (device.getMaxTransmitters() != 0) { + inDevice = device; + } + } + } + if (outDevice != null) { + // set the default provider properties + System.setProperty(Receiver.class.getName(), + "#" + outDevice.getDeviceInfo().getName()); + } + if (inDevice != null) { + System.setProperty(Transmitter.class.getName(), + "#" + inDevice.getDeviceInfo().getName()); + } + out("Using MIDI OUT Device: " + outDevice); + out("Using MIDI IN Device: " + inDevice); + + isTestExecuted = false; + if (outDevice != null) { + isTestExecuted = true; + TestHelper testHelper = new ReceiverTestHelper(outDevice); + try { + doTest("Receiver", testHelper); + failed |= testHelper.hasFailed(); + } catch (Exception e) { + out("Exception occured, cannot test!"); + isTestExecuted = false; + } + } + + if (inDevice != null) { + isTestExecuted = true; + TestHelper testHelper = new TransmitterTestHelper(inDevice); + try { + doTest("Transmitter", testHelper); + failed |= testHelper.hasFailed(); + } catch (Exception e) { + out("Exception occured, cannot test!"); + isTestExecuted = false; + } + } + + isTestPassed = ! failed; + + if (isTestExecuted) { + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } else { + out("Test NOT FAILED"); + } + } + + private static void doTest(String type, + TestHelper testHelper) throws Exception { + /* Case 1: + - MidiDevice.open() + - MidiDevice.close() + */ + out("checking " + type + " case 1..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 2a: + - MidiSystem.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 2a..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 2b: + - MidiDevice.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 2b..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 3a: + - MidiSystem.get[Receiver|Transmitter]() + - MidiDevice.open() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 3a..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 3b: + - MidiDevice.get[Receiver|Transmitter]() + - MidiDevice.open() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 3b..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 4a: + - MidiSystem.get[Receiver|Transmitter]() + - MidiDevice.open() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 4a..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 4b: + - MidiDevice.get[Receiver|Transmitter]() + - MidiDevice.open() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 4b..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 5a: + - MidiDevice.open() + - MidiSystem.get[Receiver|Transmitter]() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 5a..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 5b: + - MidiDevice.open() + - MidiDevice.get[Receiver|Transmitter]() + - MidiDevice.close() + - [Receiver|Transmitter].close() + */ + out("checking " + type + " case 5b..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 6a: + - MidiDevice.open() + - MidiSystem.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 6a..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 6b: + - MidiDevice.open() + - MidiDevice.get[Receiver|Transmitter]() + - [Receiver|Transmitter].close() + - MidiDevice.close() + */ + out("checking " + type + " case 6b..."); + testHelper.checkClosed(); + + testHelper.openDevice(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 7: + - MidiSystem.get[Receiver|Transmitter]() // 1 + - MidiDevice.get[Receiver|Transmitter]() // 2 + - [Receiver|Transmitter].close() // 2 + - [Receiver|Transmitter].close() // 1 + */ + out("checking " + type + " case 7..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 8: + - MidiSystem.get[Receiver|Transmitter]() // 1 + - MidiDevice.get[Receiver|Transmitter]() // 2 + - [Receiver|Transmitter].close() // 1 + - [Receiver|Transmitter].close() // 2 + */ + out("checking " + type + " case 8..."); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.fetchObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 9: + - MidiDevice.get[Receiver|Transmitter]() // 2 + - MidiSystem.get[Receiver|Transmitter]() // 1 + - [Receiver|Transmitter].close() // 2 + - [Receiver|Transmitter].close() // 1 + */ + out("checking " + type + " case 9..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectDevice(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case 10: + - MidiDevice.get[Receiver|Transmitter]() // 2 + - MidiSystem.get[Receiver|Transmitter]() // 1 + - [Receiver|Transmitter].close() // 1 + - [Receiver|Transmitter].close() // 2 + */ + out("checking " + type + " case 10..."); + testHelper.checkClosed(); + + testHelper.fetchObjectDevice(); + testHelper.checkClosed(); + + testHelper.fetchObjectMidiSystem(); + testHelper.checkOpen(); + + testHelper.closeObjectMidiSystem(); + testHelper.checkClosed(); + + testHelper.closeObjectDevice(); + testHelper.checkClosed(); + + out("...OK"); + + /* Case N - 1: + - 10 x MidiSystem.get[Receiver|Transmitter]() + - 10 x [Receiver|Transmitter].close() + */ + out("checking " + type + " case N - 1..."); + TestHelper[] testHelpers = new TestHelper[10]; + for (int i = 0; i < 10; i++) { + testHelpers[i] = (TestHelper) testHelper.clone(); + } + testHelper.checkClosed(); + + for (int i = 0; i < 10; i++) { + testHelpers[i].fetchObjectMidiSystem(); + testHelper.checkOpen(); + } + + + for (int i = 0; i < 9; i++) { + testHelpers[i].closeObjectMidiSystem(); + testHelper.checkOpen(); + } + + testHelpers[9].closeObjectMidiSystem(); + testHelper.checkClosed(); + + out("...OK"); + } + + private static void out(String message) { + System.out.println(message); + } + + private static abstract class TestHelper implements Cloneable { + private MidiDevice device; + private boolean failed; + + protected TestHelper(MidiDevice device) { + this.device = device; + failed = false; + } + + protected MidiDevice getDevice() { + return device; + } + + public boolean hasFailed() { + return failed; + } + + public void openDevice() throws MidiUnavailableException { + getDevice().open(); + } + + public void closeDevice() { + getDevice().close(); + } + + public void checkOpen(){ + checkOpen(getDevice(), true); + } + + public void checkClosed(){ + checkOpen(getDevice(), false); + } + + private void checkOpen(MidiDevice device, boolean desiredState) { + if (device.isOpen() != desiredState) { + out("device should be " + + getStateString(desiredState) + ", but isn't!"); + failed = true; + } + } + + + private String getStateString(boolean state) { + return state ? "open" : "closed"; + } + + + public abstract void fetchObjectMidiSystem() throws MidiUnavailableException; + public abstract void fetchObjectDevice() throws MidiUnavailableException; + public abstract void closeObjectMidiSystem(); + public abstract void closeObjectDevice(); + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + } + + private static class ReceiverTestHelper extends TestHelper { + private Receiver receiverMidiSystem; + private Receiver receiverDevice; + + public ReceiverTestHelper(MidiDevice device) { + super(device); + } + + public void fetchObjectMidiSystem() throws MidiUnavailableException { + receiverMidiSystem = MidiSystem.getReceiver(); + } + + + public void fetchObjectDevice() throws MidiUnavailableException { + receiverDevice = getDevice().getReceiver(); + } + + + public void closeObjectMidiSystem() { + receiverMidiSystem.close(); + } + + + public void closeObjectDevice() { + receiverDevice.close(); + } + } + + private static class TransmitterTestHelper extends TestHelper { + private Transmitter transmitterMidiSystem; + private Transmitter transmitterDevice; + + public TransmitterTestHelper(MidiDevice device) { + super(device); + } + + public void fetchObjectMidiSystem() throws MidiUnavailableException { + transmitterMidiSystem = MidiSystem.getTransmitter(); + } + + + public void fetchObjectDevice() throws MidiUnavailableException { + transmitterDevice = getDevice().getTransmitter(); + } + + + public void closeObjectMidiSystem() { + transmitterMidiSystem.close(); + } + + + public void closeObjectDevice() { + transmitterDevice.close(); + } + } + + /** + * Returns true if at least one MIDI (port) device is correctly installed on + * the system. + */ + public static boolean isMidiInstalled() { + boolean result = false; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + try { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + result = ! (device instanceof Sequencer) && ! (device instanceof Synthesizer); + } catch (Exception e1) { + System.err.println(e1); + } + if (result) + break; + } + return result; + } +} --- /dev/null 2016-10-24 21:40:25.000000000 +0300 +++ new/test/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java 2016-10-24 21:40:25.000000000 +0300 @@ -0,0 +1,113 @@ +/* + * 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.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 4616517 + * @summary Receiver.send() does not work properly + */ +public class ReceiverTransmitterAvailable { + + private static boolean isTestExecuted; + private static boolean isTestPassed; + + public static void main(String[] args) throws Exception { + out("#4616517: Receiver.send() does not work properly"); + doAllTests(); + if (isTestExecuted) { + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } else { + out("Test NOT FAILED"); + } + } + + private static void doAllTests() { + boolean problemOccured = false; + boolean succeeded = true; + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < infos.length; i++) { + MidiDevice device = null; + try { + device = MidiSystem.getMidiDevice(infos[i]); + succeeded &= doTest(device); + } catch (MidiUnavailableException e) { + out("exception occured; cannot test"); + problemOccured = true; + } + } + if (infos.length == 0) { + out("Soundcard does not exist or sound drivers not installed!"); + out("This test requires sound drivers for execution."); + } + isTestExecuted = !problemOccured; + isTestPassed = succeeded; + } + + private static boolean doTest(MidiDevice device) { + boolean succeeded = true; + out("Testing: " + device); + boolean expectingReceivers = (device.getMaxReceivers() != 0); + boolean expectingTransmitters = (device.getMaxTransmitters() != 0); + try { + Receiver rec = device.getReceiver(); + rec.close(); + if (! expectingReceivers) { + out("no exception on getting Receiver"); + succeeded = false; + } + } catch (MidiUnavailableException e) { + if (expectingReceivers) { + out("Exception on getting Receiver: " + e); + succeeded = false; + } + } + try { + Transmitter trans = device.getTransmitter(); + trans.close(); + if (! expectingTransmitters) { + out("no exception on getting Transmitter"); + succeeded = false; + } + } catch (MidiUnavailableException e) { + if (expectingTransmitters) { + out("Exception on getting Transmitter: " + e); + succeeded = false; + } + } + return succeeded; + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:40:26.000000000 +0300 +++ new/test/javax/sound/midi/Devices/Reopen.java 2016-10-24 21:40:26.000000000 +0300 @@ -0,0 +1,135 @@ +/* + * 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.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4914667 + * @summary Closing and reopening MIDI IN device on Linux throws + * MidiUnavailableException + */ +public class Reopen { + + private static boolean isTestExecuted; + private static boolean isTestPassed; + + /* + * run manually: + * java Reopen 100 in for 100 iterations on the MIDI IN device + * java Reopen 16 out for 16 iterations on the MIDI OUT device + */ + public static void main(String[] args) throws Exception { + if (args.length == 0) { + doAllTests(); + } else if (args.length == 2) { + int numIterations = Integer.parseInt(args[0]); + if (args[1].equals("in")) { + doTest(numIterations, true); + } else { + doTest(numIterations, false); + } + } else { + out("usage: java Reopen in|out"); + } + } + + private static void doAllTests() throws Exception { + out("#4914667: Closing and reopening MIDI IN device on Linux throws MidiUnavailableException"); + boolean success = true; + try { + success &= doTest(20, true); // MIDI IN + success &= doTest(20, false); // MIDI OUT + isTestExecuted = true; + } catch (Exception e) { + out(e); + isTestExecuted = false; + } + isTestPassed = success; + if (isTestExecuted) { + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } else { + out("Test NOT FAILED"); + } + } + + private static boolean doTest(int numIterations, boolean input) throws Exception { + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + MidiDevice outDevice = null; + MidiDevice inDevice = null; + for (int i = 0; i < infos.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(infos[i]); + if (! (device instanceof Sequencer) && + ! (device instanceof Synthesizer)) { + if (device.getMaxReceivers() != 0) { + outDevice = device; + } + if (device.getMaxTransmitters() != 0) { + inDevice = device; + } + } + } + MidiDevice testDevice = null; + if (input) { + testDevice = inDevice; + } else { + testDevice = outDevice; + } + if (testDevice == null) { + out("Cannot test: device not available."); + return true; + } + out("Using Device: " + testDevice); + + for (int i = 0; i < numIterations; i++) { + out("@@@ ITERATION: " + i); + testDevice.open(); + // This sleep ensures that the thread of MidiInDevice is started. + sleep(50); + testDevice.close(); + } + return true; + } + + private static void sleep(int milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (InterruptedException e) { + } + } + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:40:27.000000000 +0300 +++ new/test/javax/sound/midi/File/SMFCp037.java 2016-10-24 21:40:26.000000000 +0300 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; + +import javax.sound.midi.MidiSystem; + +/** + * @test + * @bug 4303933 + * @summary MidiSystem fails to load MIDI file on systems with EBCDIC simulation + */ +public class SMFCp037 { + + public static void main(String args[]) throws Exception { + // Test to read MIDI files with Cp037 character set - close enough + // for EBCDIC simulation + System.setProperty("file.encoding", "Cp037"); + // try to read this file with Cp037 encoding + MidiSystem.getSequence(new ByteArrayInputStream(SHORT_SMF)); + System.out.println(" test passed."); + } + +public static byte[] SHORT_SMF = { + 77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 2, 0, 120, 77, 84, 114, 107, 0, 0, + 0, 27, 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, + 116, 114, 97, 99, 107, 32, 48, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, -44, + 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, 116, 114, + 97, 99, 107, 32, 49, 0, -64, 30, 0, -112, 68, 126, 0, -32, 6, 67, 0, 14, + 71, 0, 20, 74, 0, 26, 77, 0, 32, 80, 0, 42, 85, 6, 50, 89, 6, 56, 92, 5, + 66, 97, 6, 74, 101, 6, 80, 104, 11, 84, 106, 20, 76, 102, 6, 70, 99, 5, 60, + 94, 6, 52, 90, 5, 44, 86, 4, 34, 81, 5, 26, 77, 5, 20, 74, 6, 10, 69, 5, + 2, 65, 7, 0, 64, 42, -112, 66, 123, 11, 68, 0, 72, 63, 126, 4, 66, 0, 43, + -32, 0, 63, 6, 0, 60, 7, 0, 56, 6, 0, 53, 5, 0, 49, 5, 0, 43, 4, 0, 37, 3, + 0, 30, 3, 0, 25, 3, 0, 19, 3, 0, 13, 4, 0, 8, 4, 0, 2, 4, 0, 0, 70, 0, 3, + 5, 0, 9, 3, 0, 14, 7, 0, 16, 25, 0, 21, 5, 0, 25, 7, 0, 28, 5, 0, 32, 5, + 0, 36, 5, 0, 41, 6, 0, 46, 5, 0, 50, 5, 0, 53, 4, 0, 58, 7, 0, 61, 7, 0, + 64, 117, -112, 63, 0, 0, -1, 47, 0 + }; +} --- /dev/null 2016-10-24 21:40:27.000000000 +0300 +++ new/test/javax/sound/midi/File/SMFParserBreak.java 2016-10-24 21:40:27.000000000 +0300 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; + +/** + * @test + * @bug 4910986 + * @summary MIDI file parser breaks up on http connection + */ +public class SMFParserBreak { + + public static void main(String[] args) throws Exception { + + InputStream is = new ByteArrayInputStream(midifile); + // create a buffered input stream that seems + // to be on an unfortunate boundary for the + // 1.4.2 SMF parser implementation + is = new ChunkInputStream(is, 32); + Sequence sequence = MidiSystem.getSequence(is); + + long duration = sequence.getMicrosecondLength() / 10000; + System.out.println("Duration: "+duration+" deciseconds "); + + // the test is passed if no exception thrown + System.out.println("Test passed"); + } + + // A MIDI file + static byte[] midifile = { + 77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 3, -30, 120, 77, 84, 114, 107, 0, + 0, 0, 123, 0, -112, 30, 100, -113, 49, -128, 50, 100, -114, 69, -112, 31, + 100, -114, 33, -128, 51, 100, -114, 55, -112, 32, 100, -114, 120, -128, 52, + 100, -114, 40, -112, 33, 100, -114, 26, -128, 53, 100, -114, 26, -112, 34, + 100, -114, 76, -128, 54, 100, -114, 12, -112, 35, 100, -114, 91, -128, 55, + 100, -114, 69, -112, 36, 100, -114, 33, -128, 56, 100, -114, 55, -112, 37, + 100, -114, 84, -128, 57, 100, -114, 40, -112, 38, 100, -114, 26, -128, 58, + 100, -114, 26, -112, 39, 100, -113, 24, -128, 59, 100, -113, 60, -112, 40, + 100, -113, 110, -128, 60, 100, -113, 96, -112, 41, 100, -113, 39, -128, 61, + 100, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, 4, 0, -1, 47, 0, 77, 84, 114, + 107, 0, 0, 0, 4, 0, -1, 47, 0 + }; +} + +/* an input stream that always returns data in chunks */ +class ChunkInputStream extends FilterInputStream { + int chunkSize; + int p = 0; // position + + public ChunkInputStream(InputStream is, int chunkSize) { + super(is); + this.chunkSize = chunkSize; + } + + // override to increase counter + public int read() throws IOException { + int ret = super.read(); + if (ret >= 0) { + p++; + } + return ret; + } + + // override to make sure that read(byte[], int, int) is used + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + // override to split the data in chunks + public int read(byte[] b, int off, int len) throws IOException { + // if we would pass a chunk boundary, + // only return up to the chunk boundary + if ( (p / chunkSize) < ( (p+len) / chunkSize)) { + // p+len is in the next chunk + len -= ((p+len) % chunkSize); + } + int ret = super.read(b, off, len); + if (ret >= 0) { + p += ret; + } + return ret; + } +} --- /dev/null 2016-10-24 21:40:28.000000000 +0300 +++ new/test/javax/sound/midi/File/WriteRealTimeMessageNPE.java 2016-10-24 21:40:28.000000000 +0300 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 5048381 + * @summary NPE when writing a sequence with a realtime MIDI message + */ +public class WriteRealTimeMessageNPE { + + public static void main(String args[]) throws Exception { + System.out.println("5048381: NullPointerException when saving a MIDI sequence"); + boolean npeThrown = false; + boolean noEx = false; + + Sequence seq = new Sequence(Sequence.PPQ, 384, 1); + Track t = seq.getTracks()[0]; + ShortMessage msg = new ShortMessage(); + msg.setMessage(0xF8, 0, 0); + t.add(new MidiEvent(msg, 0)); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + MidiSystem.write(seq, 0, out); + noEx = true; + } catch (NullPointerException npe) { + npeThrown = true; + System.out.println("## Failed: Threw unexpected NPE: "+npe); + throw new Exception("Test FAILED!"); + } catch (Exception e) { + System.out.println("Threw unexpected Exception: "+e); + System.out.println("But at least did not throw NPE..."); + } + if (noEx) { + InputStream is = new ByteArrayInputStream(out.toByteArray()); + seq = MidiSystem.getSequence(is); + System.out.println("Sequence has "+seq.getTracks().length+" tracks."); + if (seq.getTracks().length > 0) { + System.out.println("Track 0 has "+seq.getTracks()[0].size()+" events."); + } + } + System.out.println("Test passed."); + } +} --- /dev/null 2016-10-24 21:40:29.000000000 +0300 +++ new/test/javax/sound/midi/MetaMessage/MetaMessageClone.java 2016-10-24 21:40:28.000000000 +0300 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2002, 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.midi.MetaMessage; + +/** + * @test + * @bug 4511796 + * @summary Check that MetaMessage.clone() works correctly + */ +public class MetaMessageClone { + + private static void printMsg(MetaMessage msg, byte[] data) { + System.out.println(""+msg.getLength()+" total bytes, type="+msg.getType()+", dataLength="+data.length); + } + + private static void checkClone(MetaMessage msg) throws Exception { + System.out.print("Original: "); + byte[] msgData=msg.getData(); + printMsg(msg, msgData); + MetaMessage msg2=(MetaMessage) msg.clone(); + byte[] msg2Data=msg2.getData(); + System.out.print("Clone: "); + printMsg(msg2, msg2Data); + + if (msg2.getLength()!=msg.getLength() + || msg.getType()!=msg2.getType() + || msgData.length!=msg2Data.length) { + throw new Exception("cloned MetaMessage is not equal."); + } + int max=Math.min(msgData.length, 10); + for (int i=0; i 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //DialogOrient + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test6411624.pass(); + } + else + { + Test6411624.fail(); + } + } + + }// TestDialog class --- /dev/null 2016-10-24 21:40:30.000000000 +0300 +++ new/test/javax/sound/midi/MidiSystem/6411624/bug6411624.java 2016-10-24 21:40:30.000000000 +0300 @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2006, 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.IOException; +import java.util.Iterator; +import java.util.List; + +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; + +/** + * This test should be run on specific environment (solaris or linux w/o + * audio card installed). + */ +public class bug6411624 { + + public static void main(String args[]) throws Exception { + log("This test should only be run on solaris or linux system"); + log("without audio card installed (to test on SunRay set"); + log("incorrect $AUDIODEV value)."); + readln(); + + boolean testRecv = false; + boolean testTrans = false; + boolean testSeq = true; + + // print add info (midi device list) + try { + MidiDevice.Info[] midis = MidiSystem.getMidiDeviceInfo(); + log("MidiDevices (total " + midis.length + "):"); + for (int i=0; i transmitters = seq.getTransmitters(); + int size = transmitters.size(); + out(" transmitters.size()="+size); + if (size != 1 && connected) { + out(" should have 1 connection! Failed."); + failed = true; + } + if (size != 0 && !connected) { + out(" should have 0 connections! Failed."); + failed = true; + } + out(" closing..."); + seq.close(); + transmitters = seq.getTransmitters(); + size = transmitters.size(); + out(" transmitters.size()="+size); + if (size != 0) { + out(" should have 0 connections! Failed."); + failed = true; + } + + out(" opening again..."); + seq.open(); + transmitters = seq.getTransmitters(); + size = transmitters.size(); + out(" transmitters.size()="+size); + if (size != 1 && connected) { + out(" should have 1 connection! Failed."); + failed = true; + } + if (size != 0 && !connected) { + out(" should have 0 connections! Failed."); + failed = true; + } + } catch (Exception e) { + System.err.println(" unexpectedException was thrown: " + e); + System.err.println(" causes this test to FAIL."); + failed = true; + } + seq.close(); + } + + static void out(String s) { + System.out.println(s); + } +} --- /dev/null 2016-10-24 21:40:33.000000000 +0300 +++ new/test/javax/sound/midi/MidiSystem/MidiFileTypeUniqueness.java 2016-10-24 21:40:33.000000000 +0300 @@ -0,0 +1,51 @@ +/* + * 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.midi.MidiSystem; + +/** + * @test + * @bug 4883060 + * @summary AudioSystem.getAudioFileTypes returns duplicates + */ +public class MidiFileTypeUniqueness { + + public static void main(String[] args) throws Exception { + boolean foundDuplicates = false; + int[] aTypes = MidiSystem.getMidiFileTypes(); + for (int i = 0; i < aTypes.length; i++) + { + for (int j = 0; j < aTypes.length; j++) + { + if (aTypes[i] == aTypes[j] && i != j) { + foundDuplicates = true; + } + } + } + if (foundDuplicates) { + throw new Exception("Test failed"); + } else { + System.out.println("Test passed"); + } + } +} --- /dev/null 2016-10-24 21:40:34.000000000 +0300 +++ new/test/javax/sound/midi/MidiSystem/ProviderCacheing.java 2016-10-24 21:40:33.000000000 +0300 @@ -0,0 +1,65 @@ +/* + * 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.util.List; + +import com.sun.media.sound.JDK13Services; + +/** + * @test + * @bug 4776511 + * @summary RFE: Setting the default MixerProvider. Test the cacheing of + * providers. This is a part of the test for 4776511. + * @modules java.desktop/com.sun.media.sound + */ +public class ProviderCacheing { + + private static final Class[] providerClasses = { + javax.sound.midi.spi.MidiDeviceProvider.class, + javax.sound.midi.spi.MidiFileReader.class, + javax.sound.midi.spi.MidiFileWriter.class, + javax.sound.midi.spi.SoundbankReader.class, + }; + + public static void main(String[] args) throws Exception { + boolean allCached = true; + for (int i = 0; i < providerClasses.length; i++) { + List list0 = JDK13Services.getProviders(providerClasses[i]); + List list1 = JDK13Services.getProviders(providerClasses[i]); + if (list0 == list1) { + out("Providers should not be cached for " + providerClasses[i]); + allCached = false; + } + } + + if (! allCached) { + throw new Exception("Test failed"); + } else { + out("Test passed"); + } + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:40:34.000000000 +0300 +++ new/test/javax/sound/midi/MidiSystem/testdata/conf/sound.properties 2016-10-24 21:40:34.000000000 +0300 @@ -0,0 +1,27 @@ +# +# 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. +# + +javax.sound.midi.Receiver=xyz#123 +javax.sound.midi.Transmitter=xyz#123 +javax.sound.midi.Sequencer=xyz#123 +javax.sound.midi.Synthesizer=xyz#123 --- /dev/null 2016-10-24 21:40:35.000000000 +0300 +++ new/test/javax/sound/midi/Sequence/GetMicrosecondLength.java 2016-10-24 21:40:35.000000000 +0300 @@ -0,0 +1,151 @@ +/* + * 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.midi.InvalidMidiDataException; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4929955 + * @summary Sequence.getMicrosecondLength() returns wrong value + */ +public class GetMicrosecondLength { + + public static boolean failed = false; + //private static Sequencer seq = null; + + public static void main(String[] args) throws Exception { + /* + try { + seq = MidiSystem.getSequencer(); + } catch (Exception e) { + e.printStackTrace(); + } + */ + for (int sec = 1; sec < 10; sec += 4) { + for (int tempo=0; tempo < 1000; tempo+=120) { + for (int resolution=1; resolution < 480; ) { + testSequence(sec, tempo, resolution); + if (resolution == 1) { + resolution = 120; + } else { + resolution += 120; + } + } + } + } + if (failed) throw new Exception("Test FAILED!"); + out("Test Passed."); + } + + /** + * Create a new Sequence for testing. + */ + private static void testSequence(int lengthInSeconds, int tempoInBPM, int resolution) { + Sequence sequence = null; + long lengthInMicroseconds = lengthInSeconds * 1000000; + boolean createTempoEvent = true; + if (tempoInBPM == 0) { + tempoInBPM = 120; + createTempoEvent = false; + System.out.print("Creating sequence: "+lengthInSeconds+"sec, " + +"resolution="+resolution+" ticks/beat..."); + } else { + System.out.print("Creating sequence: "+lengthInSeconds+"sec, " + +tempoInBPM+" beats/min, " + +"resolution="+resolution+" ticks/beat..."); + } + //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM; + long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l; + //out("expected length in ticks: " + lengthInTicks); + try { + sequence = new Sequence(Sequence.PPQ, resolution); + Track track = sequence.createTrack(); + if (createTempoEvent) { + int tempoInMPQ = (int) (60000000l / tempoInBPM); + MetaMessage tm = new MetaMessage(); + byte[] msg = new byte[3]; + msg[0] = (byte) (tempoInMPQ >> 16); + msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF); + msg[2] = (byte) (tempoInMPQ & 0xFF); + + tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length); + track.add(new MidiEvent(tm, 0)); + //out("regtest: tempoInMPQ="+tempoInMPQ); + //out("Added tempo event: new size="+track.size()); + } + ShortMessage mm = new ShortMessage(); + mm.setMessage(0xF6, 0, 0); + MidiEvent me = new MidiEvent(mm, lengthInTicks); + track.add(me); + //out("Added realtime event: new size="+track.size()); + } catch (InvalidMidiDataException e) { + out(e); + } + boolean thisFailed = false; + long actualLengthInTicks = sequence.getTickLength(); + // allow +/- 5% + if (Math.abs(actualLengthInTicks - lengthInTicks) > lengthInTicks / 20) { + out("FAILED:"); + out(" expected length in ticks: " + lengthInTicks); + out(" actual length in ticks : " + actualLengthInTicks); + thisFailed = true; + } + long actualLengthInUs = sequence.getMicrosecondLength(); + // allow +/- 5% + if (Math.abs(actualLengthInUs - lengthInMicroseconds) > lengthInMicroseconds / 20) { + if (!thisFailed) { + out("FAILED:"); + } + out(" expected length in microsecs: " + lengthInMicroseconds); + out(" actual length in microsecs : " + actualLengthInUs); + thisFailed = true; + } + if (!thisFailed) { + out("OK"); + } + /*if (seq != null) { + try { + seq.setSequence(sequence); + out("Sequencer tempo="+seq.getTempoInBPM()); + } catch (Exception e) { + e.printStackTrace(); + } + } + */ + failed |= thisFailed; + } + + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:40:36.000000000 +0300 +++ new/test/javax/sound/midi/Sequence/MidiSMPTE.java 2016-10-24 21:40:35.000000000 +0300 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; + +/** + * @test + * @bug 4291250 + * @summary Midi files with SMPTE time do not play properly + */ +public class MidiSMPTE { + + public static void main(String[] args) throws Exception { + Sequence s = null; + //File midiFile = new File("outsmpte.mid"); + //InputStream is = new FileInputStream(midiFile); + //is = new BufferedInputStream(is); + InputStream is = new ByteArrayInputStream(smptemidifile); + s = MidiSystem.getSequence(is); + long duration = s.getMicrosecondLength() / 1000000; + System.out.println("Duration: "+duration+" seconds "); + if (duration > 14) { + throw new Exception("SMPTE time reader is broken! Test FAILED"); + } + System.out.println("Test passed"); + } + + public static void printFile(String filename) throws Exception { + File file = new File(filename); + FileInputStream fis = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + fis.read(data); + String s = ""; + for (int i=0; i72) { + System.out.println(s); + s=""; + } + } + System.out.println(s); + } + + // A MIDI file with SMPTE timing + static byte[] smptemidifile = { + 77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 3, -30, 120, 77, 84, 114, 107, 0, + 0, 0, 123, 0, -112, 30, 100, -113, 49, -128, 50, 100, -114, 69, -112, 31, + 100, -114, 33, -128, 51, 100, -114, 55, -112, 32, 100, -114, 120, -128, 52, + 100, -114, 40, -112, 33, 100, -114, 26, -128, 53, 100, -114, 26, -112, 34, + 100, -114, 76, -128, 54, 100, -114, 12, -112, 35, 100, -114, 91, -128, 55, + 100, -114, 69, -112, 36, 100, -114, 33, -128, 56, 100, -114, 55, -112, 37, + 100, -114, 84, -128, 57, 100, -114, 40, -112, 38, 100, -114, 26, -128, 58, + 100, -114, 26, -112, 39, 100, -113, 24, -128, 59, 100, -113, 60, -112, 40, + 100, -113, 110, -128, 60, 100, -113, 96, -112, 41, 100, -113, 39, -128, 61, + 100, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, 4, 0, -1, 47, 0, 77, 84, 114, + 107, 0, 0, 0, 4, 0, -1, 47, 0 + }; + +} --- /dev/null 2016-10-24 21:40:36.000000000 +0300 +++ new/test/javax/sound/midi/Sequence/SMPTEDuration.java 2016-10-24 21:40:36.000000000 +0300 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2002, 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.midi.InvalidMidiDataException; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4702328 + * @summary Wrong time in sequence for SMPTE based types + */ +public class SMPTEDuration { + + public static void main(String args[]) throws Exception { + int[][] dataMes = { {ShortMessage.NOTE_ON, 10, 0x24, 0x50} , + { ShortMessage.NOTE_OFF, 10, 0x24, 0x44 }, + { ShortMessage.NOTE_ON, 10, 0x24, 0x50 }, + { ShortMessage.NOTE_ON, 10, 0x26, 0x50 }, + { ShortMessage.NOTE_OFF, 10, 0x26, 0x53 } }; + long[] ticks = { 0, 68, 240, 240, 286}; + int res = 240; + ShortMessage msg; + Sequence midiData = null; + Track track; + boolean failed = false; + + + try { + midiData = new Sequence(Sequence.SMPTE_24 , res); + } catch (InvalidMidiDataException invMidiEx) { + invMidiEx.printStackTrace(System.out); + System.out.println("Unexpected InvalidMidiDataException: " + + invMidiEx.getMessage()); + failed = true; + } + track = midiData.createTrack(); + for (int i = 0; i < dataMes.length; i++) { + msg = new ShortMessage(); + try { + msg.setMessage(dataMes[i][0], dataMes[i][1], dataMes[i][2], + dataMes[i][3]); + } catch (InvalidMidiDataException invMidiEx) { + invMidiEx.printStackTrace(System.out); + System.out.println("Unexpected InvalidMidiDataException: " + + invMidiEx.getMessage()); + failed = true; + } + track.add(new MidiEvent(msg, ticks[i])); + } + // lengthInMs = (tickLength*1000000)/(divType*Res) + long micros = (long) ((midiData.getTickLength() * 1000000) / (res * Sequence.SMPTE_24)); + if (midiData.getMicrosecondLength() != micros) { + failed = true; + System.out.println("getMicrosecondLength() returns wrong length: " + + midiData.getMicrosecondLength()); + System.out.println("getMicrosecondLength() must return length: " + + micros); + } + if (midiData.getTickLength() != 286) { + failed = true; + System.out.println("getTickLength() returns wrong length: " + + midiData.getTickLength()); + } + + if( failed == true ) { + throw new Exception("test failed"); + } else { + System.out.println("Passed."); + } + } +} --- /dev/null 2016-10-24 21:40:37.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/LoopIAE.java 2016-10-24 21:40:37.000000000 +0300 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2004, 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.midi.InvalidMidiDataException; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 5025549 + * @summary Verify that setLoopEndPoint throws IAE + */ +public class LoopIAE { + + static ShortMessage MidiMsg3(int a, int b, int c) { + try { + ShortMessage msg = new ShortMessage(); + msg.setMessage((byte)a,(byte)b,(byte)c); + return msg; + } catch(InvalidMidiDataException ex) { + throw new RuntimeException(); + } + } + + static boolean failed = false; + + public static void main(String[] argv) throws Exception { + if (!hasSequencer()) { + return; + } + Sequencer sequencer = MidiSystem.getSequencer(); + Sequence sequence = new Sequence(Sequence.PPQ, 240); + Track track = sequence.createTrack(); + + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,100),0)); + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,0),0 + 240)); + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,100),10*20)); + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,0),10*20 + 10)); + + try { + sequencer.open(); + sequencer.setSequence(sequence); + sequencer.setTempoInBPM(100); + + System.out.println("Setting loop end point to 1"); + sequencer.setLoopEndPoint(1); + System.out.println(" -> effectively: "+sequencer.getLoopEndPoint()); + System.out.println("Setting loop start point to 2 -- should throw IAE"); + sequencer.setLoopStartPoint(2); + System.out.println(" -> effectively: "+sequencer.getLoopStartPoint()); + System.out.println("No IllegalArgumentException was thrown!"); + failed = true; + } catch (IllegalArgumentException iae) { + System.out.println("IAE was thrown correctly."); + } catch (MidiUnavailableException mue) { + System.out.println("MidiUnavailableException was thrown: " + mue); + System.out.println("Cannot execute test."); + } catch (InvalidMidiDataException imEx) { + System.out.println("InvalidMidiDataException was thrown."); + imEx.printStackTrace(); + System.out.println("Cannot execute test."); + } finally { + if (sequencer != null && sequencer.isOpen()) { + sequencer.close(); + } + } + if (failed) { + throw new Exception("Test FAILED!"); + } + System.out.println("test passed."); + } + + static boolean hasSequencer() { + try { + Sequencer seq = MidiSystem.getSequencer(); + if (seq != null) { + if (seq.isOpen()) { + seq.close(); + } + return true; + } + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("No sequencer available! Cannot execute test."); + return false; + } +} --- /dev/null 2016-10-24 21:40:38.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/Looping.java 2016-10-24 21:40:38.000000000 +0300 @@ -0,0 +1,315 @@ +/* + * 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.midi.InvalidMidiDataException; +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4204105 + * @summary RFE: add loop() method(s) to Sequencer + * @key intermittent + */ +public class Looping { + + public static void main(String[] args) throws Exception { + out("4204105: RFE: add loop() method(s) to Sequencer"); + boolean passed = testAll(); + if (passed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + + /** + * Execute the test on all available Sequencers. + * + * @return true if the test passed for all Sequencers, false otherwise + */ + private static boolean testAll() throws Exception { + boolean result = true; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + if (device instanceof Sequencer) { + result &= testSequencer((Sequencer) device); + } + } + return result; + } + + /** + * Execute the test on the passed Sequencer. + * + * @return true if the test is passed this Sequencer, false otherwise + */ + private static boolean testSequencer(Sequencer seq) throws Exception{ + boolean result = true; + out("testing: " + seq); + + result &= testGetSet(seq); + + seq.setSequence(createSequence()); + + result &= testGetSet(seq); + + result &= testPlay(seq); + + return result; + } + + private static boolean testGetSet(Sequencer seq) { + boolean result = true; + Sequence sequence = seq.getSequence(); + boolean isSequenceLoaded = (sequence != null); + + out("TestGetSet"); + + try { + if (seq.getLoopStartPoint() != 0) { + out("start point", isSequenceLoaded, + "isn't 0!"); + result = false; + } + } catch (IllegalArgumentException iae) { + if (!isSequenceLoaded) { + out("Caught permissable IllegalArgumentException:"); + } else { + out("Threw unacceptable IllegalArgumentException! FAILED"); + result = false; + } + out(iae.toString()); + } + + if (seq.getLoopEndPoint() != -1) { + out("end point", isSequenceLoaded, + "isn't -1!"); + result = false; + } + + try { + seq.setLoopStartPoint(25); + if (seq.getLoopStartPoint() != 25) { + out("setLoopStartPoint()", isSequenceLoaded, + "doesn't set the start point correctly!"); + result = false; + } + } catch (IllegalArgumentException iae) { + if (!isSequenceLoaded) { + out("Caught permissable IllegalArgumentException:"); + } else { + out("Threw unacceptable IllegalArgumentException! FAILED"); + result = false; + } + out(iae.toString()); + } + + try { + seq.setLoopEndPoint(26); + if (seq.getLoopEndPoint() != 26) { + out("setLoopEndPoint()", isSequenceLoaded, + "doesn't set the end point correctly!"); + result = false; + } + } catch (IllegalArgumentException iae) { + if (!isSequenceLoaded) { + out("Caught permissable IllegalArgumentException:"); + } else { + out("Threw unacceptable IllegalArgumentException! FAILED"); + result = false; + } + out(iae.toString()); + } + + try { + seq.setLoopStartPoint(0); + if (seq.getLoopStartPoint() != 0) { + out("setLoopStartPoint()", isSequenceLoaded, + "doesn't set the start point correctly!"); + result = false; + } + } catch (IllegalArgumentException iae) { + if (!isSequenceLoaded) { + out("Caught permissable IllegalArgumentException:"); + } else { + out("Threw unacceptable IllegalArgumentException! FAILED"); + result = false; + } + out(iae.toString()); + } + + if (isSequenceLoaded) { + seq.setLoopEndPoint(sequence.getTickLength()); + if (seq.getLoopEndPoint() != sequence.getTickLength()) { + out("setLoopEndPoint()", isSequenceLoaded, + "doesn't set the end point correctly!"); + result = false; + } + } else { + // fails + seq.setLoopEndPoint(-1); + if (seq.getLoopEndPoint() != -1) { + out("setLoopEndPoint()", isSequenceLoaded, + "doesn't set the end point correctly!"); + result = false; + } + } + + if (seq.getLoopCount() != 0) { + out("loop count", isSequenceLoaded, + "isn't 0!"); + result = false; + } + + seq.setLoopCount(1001); + if (seq.getLoopCount() != 1001) { + out("setLoopCount()", isSequenceLoaded, + "doesn't set the loop count correctly!"); + result = false; + } + + seq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY); + if (seq.getLoopCount() != Sequencer.LOOP_CONTINUOUSLY) { + out("setLoopCount(Sequencer.LOOP_CONTINUOUSLY)", isSequenceLoaded, + "doesn't set the loop count correctly!"); + result = false; + } + + try { + seq.setLoopCount(-55); + out("setLoopCount()", isSequenceLoaded, + "doesn't throw IllegalArgumentException on illegal value!"); + result = false; + } catch (IllegalArgumentException e) { + // EXCEPTION IS EXPECTED + out("Caught permissable IAE"); + } + + seq.setLoopCount(0); + if (seq.getLoopCount() != 0) { + out("setLoopCount()", isSequenceLoaded, + "doesn't set the loop count correctly!"); + result = false; + } + + return result; + } + + private static boolean testPlay(Sequencer seq) { + boolean result = true; + long stopTime; + + out("TestPlay"); + + TestMetaEventListener listener = new TestMetaEventListener(); + seq.addMetaEventListener(listener); + long startTime = System.currentTimeMillis(); + try { + seq.open(); + out("Playing sequence, length="+(seq.getMicrosecondLength()/1000)+"millis"); + seq.start(); + while (true) { + stopTime = listener.getStopTime(); + if (stopTime != 0) { + break; + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + long measuredDuration = stopTime - startTime; + out("play duration (us): " + measuredDuration); + } catch (Exception e) { + out("test not executed; exception:"); + e.printStackTrace(); + } + seq.close(); + return result; + } + + /** + * Create a new Sequence for testing. + * + * @return a dummy Sequence, or null, if a problem occured while creating + * the Sequence + */ + private static Sequence createSequence() { + Sequence sequence = null; + int lengthInSeconds = 2; + long lengthInMicroseconds = lengthInSeconds * 1000000; + int resolution = 480; + long lengthInTicks = (lengthInMicroseconds * 120 * resolution) / 60000000l; + out("length in ticks: " + lengthInTicks); + try { + sequence = new Sequence(Sequence.PPQ, resolution, 1); + Track track = sequence.createTrack(); + ShortMessage mm = new ShortMessage(); + mm.setMessage(0xF6, 0, 0); + MidiEvent me = new MidiEvent(mm, lengthInTicks); + track.add(me); + } catch (InvalidMidiDataException e) { + // DO NOTHING + } + out("sequence length (ticks): " + sequence.getTickLength()); + out("sequence length (us): " + sequence.getMicrosecondLength()); + return sequence; + } + + + private static void out(String m1, boolean isSequenceLoaded, String m2) { + out(m1 + (isSequenceLoaded ? " with Sequence " : " without Sequence ") + m2); + } + + private static void out(String message) { + System.out.println(message); + } + + private static class TestMetaEventListener implements MetaEventListener { + private long stopTime; + + + public void meta(MetaMessage m) { + System.out.print(" Got MetaMessage: "); + if (m.getType() == 47) { + stopTime = System.currentTimeMillis(); + System.out.println(" End Of Track -- OK"); + } else { + System.out.println(" unknown. Ignored."); + } + } + + public long getStopTime() { + return stopTime; + } + } +} --- /dev/null 2016-10-24 21:40:39.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/MetaCallback.java 2016-10-24 21:40:38.000000000 +0300 @@ -0,0 +1,133 @@ +/* + * 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.midi.Instrument; +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4347135 + * @summary MIDI MetaMessage callback inconsistent + * @run main/othervm MetaCallback + */ +public class MetaCallback implements MetaEventListener { + + static ShortMessage MidiMsg3(int a, int b, int c) { + try { + ShortMessage msg = new ShortMessage(); + msg.setMessage((byte)a,(byte)b,(byte)c); + return msg; + } catch(InvalidMidiDataException ex) { + throw new RuntimeException(); + } + } + + //Synthesizer synth; + Instrument[] instruments; + Sequencer sequencer; + Sequence sequence; + Track track; + + public static int TOTAL_COUNT = 100; + + int metaCount = 0; + boolean finished = false; + + MetaCallback() throws Exception { + + sequencer=MidiSystem.getSequencer(); + sequence=new Sequence(Sequence.PPQ,240); + track=sequence.createTrack(); + sequencer.addMetaEventListener(this); + + byte[] data = new byte[1]; + + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,100),0)); + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+0,45,0),0 + 240)); + int c; + for(c=0; c < TOTAL_COUNT; c++) { + data[0]=(byte)(c+1); + MetaMessage meta = new MetaMessage(); + meta.setMessage(1, data, 1); // type, data, length + track.add(new MidiEvent(meta,c*20)); + } + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,100),c*20)); + track.add(new MidiEvent(MidiMsg3(ShortMessage.NOTE_ON+9,45,0),c*20 + 10)); + + sequencer.setSlaveSyncMode(Sequencer.SyncMode.INTERNAL_CLOCK); + sequencer.setMasterSyncMode(Sequencer.SyncMode.INTERNAL_CLOCK); + sequencer.open(); + sequencer.setSequence(sequence); + sequencer.setTempoInBPM(100); + System.out.println("Starting playback..."); + this.start(); + while (!finished && sequencer.getTickPosition() < sequencer.getTickLength()) { + System.out.println("Tick "+sequencer.getTickPosition()+"..."); + Thread.sleep(1000); + } + System.out.println("Stopping playback..."); + this.stop(); + if (metaCount != TOTAL_COUNT) { + throw new Exception("Expected "+TOTAL_COUNT+" callbacks, but got "+metaCount+"!"); + } + } + void start() {sequencer.start();} + void stop() {sequencer.stop();} + + public void meta(MetaMessage msg) { + System.out.println(""+metaCount+": got "+msg); + if (msg.getType() == 0x2F) { + finished = true; + } else if (msg.getData().length > 0 && msg.getType() == 1) { + metaCount++; + } + } + + public static void main(String[] argv) throws Exception { + if (hasSequencer()) { + new MetaCallback(); + System.out.println("Test passed"); + } + } + + static boolean hasSequencer() { + try { + Sequencer seq = MidiSystem.getSequencer(); + if (seq != null) { + seq.open(); + seq.close(); + return true; + } + } catch (Exception e) {} + System.out.println("No sequencer available! Cannot execute test."); + return false; + } +} --- /dev/null 2016-10-24 21:40:39.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/Recording.java 2016-10-24 21:40:39.000000000 +0300 @@ -0,0 +1,213 @@ +/* + * 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.midi.InvalidMidiDataException; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4932841 + * @key intermittent + * @summary Sequencer's recording feature does not work + */ +public class Recording { + + public static boolean failed = false; + public static boolean passed = false; + private static Sequencer seq = null; + + public static void main(String[] args) throws Exception { + try { + seq = MidiSystem.getSequencer(); + + // create an arbitrary sequence which lasts 10 seconds + Sequence sequence = createSequence(10, 120, 240); + + seq.setSequence(sequence); + out("Set Sequence to Sequencer. Tempo="+seq.getTempoInBPM()); + + Track track = sequence.createTrack(); + int oldSize = track.size(); + seq.recordEnable(track, -1); + + seq.open(); + + // if getReceiver throws Exception, failed! + failed = true; + Receiver rec = seq.getReceiver(); + + // start recording and add various events + seq.startRecording(); + + // is exception from here on, not failed + failed = false; + + if (!seq.isRecording()) { + failed = true; + throw new Exception("Sequencer did not start recording!"); + } + if (!seq.isRunning()) { + failed = true; + throw new Exception("Sequencer started recording, but is not running!"); + } + + // first: add an event to the middle of the sequence + ShortMessage msg = new ShortMessage(); + msg.setMessage(0xC0, 80, 00); + rec.send(msg, 5l * 1000l * 1000l); + + Thread.sleep(1000); + + // then add a real-time event + msg = new ShortMessage(); + msg.setMessage(0xC0, 81, 00); + long secondEventTick = seq.getTickPosition(); + rec.send(msg, -1); + + seq.stopRecording(); + if (seq.isRecording()) { + failed = true; + throw new Exception("Stopped recording, but Sequencer is still recording!"); + } + if (!seq.isRunning()) { + failed = true; + throw new Exception("Stopped recording, but Sequencer but is not running anymore!"); + } + + seq.stop(); + if (seq.isRunning()) { + failed = true; + throw new Exception("Stopped Sequencer, but it is still running!"); + } + + // now examine the contents of the recorded track: + // 1) number of events: should be 2 more + int newSize = track.size(); + int addedEventCount = newSize - oldSize; + + out("Added "+addedEventCount+" events to recording track."); + if (addedEventCount != 2) { + failed = true; + throw new Exception("Did not add 2 events!"); + } + + // 2) the first event should be at roughly "secondEventTick" + MidiEvent ev = track.get(0); + msg = (ShortMessage) ev.getMessage(); + out("The first recorded event is at tick position: "+ev.getTick()); + if (Math.abs(ev.getTick() - secondEventTick) > 1000) { + out(" -> but expected something like: "+secondEventTick+"! FAILED."); + failed = true; + } + + ev = track.get(1); + msg = (ShortMessage) ev.getMessage(); + out("The 2nd recorded event is at tick position: "+ev.getTick()); + out(" -> sequence's tick length is "+seq.getTickLength()); + if (Math.abs(ev.getTick() - (sequence.getTickLength() / 2)) > 1000) { + out(" -> but expected something like: "+(seq.getTickLength()/2)+"! FAILED."); + failed = true; + } + + passed = true; + } catch (Exception e) { + out(e.toString()); + if (!failed) out("Test not failed."); + } + if (seq != null) { + seq.close(); + } + + if (failed) { + throw new Exception("Test FAILED!"); + } + else if (passed) { + out("Test Passed."); + } + } + + /** + * Create a new Sequence for testing. + */ + private static Sequence createSequence(int lengthInSeconds, int tempoInBPM, + int resolution) { + Sequence sequence = null; + long lengthInMicroseconds = lengthInSeconds * 1000000; + boolean createTempoEvent = true; + if (tempoInBPM == 0) { + tempoInBPM = 120; + createTempoEvent = false; + System.out.print("Creating sequence: "+lengthInSeconds+"sec, " + +"resolution="+resolution+" ticks/beat..."); + } else { + System.out.print("Creating sequence: "+lengthInSeconds+"sec, " + +tempoInBPM+" beats/min, " + +"resolution="+resolution+" ticks/beat..."); + } + //long lengthInTicks = (lengthInMicroseconds * resolution) / tempoInBPM; + long lengthInTicks = (lengthInMicroseconds * tempoInBPM * resolution) / 60000000l; + //out("expected length in ticks: " + lengthInTicks); + try { + sequence = new Sequence(Sequence.PPQ, resolution); + Track track = sequence.createTrack(); + if (createTempoEvent) { + int tempoInMPQ = (int) (60000000l / tempoInBPM); + MetaMessage tm = new MetaMessage(); + byte[] msg = new byte[3]; + msg[0] = (byte) (tempoInMPQ >> 16); + msg[1] = (byte) ((tempoInMPQ >> 8) & 0xFF); + msg[2] = (byte) (tempoInMPQ & 0xFF); + + tm.setMessage(0x51 /* Meta Tempo */, msg, msg.length); + track.add(new MidiEvent(tm, 0)); + //out("regtest: tempoInMPQ="+tempoInMPQ); + //out("Added tempo event: new size="+track.size()); + } + ShortMessage mm = new ShortMessage(); + mm.setMessage(0xF6, 0, 0); + MidiEvent me = new MidiEvent(mm, lengthInTicks); + track.add(me); + //out("Added realtime event: new size="+track.size()); + } catch (InvalidMidiDataException e) { + out(e); + } + out("OK"); + + return sequence; + } + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:40:40.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/SeqRecordDoesNotCopy.java 2016-10-24 21:40:40.000000000 +0300 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2004, 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.midi.MidiEvent; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 5048381 + * @summary Sequencer doesn't create distinct messages when recording events. + * @key headful + */ +public class SeqRecordDoesNotCopy { + public static void main(String argv[]) throws Exception { + Sequencer s = MidiSystem.getSequencer(); + s.open(); + try { + Sequence seq = new Sequence(Sequence.PPQ, 384, 2); + s.setSequence(seq); + Track t = seq.getTracks()[0]; + ShortMessage msg = new ShortMessage(); + msg.setMessage(0x90, 0x40, 0x7F); + t.add(new MidiEvent(msg, 11000)); + msg.setMessage(0x90, 0x40, 0x00); + t.add(new MidiEvent(msg, 12000)); + t = seq.getTracks()[1]; + s.recordEnable(t, -1); + System.out.println("Started recording..."); + s.startRecording(); + Receiver r = s.getReceiver(); + Thread.sleep(100); + // send a normal message + System.out.println("Recording a normal NOTE ON message..."); + msg.setMessage(0x90, 0x40, 0x6F); + r.send(msg, -1); + Thread.sleep(100); + // send a normal message + System.out.println("Recording a normal NOTE OFF message..."); + msg.setMessage(0x90, 0x40, 0x00); + r.send(msg, -1); + Thread.sleep(100); + s.stop(); + // now see if the messages were recorded + System.out.println("Recorded messages:"); + int sameMessage = 0; + for (int i = 0; i < t.size(); i++) { + System.out.print(" "+(i+1)+". "); + printEvent(t.get(i)); + if (t.get(i).getMessage() == msg) { + System.out.println("## Failed: Same Message reference!"); + sameMessage++; + } + } + if (sameMessage > 0) { + System.out.println("## Failed: The same instance was recorded!"); + throw new Exception("Test FAILED!"); + } + System.out.println("Did not detect any duplicate messages."); + System.out.println("Test passed."); + } catch (Exception e) { + System.out.println("Unexpected Exception: "+e); + //e.printStackTrace(); + throw new Exception("Test FAILED!"); + } finally { + s.close(); + } + } + public static void printEvent(MidiEvent event) + { + MidiMessage message = event.getMessage(); + long tick = event.getTick(); + byte[] data = message.getMessage(); + + StringBuffer sb = new StringBuffer((data.length * 3) - 1); + + for (int i = 0; i < data.length; i++) + { + sb.append(toHexByteString(data[i])); + if (i < data.length - 1) sb.append(' '); + } + System.out.printf("%5d: %s%n", tick, sb); + } + + private static String toHexByteString(int n) + { + if (n < 0) n &= 0xFF; + String s = Integer.toHexString(n).toUpperCase(); + if (s.length() == 1) s = '0' + s; + return s; + } +} --- /dev/null 2016-10-24 21:40:41.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java 2016-10-24 21:40:40.000000000 +0300 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2004, 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.midi.MidiEvent; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 5048381 + * @summary Sequencer records real time messages into the sequence + * @key headful + */ +public class SeqRecordsRealTimeEvents { + public static void main(String argv[]) throws Exception { + Sequencer s = MidiSystem.getSequencer(); + s.open(); + try { + Sequence seq = new Sequence(Sequence.PPQ, 384, 2); + s.setSequence(seq); + Track t = seq.getTracks()[0]; + ShortMessage msg = new ShortMessage(); + msg.setMessage(0x90, 0x40, 0x7F); + t.add(new MidiEvent(msg, 11000)); + msg = new ShortMessage(); + msg.setMessage(0x90, 0x40, 0x00); + t.add(new MidiEvent(msg, 12000)); + t = seq.getTracks()[1]; + s.recordEnable(t, -1); + System.out.println("Started recording..."); + s.startRecording(); + Receiver r = s.getReceiver(); + Thread.sleep(100); + int oldTrackSize = t.size(); + // send a realtime message to the track + System.out.println("Recording real time message..."); + msg = new ShortMessage(); + msg.setMessage(0xF8, 0, 0); + r.send(msg, -1); + Thread.sleep(100); + // send a normal message + msg = new ShortMessage(); + System.out.println("Recording a normal NOTE ON message..."); + msg.setMessage(0x90, 0x40, 0x6F); + r.send(msg, -1); + Thread.sleep(100); + s.stop(); + // now see if the messages were recorded + int newMessages = t.size() - oldTrackSize; + System.out.println("Recorded messages:"); + for (int i = 0; i < t.size(); i++) { + System.out.print(" "+(i+1)+". "); + printEvent(t.get(i)); + } + if (newMessages == 0) { + System.out.println("## Failed: No messages were recorded!"); + throw new Exception("Test FAILED!"); + } else if (newMessages == 1) { + System.out.println("Only one message was recorded. Correct!"); + } else if (newMessages > 1) { + System.out.println("## Failed: 2 or more messages were recorded!"); + throw new Exception("Test FAILED!"); + } + System.out.println("Test passed."); + } catch (Exception e) { + System.out.println("Unexpected Exception: "+e); + //e.printStackTrace(); + throw new Exception("Test FAILED!"); + } finally { + s.close(); + } + } + public static void printEvent(MidiEvent event) + { + MidiMessage message = event.getMessage(); + long tick = event.getTick(); + byte[] data = message.getMessage(); + + StringBuffer sb = new StringBuffer((data.length * 3) - 1); + + for (int i = 0; i < data.length; i++) + { + sb.append(toHexByteString(data[i])); + if (i < data.length - 1) sb.append(' '); + } + System.out.printf("%5d: %s%n", tick, sb); + } + + private static String toHexByteString(int n) + { + if (n < 0) n &= 0xFF; + String s = Integer.toHexString(n).toUpperCase(); + if (s.length() == 1) s = '0' + s; + return s; + } +} --- /dev/null 2016-10-24 21:40:41.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/SeqStartRecording.java 2016-10-24 21:40:41.000000000 +0300 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2004, 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.midi.MidiSystem; +import javax.sound.midi.Sequencer; + +/** + * @test + * @bug 5001943 + * @summary Sequencer.startRecording throws unexpected NPE + * @key headful + */ +public class SeqStartRecording { + public static void main(String argv[]) throws Exception { + Sequencer seq = MidiSystem.getSequencer(); + seq.open(); + try { + seq.startRecording(); + System.out.println("Test passed."); + } catch (NullPointerException npe) { + System.out.println("Caught NPE: "+npe); + npe.printStackTrace(); + throw new Exception("Test FAILED!"); + } catch (Exception e) { + System.out.println("Unexpected Exception: "+e); + e.printStackTrace(); + System.out.println("Test NOT failed."); + } finally { + seq.close(); + } + } +} --- /dev/null 2016-10-24 21:40:42.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/SequencerCacheValues.java 2016-10-24 21:40:42.000000000 +0300 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2002, 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.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Sequencer; + +/** + * @test + * @bug 4716740 + * @summary default sequencer does not set the tempo factor + */ +public class SequencerCacheValues { + + static boolean failed = false; + + public static void main(String args[]) throws Exception { + Sequencer seq = null; + int totalNumberOfSequencers = 0; + + MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo(); + for (int device=0; device72) { + System.out.println(s); + s=""; + } + } + System.out.println(s); + } + + public static Sequence getSequence() throws Exception { + ByteArrayInputStream bais = new ByteArrayInputStream(pitchbend); + Sequence seq = MidiSystem.getSequence(bais); + return seq; + } + + public static byte[] pitchbend = { + 77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 2, 0, 120, 77, 84, 114, 107, 0, 0, + 0, 27, 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, + 116, 114, 97, 99, 107, 32, 48, 0, -1, 47, 0, 77, 84, 114, 107, 0, 0, 0, -44, + 0, -1, 3, 19, 77, 73, 68, 73, 32, 116, 101, 115, 116, 32, 45, 32, 116, 114, + 97, 99, 107, 32, 49, 0, -64, 30, 0, -112, 68, 126, 0, -32, 6, 67, 0, 14, + 71, 0, 20, 74, 0, 26, 77, 0, 32, 80, 0, 42, 85, 6, 50, 89, 6, 56, 92, 5, + 66, 97, 6, 74, 101, 6, 80, 104, 11, 84, 106, 20, 76, 102, 6, 70, 99, 5, 60, + 94, 6, 52, 90, 5, 44, 86, 4, 34, 81, 5, 26, 77, 5, 20, 74, 6, 10, 69, 5, + 2, 65, 7, 0, 64, 42, -112, 66, 123, 11, 68, 0, 72, 63, 126, 4, 66, 0, 43, + -32, 0, 63, 6, 0, 60, 7, 0, 56, 6, 0, 53, 5, 0, 49, 5, 0, 43, 4, 0, 37, 3, + 0, 30, 3, 0, 25, 3, 0, 19, 3, 0, 13, 4, 0, 8, 4, 0, 2, 4, 0, 0, 70, 0, 3, + 5, 0, 9, 3, 0, 14, 7, 0, 16, 25, 0, 21, 5, 0, 25, 7, 0, 28, 5, 0, 32, 5, + 0, 36, 5, 0, 41, 6, 0, 46, 5, 0, 50, 5, 0, 53, 4, 0, 58, 7, 0, 61, 7, 0, + 64, 117, -112, 63, 0, 0, -1, 47, 0 + }; + + static boolean hasSequencer() { + try { + Sequencer seq = MidiSystem.getSequencer(); + if (seq != null) { + seq.open(); + seq.close(); + return true; + } + } catch (Exception e) {} + System.out.println("No sequencer available! Cannot execute test."); + return false; + } +} --- /dev/null 2016-10-24 21:40:43.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/SequencerState.java 2016-10-24 21:40:43.000000000 +0300 @@ -0,0 +1,272 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; + +/** + * @test + * @bug 4913027 + * @summary several Sequencer methods should specify behaviour on closed Sequencer + */ +public class SequencerState { + + private static boolean hasSequencer() { + try { + Sequencer seq = MidiSystem.getSequencer(); + if (seq != null) { + seq.open(); + seq.close(); + return true; + } + } catch (Exception e) {} + System.out.println("No sequencer available! Cannot execute test."); + return false; + } + + + public static void main(String[] args) throws Exception { + out("4913027: several Sequencer methods should should specify behaviour on closed Sequencer"); + if (hasSequencer()) { + boolean passed = testAll(); + if (passed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + } + + /** + * Execute the test on all available Sequencers. + * + * @return true if the test passed for all Sequencers, false otherwise + */ + private static boolean testAll() throws Exception { + boolean result = true; + MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); + for (int i = 0; i < devices.length; i++) { + MidiDevice device = MidiSystem.getMidiDevice(devices[i]); + if (device instanceof Sequencer) { + result &= testSequencer((Sequencer) device); + } + } + return result; + } + + /** + * Execute the test on the passed Sequencer. + * + * @return true if the test is passed this Sequencer, false otherwise + */ + private static boolean testSequencer(Sequencer seq) throws Exception { + boolean result = true; + + out("testing: " + seq); + /* test calls in closed state. + */ + if (seq.isOpen()) { + out("Sequencer is already open, cannot test!"); + return result; + } + + try { + seq.start(); + out("closed state: start() does not throw IllegalStateException!"); + result = false; + } catch (IllegalStateException e) { + } + + try { + seq.stop(); + out("closed state: stop() does not throw IllegalStateException!"); + result = false; + } catch (IllegalStateException e) { + } + + try { + seq.startRecording(); + out("closed state: startRecording() does not throw IllegalStateException!"); + result = false; + } catch (IllegalStateException e) { + } + + try { + seq.stopRecording(); + out("closed state: stopRecording() does not throw IllegalStateException!"); + result = false; + } catch (IllegalStateException e) { + } + + Sequence sequence = createSequence(); + if (sequence == null) { + out("created Sequence is null, cannot test!"); + return result; + } + try { + seq.setSequence(sequence); + } catch (IllegalStateException e) { + out("closed state: setSequence(Sequence) throws IllegalStateException!"); + result = false; + } + + InputStream inputStream = createSequenceInputStream(); + if (inputStream == null) { + out("created InputStream is null, cannot test!"); + return result; + } + try { + seq.setSequence(inputStream); + } catch (IllegalStateException e) { + out("closed state: setSequence(InputStream) throws IllegalStateException!"); + result = false; + } + + try { + seq.getSequence(); + } catch (IllegalStateException e) { + out("closed state: getSequence() throws IllegalStateException!"); + result = false; + } + + /* test calls in open state. + */ + seq.open(); + if (! seq.isOpen()) { + out("Sequencer is not open, cannot test!"); + return result; + } + + try { + seq.start(); + } catch (IllegalStateException e) { + out("open state: start() throws IllegalStateException!"); + result = false; + } + + try { + seq.stop(); + } catch (IllegalStateException e) { + out("open state: stop() throws IllegalStateException!"); + result = false; + } + + try { + seq.startRecording(); + } catch (IllegalStateException e) { + out("open state: startRecording() throws IllegalStateException!"); + result = false; + } + + try { + seq.stopRecording(); + } catch (IllegalStateException e) { + out("open state: stopRecording() throws IllegalStateException!"); + result = false; + } + + sequence = createSequence(); + if (sequence == null) { + out("created Sequence is null, cannot test!"); + return result; + } + try { + seq.setSequence(sequence); + } catch (IllegalStateException e) { + out("open state: setSequence(Sequence) throws IllegalStateException!"); + result = false; + } + + inputStream = createSequenceInputStream(); + if (inputStream == null) { + out("created InputStream is null, cannot test!"); + return result; + } + try { + seq.setSequence(inputStream); + } catch (IllegalStateException e) { + out("open state: setSequence(InputStream) throws IllegalStateException!"); + result = false; + } + + try { + seq.getSequence(); + } catch (IllegalStateException e) { + out("open state: getSequence() throws IllegalStateException!"); + result = false; + } + + seq.close(); + return result; + } + + /** + * Create a new Sequence for testing. + * + * @return a dummy Sequence, or null, if a problem occured while creating + * the Sequence + */ + private static Sequence createSequence() { + Sequence sequence = null; + try { + sequence = new Sequence(Sequence.PPQ, 480, 1); + } catch (InvalidMidiDataException e) { + // DO NOTHING + } + return sequence; + } + + /** + * Create a new InputStream containing a Sequence for testing. + * + * @return an InputStream containing a dummy Sequence, or null, if a problem + * occured while creating the InputStream + */ + private static InputStream createSequenceInputStream() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Sequence sequence = createSequence(); + if (sequence == null) { + return null; + } + try { + MidiSystem.write(sequence, 0, baos); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + return bais; + } catch (IOException e) { + return null; + } + } + + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:40:44.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/SetTickPosition.java 2016-10-24 21:40:44.000000000 +0300 @@ -0,0 +1,139 @@ +/* + * 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.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4493775 + * @summary Sequncer method, setTickPosition(long) doesnot set the Tick position + */ +public class SetTickPosition { + private static boolean testPassed = true; + + public void runTest() + { + Sequencer theSequencer = null; + try + { + System.out.print("Getting Sequencer..."); + theSequencer = MidiSystem.getSequencer(); + System.out.println("got "+theSequencer); + + if(!(theSequencer.isOpen())) + { + System.out.println("Opening Sequencer..."); + theSequencer.open(); + + if(!(theSequencer.isOpen())) + { + System.out.println("Unable to open the Sequencer. Test NOT FAILED."); + return; + } + } + + System.out.println("theSequencer is open!\n"); + + System.out.println("Creating New Sequence..."); + Sequence theSequence = new Sequence(Sequence.PPQ, 120); + + System.out.println("Adding Track To Sequence..."); + Track theTrack = theSequence.createTrack(); + + int theChannel = 0; + + int theNote = 60; + int theVelocity = 100; + ShortMessage theShortMessage = new ShortMessage(); + + for (int tick=0; tick<2000; tick+=120) { + //System.out.println("Adding NOTE_ON To Track At Tick: " + tick + "...\n"); + theShortMessage.setMessage(ShortMessage.NOTE_ON, theChannel, theNote, theVelocity); + MidiEvent theMidiEvent = new MidiEvent(theShortMessage, tick); + theTrack.add(theMidiEvent); + + //System.out.println("Adding NOTE_OFF To Track At Tick: " + (tick+60) + "...\n"); + theShortMessage.setMessage(ShortMessage.NOTE_OFF, theChannel, theNote, theVelocity); + theMidiEvent = new MidiEvent(theShortMessage, tick+60); + theTrack.add(theMidiEvent); + } + theSequencer.setSequence(theSequence); + + float theTempoInBPM = 120; + theSequencer.setTempoInBPM(theTempoInBPM); + long theTickLengthOfSequence = theSequencer.getTickLength(); + System.out.println("Length Of Sequence In Ticks: " + theTickLengthOfSequence); + System.out.println("Sequence resolution: " + theSequencer.getSequence().getResolution()); + + theSequencer.start(); + for(long theTickPosition = 0; theTickPosition < theTickLengthOfSequence; theTickPosition += (theTickLengthOfSequence / 10)) + { + System.out.println("Now Setting Tick Position To: " + theTickPosition); + theSequencer.setTickPosition(theTickPosition); + + long theCurrentTickPosition = theSequencer.getTickPosition(); + long theCurrentMsPosition = (long) (theSequencer.getMicrosecondPosition()/1000); + System.out.println("IsRunning()=" + theSequencer.isRunning()); + System.out.println("Now Current Tick Position Is: " + theCurrentTickPosition); + //System.out.println("Now Current micro Position Is: " + theCurrentMsPosition); + System.out.println(""); + + try { + Thread.sleep(800); + } catch (InterruptedException ie) {} + + // last time, set tick pos to 0 + if (theTickPosition>0 && theTickPosition<(theTickLengthOfSequence / 10)) { + theTickPosition=(theTickLengthOfSequence / 10); + } + + // 30 = 1/4 * 120, the resolution of the sequence + if(Math.abs(theCurrentTickPosition - theTickPosition) > 30) { + System.out.println("theCurrentTickPosition != theTickPosition!"); + testPassed = false; + } + } + + } + catch (Exception ex) { ex.printStackTrace(); } + if (theSequencer != null) { + theSequencer.close(); + } + if (testPassed) { + System.out.println("Test Passed."); + } + } + + public static void main(String[] args) throws Exception { + SetTickPosition thisTest = new SetTickPosition(); + thisTest.runTest(); + if (!testPassed) { + throw new Exception("Test FAILED"); + } + } +} --- /dev/null 2016-10-24 21:40:45.000000000 +0300 +++ new/test/javax/sound/midi/Sequencer/TickLength.java 2016-10-24 21:40:45.000000000 +0300 @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2002, 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.midi.InvalidMidiDataException; +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4427890 + * @run main/othervm TickLength + * @summary Sequencer.getTickLength() and Sequence.getTickLength() report the + * wrong length + */ +public class TickLength implements MetaEventListener { + private Sequence theSequence; + private Sequencer theSequencer; + + public TickLength() { + this.initMidiCompoments(); + System.out.println("Got Sequencer "+theSequencer); + theSequence = this.generateSequence(); + try { + theSequencer.setSequence(theSequence); + } + catch(Exception e) { + System.out.println(this.getClass()+"\tCannot set sequence to sequencer ("+e+")"); + return; + } + } + + public void start() { + theSequencer.start(); + } + + /* + instantiate the necessary midi components + */ + private boolean initMidiCompoments() { + + + try { + theSequencer = MidiSystem.getSequencer(); + } + catch(Exception e) { + System.out.println(this.getClass()+"\tSequencer Device not supported"+e+")"); + return false; + } + + try { + theSequencer.open(); + } + catch(Exception e) { + System.out.println(this.getClass()+"Cannot open Sequencer Device"); + return false; + } + if(!theSequencer.addMetaEventListener(this)) { + System.out.println(this.getClass()+"\tCould not register MetaEventListener - there will be problems with scrolling! "); + return false; + } + return true; + } + + static int lastTick = 0; + + private Sequence generateSequence() { + MidiEvent dummyMidiEvent; + ShortMessage dummyShortMessage; + Sequence dummySequence = null; + Track[] allTracks ; + Track theTrack; + + try { + dummySequence = new Sequence(Sequence.PPQ,1500); + } + catch(InvalidMidiDataException e) { + System.out.println("O o "+e); + } + + dummySequence.createTrack(); + allTracks = dummySequence.getTracks(); + theTrack = allTracks[0]; + lastTick = 0; + for(int i=0;i<20; i++) { + theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_ON, 2, 30+i, 100,100+1000*i)); + theTrack.add(this.createMetaMidiEvent(1,"start",100+1000*i)); + lastTick = (1000*i)+600; + theTrack.add(this.createShortMidiEvent(ShortMessage.NOTE_OFF, 2, 30+i, 100, lastTick)); + theTrack.add(this.createMetaMidiEvent(1,"end",lastTick)); + } + + return dummySequence; + } + + /* + A method to create a short midi event (sound) + */ + + public MidiEvent createShortMidiEvent(int theCommand, int theChannel, int theData1, int theData2, long theTime) { + ShortMessage dummyShortMessage; + MidiEvent dummyMidiEvent; + + try { + dummyShortMessage = new ShortMessage(); + dummyShortMessage.setMessage(theCommand, theChannel, theData1, theData2); + dummyMidiEvent = new MidiEvent(dummyShortMessage,theTime); + } + catch (Exception e) { + System.out.println(this.getClass()+"\t"+e); + return null; + } + + return dummyMidiEvent; + } + + /* + A method to create a meta midi event (used in meta() method) + */ + public MidiEvent createMetaMidiEvent(int theType, String theData1, long theTime) { + MetaMessage dummyMetaMessage; + MidiEvent dummyMidiEvent; + + try { + dummyMetaMessage = new MetaMessage(); + dummyMetaMessage.setMessage(theType, theData1.getBytes(), theData1.length()); + dummyMidiEvent = new MidiEvent(dummyMetaMessage,theTime); + } + catch (Exception e) { + System.out.println(e); + return null; + } + + return dummyMidiEvent; + } + + /* + the method is activated by each meta midi event + it puts out the actual tick position, as well as the WRONG total tick length and the RIGHT + tick length using the work around by dividing the total length by 64 + */ + public void meta(MetaMessage p1) { + if(p1.getType() ==47) { + return; + } + System.out.println("getTickPosition:\t"+theSequencer.getTickPosition() + +"\t Sequencer.getTickLength:\t"+theSequencer.getTickLength() + +"\tReal Length:\t"+lastTick + +"\t Sequence.getTickLength:\t"+theSequence.getTickLength() + //(theSequencer.getTickLength()/64)); + ); + } + + public void checkLengths() throws Exception { + System.out.println("Sequencer.getTickLength() = "+theSequencer.getTickLength()); + System.out.println("Sequence.getTickLength() = "+theSequence.getTickLength()); + long diff = theSequencer.getTickLength() - theSequence.getTickLength(); + if (diff > 100 || diff < -100) { + throw new Exception("Difference too large! Failed."); + } + System.out.println("Passed"); + } + + public static void main(String[] args) throws Exception { + if (!hasSequencer()) { + return; + } + TickLength tlt = new TickLength(); + //tlt.start(); + tlt.checkLengths(); + } + + static boolean hasSequencer() { + try { + Sequencer seq = MidiSystem.getSequencer(); + if (seq != null) { + seq.open(); + seq.close(); + return true; + } + } catch (Exception e) {} + System.out.println("No sequencer available! Cannot execute test."); + return false; + } + +} --- /dev/null 2016-10-24 21:40:46.000000000 +0300 +++ new/test/javax/sound/midi/ShortMessage/FastShortMessage.java 2016-10-24 21:40:45.000000000 +0300 @@ -0,0 +1,71 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4851018 + * @summary MidiMessage.getLength and .getData return wrong values. + * also: 4890405: Reading MidiMessage byte array fails in 1.4.2 + */ +public class FastShortMessage { + public static void main(String args[]) throws Exception { + int[] dataMes = {ShortMessage.NOTE_ON | 9, 0x24, 0x50}; + int res = 240; + Sequence midiData = new Sequence(Sequence.PPQ, res); + + Track track = midiData.createTrack(); + ShortMessage msg = new ShortMessage(); + msg.setMessage(dataMes[0], dataMes[1], dataMes[2]); + track.add(new MidiEvent(msg, 0)); + + // save sequence to outputstream + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + MidiSystem.write(midiData, 0, baos); + + // reload that sequence + InputStream is = new ByteArrayInputStream(baos.toByteArray()); + Sequence seq = MidiSystem.getSequence(is); + + track = seq.getTracks()[0]; + msg = (ShortMessage) (track.get(0).getMessage()); + byte[] msgData = msg.getMessage(); + + if (msgData.length != dataMes.length + || (msgData[0] & 0xFF) != dataMes[0] + || (msgData[1] & 0xFF) != dataMes[1] + || (msgData[2] & 0xFF) != dataMes[2]) { + throw new Exception("test failed. read length="+msgData.length); + } + System.out.println("Test Passed."); + } +} --- /dev/null 2016-10-24 21:40:46.000000000 +0300 +++ new/test/javax/sound/midi/ShortMessage/FastShortMessage2.java 2016-10-24 21:40:46.000000000 +0300 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2004, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.midi.MidiEvent; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 5011306 + * @summary FastShortMessage.setMessage does not use the data2 parameter + */ +public class FastShortMessage2 { + + public static void main(String args[]) throws Exception { + int[] dataMes = {ShortMessage.NOTE_ON | 9, 0x24, 0x50}; + + Sequence midiData = new Sequence(Sequence.PPQ, 240); + Track track = midiData.createTrack(); + ShortMessage msg = new ShortMessage(); + msg.setMessage(dataMes[0], dataMes[1], dataMes[2]); + track.add(new MidiEvent(msg, 0)); + // save sequence to outputstream + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + MidiSystem.write(midiData, 0, baos); + // reload that sequence + InputStream is = new ByteArrayInputStream(baos.toByteArray()); + Sequence seq = MidiSystem.getSequence(is); + track = seq.getTracks()[0]; + msg = (ShortMessage) (track.get(0).getMessage()); + if (!msg.getClass().toString().contains("FastShortMessage")) { + System.out.println("msg is not FastShortMessage, this test is useless then..."+msg.getClass()); + } + + msg.setMessage(dataMes[0], dataMes[1], dataMes[2]); + byte[] msgData = msg.getMessage(); + + if (msgData.length != dataMes.length + || (msgData[0] & 0xFF) != dataMes[0] + || (msgData[1] & 0xFF) != dataMes[1] + || (msgData[2] & 0xFF) != dataMes[2]) { + System.out.println("status="+(msgData[0] & 0xFF)+" and expected "+dataMes[0]); + System.out.println("data1="+(msgData[1] & 0xFF)+" and expected "+dataMes[1]); + System.out.println("data2="+(msgData[2] & 0xFF)+" and expected "+dataMes[2]); + throw new Exception("Test FAILED!"); + } + System.out.println("Test Passed."); + } +} --- /dev/null 2016-10-24 21:40:47.000000000 +0300 +++ new/test/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java 2016-10-24 21:40:47.000000000 +0300 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2002, 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.midi.Instrument; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Soundbank; +import javax.sound.midi.Synthesizer; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4429762 + * @summary Some instrument names in some soundbanks include bad extra characters + */ +public class ExtraCharInSoundbank { + + private static void printName(String loadedName) + { + System.out.println("Loaded Name: " + loadedName); + byte[] theLoadedNameByteArray = loadedName.getBytes(); + + System.out.print("Name Bytes: "); + for(int i = 0; i < theLoadedNameByteArray.length; i++) + System.out.print((Integer.toHexString((int)theLoadedNameByteArray[i]).toUpperCase()) + " "); + System.out.println(""); + System.out.println(""); + } + + private static boolean containsControlChar(String name) { + byte[] bytes = name.getBytes(); + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] < 32) { + return true; + } + } + return false; + } + + public static boolean checkInstrumentNames(Synthesizer theSynthesizer) + { + boolean containsControlCharacters = false; + + Instrument[] theLoadedInstruments = theSynthesizer.getLoadedInstruments(); + + System.out.println("Checking soundbank..."); + for(int theInstrumentIndex = 0; theInstrumentIndex < theLoadedInstruments.length; theInstrumentIndex++) { + String name = theLoadedInstruments[theInstrumentIndex].getName(); + if (containsControlChar(name)) { + containsControlCharacters = true; + System.out.print("Instrument[" + theInstrumentIndex + "] contains unexpected control characters: "); + printName(name); + } + } + return !containsControlCharacters; + } + + public static void main(String[] args) throws Exception { + // the internal synthesizer needs a soundcard to work properly + if (!isSoundcardInstalled()) { + return; + } + Synthesizer theSynth = MidiSystem.getSynthesizer(); + System.out.println("Got synth: "+theSynth); + theSynth.open(); + try { + Soundbank theSoundbank = theSynth.getDefaultSoundbank(); + System.out.println("Got soundbank: "+theSoundbank); + theSynth.loadAllInstruments(theSoundbank); + try { + if (!checkInstrumentNames(theSynth)) { + throw new Exception("Test failed"); + } + } finally { + theSynth.unloadAllInstruments(theSoundbank); + } + } finally { + theSynth.close(); + } + System.out.println("Test passed."); + } + + /** + * Returns true if at least one soundcard is correctly installed + * on the system. + */ + public static boolean isSoundcardInstalled() { + boolean result = false; + try { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + if (mixers.length > 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:40:48.000000000 +0300 +++ new/test/javax/sound/midi/Soundbanks/GetSoundBankIOException.java 2016-10-24 21:40:47.000000000 +0300 @@ -0,0 +1,85 @@ +/* + * 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.io.IOException; +import java.io.InputStream; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MidiSystem; + +/** + * @test + * @bug 4629810 + * @summary MidiSystem.getSoundbank() throws unexpected IOException + */ +public class GetSoundBankIOException { + + public static void main(String args[]) throws Exception { + boolean failed = false; + try { + String filename = "GetSoundBankIOException.java"; + System.out.println("Opening "+filename+" as soundbank..."); + File midiFile = new File(System.getProperty("test.src", "."), filename); + MidiSystem.getSoundbank(midiFile); + //Soundbank sBank = MidiSystem.getSoundbank(new NonMarkableIS()); + System.err.println("InvalidMidiDataException was not thrown!"); + failed = true; + } catch (InvalidMidiDataException invMidiEx) { + System.err.println("InvalidMidiDataException was thrown. OK."); + } catch (IOException ioEx) { + System.err.println("Unexpected IOException was caught!"); + System.err.println(ioEx.getMessage()); + ioEx.printStackTrace(); + failed = true; + } + + if (failed) throw new Exception("Test FAILED!"); + System.out.println("Test passed."); + } + + private static class NonMarkableIS extends InputStream { + int counter = 0; + + public NonMarkableIS() { + } + + public int read() throws IOException { + if (counter > 1000) return -1; + return (++counter) % 256; + } + + public synchronized void mark(int readlimit) { + System.out.println("Called mark with readlimit= "+readlimit); + } + + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + public boolean markSupported() { + return false; + } + + } +} --- /dev/null 2016-10-24 21:40:48.000000000 +0300 +++ new/test/javax/sound/midi/Synthesizer/AsynchronousMidiChannel.java 2016-10-24 21:40:48.000000000 +0300 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2004, 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.PrintStream; + +import javax.sound.midi.Instrument; +import javax.sound.midi.MidiChannel; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Soundbank; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4987585 + * @summary Some MidiChannel methods are asynchronous + */ +public class AsynchronousMidiChannel { + static PrintStream log = System.err; + static PrintStream ref = System.out; + + public static void main(String args[]) { + doIt(args); + } + + public static void doIt(String args[]) { + Synthesizer synth = null; + MidiChannel mChanArr[]; + MidiChannel chan = null; + boolean failed = false; + int i = 0; + int chanNum = 0; + + int val = 1; + int contr = 0; + Soundbank sBank; + Instrument[] insArr; + Instrument instr = null; + Object ev = new Object(); + + try { + synth = MidiSystem.getSynthesizer(); + System.out.println("Got synth: "+synth); + synth.open(); + + int latency = (int) synth.getLatency(); + System.out.println(" -> latency: " + +latency + +" microseconds"); + + mChanArr = synth.getChannels(); + while ((i < mChanArr.length) && (chan == null)) { + chanNum = i; + chan = mChanArr[i++]; + } + if (chan == null) { + System.out.println("No channels in " + +"this synthesizer!"); + return; + } + System.out.println("Got MidiChannel: "+chan); + + + sBank = synth.getDefaultSoundbank(); + if (sBank == null) { + System.out.println("No default sound bank!"); + return; + } + + + insArr = sBank.getInstruments(); + for (int j = 0; j < insArr.length; j++) { + if (insArr[j].getPatch().getBank() == val) { + instr = insArr[j]; + synth.loadInstrument(instr); + } + } + if (instr == null) { + System.out.println("No instr. with this bank!"); + return; + } + + chan.controlChange(contr, val); + + // need to respect the synthesizer's latency + if (latency > 0) { + try { + Thread.sleep(latency/1000); + } catch (InterruptedException inEx) { + } + } + + if (chan.getController(contr) != val) { + failed = true; + System.err.println("getController() does not " + +"return proper value: " + + chan.getController(contr)); + } else { + System.out.println("getController(" + + contr + ") returns proper value: " + + chan.getController(contr)); + } + + } catch (MidiUnavailableException mue) { + System.err.println("MidiUnavailableException was " + +"thrown: " + mue); + System.out.println("could not test."); + return; + } catch(SecurityException se) { + se.printStackTrace(); + System.err.println("Sound access is not denied but " + + "SecurityException was thrown!"); + return; + + } finally { + if (synth != null) synth.close(); + } + + + if (failed == true) { + System.out.println("test failed"); + } else { + System.out.println("OKAY"); + } + return; + } +} --- /dev/null 2016-10-24 21:40:49.000000000 +0300 +++ new/test/javax/sound/midi/Synthesizer/Receiver/bug6186488.java 2016-10-24 21:40:49.000000000 +0300 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005, 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.midi.MidiDevice; +import javax.sound.midi.MidiMessage; +import javax.sound.midi.MidiSystem; + +/** + * @test + * @bug 6186488 + * @summary Tests that software Java Syntesizer processed + * non-ShortMessage-derived messages + * @run main/manual=yesno bug6186488 + */ +public class bug6186488 { + public static void main(String[] args) throws Exception { + MidiDevice/*Synthesizer*/ synth = null; + + try { + synth = MidiSystem.getSynthesizer(); + //synth = MidiSystem.getMidiDevice(infos[0]); + + System.out.println("Synthesizer: " + synth.getDeviceInfo()); + synth.open(); + MidiMessage msg = new GenericMidiMessage(0x90, 0x3C, 0x40); + //ShortMessage msg = new ShortMessage(); + //msg.setMessage(0x90, 0x3C, 0x40); + + synth.getReceiver().send(msg, 0); + Thread.sleep(2000); + + } catch (Exception ex) { + ex.printStackTrace(); + throw ex; + } finally { + if (synth != null && synth.isOpen()) + synth.close(); + } + System.out.print("Did you heard a note? (enter 'y' or 'n') "); + int result = System.in.read(); + System.in.skip(1000); + if (result == 'y' || result == 'Y') + { + System.out.println("Test passed sucessfully."); + } + else + { + System.out.println("Test FAILED."); + throw new RuntimeException("Test failed."); + } + } + + private static class GenericMidiMessage extends MidiMessage { + GenericMidiMessage(int... message) { + super(new byte[message.length]); + for (int i=0; i latency: " + +latency + +" microseconds"); + if (latency < 5000 && latency > 0) { + System.out.println("## This latency is VERY small, probably due to this bug."); + System.out.println("## This causes failure of this test."); + failed = true; + } + } catch (MidiUnavailableException mue) { + System.err.println("MidiUnavailableException was " + +"thrown: " + mue); + System.out.println("could not test."); + notexec = true; + } catch(SecurityException se) { + se.printStackTrace(); + System.err.println("Sound access is not denied but " + + "SecurityException was thrown!"); + notexec = true; + } finally { + if (synth != null) synth.close(); + } + + + if (failed) { + throw new Exception("Test FAILED!"); + } + if (notexec) { + System.out.println("Test not failed."); + } else { + System.out.println("Test Passed."); + } + } +} --- /dev/null 2016-10-24 21:40:51.000000000 +0300 +++ new/test/javax/sound/midi/Synthesizer/bug4685396.java 2016-10-24 21:40:50.000000000 +0300 @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2006, 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.midi.Instrument; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.Soundbank; +import javax.sound.midi.Synthesizer; + +/** + * @test + * @bug 4685396 + * @summary Tests that Synthesizer.remapInstrument works + * @run main bug4685396 + * @key headful + */ +public class bug4685396 { + + static Synthesizer synth = null; + + public static boolean isInstrumentExist(Instrument inst, Instrument[] insts) { + for (int i = 0; i < insts.length; i++) { + if (inst.equals(insts[i])) + return true; + } + return false; + } + + static boolean test( + boolean reloadInstr, // reload all instruments? + boolean unloadFrom, // unload "from" instrument? + boolean unloadTo // unload "to" instrument? + ) throws Exception + { + log("Starting test: reloadInstr=" + reloadInstr + + ", unloadFrom=" + unloadFrom + + ", unloadTo=" + unloadTo + + ""); + + log(" creating synthesizer..."); + synth = MidiSystem.getSynthesizer(); + log(" opening synthesizer..."); + synth.open(); + + Soundbank sbank = synth.getDefaultSoundbank(); + if (sbank == null) + throw new RuntimeException("ERROR: Could not get default soundbank"); + + if (reloadInstr) { + synth.unloadAllInstruments(sbank); + synth.loadAllInstruments(sbank); + } + + Instrument[] instrs = synth.getLoadedInstruments(); + + log(" " + instrs.length + " instruments loaded."); + + if (instrs.length < 2) + throw new RuntimeException("ERROR: need at least 2 loaded instruments"); + + Instrument from = instrs[0]; + Instrument to = instrs[instrs.length - 1]; + + if (unloadFrom) + synth.unloadInstrument(from); + if (unloadTo) + synth.unloadInstrument(to); + + log(" from instrument (" + (unloadFrom ? "UNLOADED" : "LOADED") + + "): " + from.toString()); + log(" to instrument (" + (unloadTo ? "UNLOADED" : "LOADED") + + "): " + to.toString()); + + boolean result = false; + boolean excepted = false; + try { + result = synth.remapInstrument(from, to); + log(" remapInstrument(from, to) returns " + result); + } catch (IllegalArgumentException ex) { + excepted = true; + log(" EXCEPTION:"); + ex.printStackTrace(System.out); + } + + instrs = synth.getLoadedInstruments(); + log(" " + instrs.length + " instruments remains loaded."); + + boolean toUnloaded = !isInstrumentExist(to, instrs); + boolean fromUnloaded = !isInstrumentExist(from, instrs); + + log(" from instrument is " + (fromUnloaded ? "UNLOADED" : "LOADED")); + log(" to instrument is " + (toUnloaded ? "UNLOADED" : "LOADED")); + + boolean bOK = true; + if (result) { + if (unloadTo) { + bOK = false; + log("ERROR: unloaded to, but sucessfull remap"); + } + if (!fromUnloaded) { + bOK = false; + log("ERROR: sucessfull remap, but from hasn't been unloaded"); + } + if (toUnloaded) { + bOK = false; + log("ERROR: to has been unloaded!"); + } + } else { + if (!excepted) { + bOK = false; + log("ERROR: remap returns false, exception hasn't been thrown"); + } + if (!unloadTo) { + bOK = false; + log("ERROR: to is loaded, but remap returns false"); + } + if (unloadFrom != fromUnloaded) { + bOK = false; + log("ERROR: remap returns false, but status of from has been changed"); + } + } + + if (bOK) { + log("Test result: OK\n"); + } else { + log("Test result: FAIL\n"); + } + + return bOK; + } + + static void cleanup() { + if (synth != null) { + synth.close(); + synth = null; + } + } + + static boolean runTest( + boolean reloadInstr, // reload all instruments? + boolean unloadTo, // unload "to" instrument? + boolean unloadFrom // unload "from" instrument? + ) + { + boolean success = false; + try { + success = test(reloadInstr, unloadFrom, unloadTo); + } catch (Exception ex) { + log("Exception: " + ex.toString()); + } + cleanup(); + return success; + } + + public static void main(String args[]) throws Exception { + boolean failed = false; + if (!runTest(true, false, false)) + failed = true; + if (!runTest(true, false, true)) + failed = true; + if (!runTest(true, true, false)) + failed = true; + if (!runTest(true, true, true)) + failed = true; + + if (failed) { + throw new RuntimeException("Test FAILED."); + } + log("Test sucessfully passed."); + } + + + // helper routines + static long startTime = currentTimeMillis(); + static long currentTimeMillis() { + //return System.nanoTime() / 1000000L; + return System.currentTimeMillis(); + } + static void log(String s) { + long time = currentTimeMillis() - startTime; + long ms = time % 1000; + time /= 1000; + long sec = time % 60; + time /= 60; + long min = time % 60; + time /= 60; + System.out.println("" + + (time < 10 ? "0" : "") + time + + ":" + (min < 10 ? "0" : "") + min + + ":" + (sec < 10 ? "0" : "") + sec + + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms + + " (" + Thread.currentThread().getName() + ") " + s); + } + static void delay(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) {} + } +} --- /dev/null 2016-10-24 21:40:51.000000000 +0300 +++ new/test/javax/sound/midi/Track/TrackAddSameTick.java 2016-10-24 21:40:51.000000000 +0300 @@ -0,0 +1,97 @@ +/* + * 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.midi.MidiEvent; +import javax.sound.midi.Sequence; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Track; + +/** + * @test + * @bug 4941944 + * @summary Track may not have a determined order for inserting events at same + * tick time + */ +public class TrackAddSameTick { + + static boolean failed = false; + static MidiEvent[] evs = new MidiEvent[10]; + + public static void main(String argv[]) throws Exception { + Sequence seq = new Sequence(Sequence.PPQ, 240); + Track t = seq.createTrack(); + + log("add 10 events in random order"); + t.add(createEvent(10, 5)); + t.add(createEvent(0, 0)); + t.add(createEvent(10, 6)); + t.add(createEvent(11, 8)); + t.add(createEvent(10, 7)); + t.add(createEvent(0, 1)); + t.add(createEvent(0, 2)); + t.add(createEvent(15, 9)); + t.add(createEvent(0, 3)); + t.add(createEvent(1, 4)); + + // now compare the events. + // The note param will tell us the + // the expected position + long lastTick = 0; + for (int i = 0; i < t.size(); i++) { + MidiEvent ev = t.get(i); + if (ev.getMessage() instanceof ShortMessage) { + ShortMessage msg = (ShortMessage) ev.getMessage(); + log(""+i+": ShortMessage at tick "+ev.getTick() + +" with expected position "+msg.getData1()); + if (ev.getTick() < lastTick) { + log(" FAILED: last tick is larger than this event's tick!"); + failed = true; + } + if (i != msg.getData1()) { + log(" FAILED: Track did not order correctly."); + failed = true; + } + } + } + + if (failed) throw new Exception("Test FAILED!"); + log("Test passed."); + } + + public static MidiEvent createEvent(long tick, int expectedPos) + throws Exception { + ShortMessage msg = new ShortMessage(); + msg.setMessage(0x90, (int) expectedPos, 00); + MidiEvent ev = new MidiEvent(msg, tick); + return ev; + } + + public static void log(String s) { + System.out.println(s); + } + + public static void log(Exception e) { + //System.out.println(s); + e.printStackTrace(); + } +} --- /dev/null 2016-10-24 21:40:52.000000000 +0300 +++ new/test/javax/sound/midi/Track/bug6416024.java 2016-10-24 21:40:52.000000000 +0300 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2006, 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.midi.InvalidMidiDataException; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiEvent; +import javax.sound.midi.Sequence; +import javax.sound.midi.Track; + +/** + * @test + * @bug 6416024 + * @summary Tests that sequence correctly handle removing of EndOfTrack event + * @run main bug6416024 + */ +public class bug6416024 { + + boolean test() { + Sequence sequence = null; + Track track = null; + MidiEvent event = null; + + log("creating sequence..."); + try { + sequence = new Sequence(Sequence.PPQ, 10); + log(" - OK: " + sequence); + } catch(InvalidMidiDataException e ) { + log(" - FAILED: got exception"); + e.printStackTrace(System.out); + return false; + } + + log("creating track..."); + track = sequence.createTrack(); + log(" - OK: " + track); + log("initial track size=" + track.size()); + + log("removing all track events..."); + while (track.size() > 0) { + try { + event = track.get(0); + log(" ..removing event " + event); + track.remove(event); + log(" - OK, track size=" + track.size()); + } catch (Exception e) { + log(" - FAILED: got exception"); + e.printStackTrace(System.out); + return false; + } + } + + MetaMessage newMsg = new MetaMessage(); + MidiEvent newEvent = new MidiEvent(newMsg, 10); + log("adding new event..."); + try { + if (!track.add(newEvent)) { + log("event hasn't been added"); + return false; + } + log(" - OK, track size=" + track.size()); + } catch (Exception e) { + log(" - FAILED: got exception"); + e.printStackTrace(System.out); + return false; + } + + return true; + } + + public static void main(String args[]) throws Exception { + bug6416024 This = new bug6416024(); + if (This.test()) { + log("Test passed sucessfully."); + } else { + log("Test FAILED!"); + delay(1000); + throw new RuntimeException("Test failed!"); + } + } + + // helper routines + static long startTime = currentTimeMillis(); + static long currentTimeMillis() { + //return System.nanoTime() / 1000000L; + return System.currentTimeMillis(); + } + static void log(String s) { + long time = currentTimeMillis() - startTime; + long ms = time % 1000; + time /= 1000; + long sec = time % 60; + time /= 60; + long min = time % 60; + time /= 60; + System.out.println("" + + (time < 10 ? "0" : "") + time + + ":" + (min < 10 ? "0" : "") + min + + ":" + (sec < 10 ? "0" : "") + sec + + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms + + " (" + Thread.currentThread().getName() + ") " + s); + } + static void delay(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) {} + } +} --- /dev/null 2016-10-24 21:40:53.000000000 +0300 +++ new/test/javax/sound/midi/Transmitter/bug6415669.java 2016-10-24 21:40:52.000000000 +0300 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2006, 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.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Transmitter; + +/** + * @test + * @bug 6415669 + * @summary Tests that terminating thread which got transmitter doesn't cause + * JVM crash (windows) + * @run main bug6415669 + */ +public class bug6415669 { + + public static void main(String args[]) throws Exception { + String osStr = System.getProperty("os.name"); + boolean isWin = osStr.toLowerCase().startsWith("windows"); + log("OS: " + osStr); + log("Arch: " + System.getProperty("os.arch")); + if (!isWin) { + log("The test is for Windows only"); + return; + } + + bug6415669 This = new bug6415669(); + if (This.test()) { + log("Test sucessfully passed."); + } else { + log("Test FAILED!"); + throw new RuntimeException("Test FAILED!"); + } + } + + volatile Transmitter transmitter = null; + Thread openThread = null; + boolean test() { + openThread = new Thread(new Runnable() { + public void run() { + try { + log("openThread: getting transmitter..."); + transmitter = MidiSystem.getTransmitter(); + log("openThread: - OK: " + transmitter); + } catch (MidiUnavailableException ex) { + log("openThread: - Exception: "); + ex.printStackTrace(System.out); + log("openThread: skipping..."); + } + log("openThread: exiting..."); + } + }); + log("starting openThread..."); + openThread.start(); + + while (openThread.isAlive()) + delay(500); + // make additional delay + delay(500); + + if (transmitter == null) { + return true; // midi is not available, just ignore + } + + log("closing transmitter"); + transmitter.close(); + log(" - OK"); + + return true; + } + + // helper routines + static long startTime = currentTimeMillis(); + static long currentTimeMillis() { + //return System.nanoTime() / 1000000L; + return System.currentTimeMillis(); + } + static void log(String s) { + long time = currentTimeMillis() - startTime; + long ms = time % 1000; + time /= 1000; + long sec = time % 60; + time /= 60; + long min = time % 60; + time /= 60; + System.out.println("" + + (time < 10 ? "0" : "") + time + + ":" + (min < 10 ? "0" : "") + min + + ":" + (sec < 10 ? "0" : "") + sec + + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms + + " (" + Thread.currentThread().getName() + ") " + s); + } + static void delay(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) {} + } +} --- /dev/null 2016-10-24 21:40:53.000000000 +0300 +++ new/test/javax/sound/sampled/AudioFileFormat/AudioFileFormatToString.java 2016-10-24 21:40:53.000000000 +0300 @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2002, 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.AudioFileFormat; +import javax.sound.sampled.AudioFormat; + +/** + * @test + * @bug 4672864 + * @summary AudioFileFormat.toString() throws unexpected NullPointerException + */ +public class AudioFileFormatToString { + + static final int STATUS_PASSED = 0; + static final int STATUS_FAILED = 2; + static final int STATUS_TEMP = 95; + + public static void main(String argv[]) throws Exception { + int testExitStatus = run(argv, System.out); + if (testExitStatus != STATUS_PASSED) { + throw new Exception("Test FAILED " + testExitStatus); + } + System.out.println("Test passed."); + } + + public static int run(String argv[], java.io.PrintStream out) { + int testResult = STATUS_PASSED; + + out.println("\n==> Test for AudioFileFormat class:"); + + AudioFormat testAudioFormat = + new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, // AudioFormat.Encoding + (float) 44100.0, // float SampleRate + (int) 8, // int sampleSizeInBits + (int) 2, // int channels + (int) 2, // int frameSize + (float) 110.0, // float frameRate + true // boolean bigEndian + ); + AudioFormat nullAudioFormat = null; + + AudioFileFormat.Type testAudioFileFormatType = AudioFileFormat.Type.WAVE; + AudioFileFormat.Type nullAudioFileFormatType = null; + + AudioFileFormat testedAudioFileFormat = null; + out.println("\n>> public AudioFileFormat constructor for AudioFileFormat.Type = null: "); + try { + testedAudioFileFormat = + new AudioFileFormat(nullAudioFileFormatType, // AudioFileFormat.Type + testAudioFormat, // AudioFormat + (int) 1024 // int frameLength + ); + out.println("> No any Exception was thrown!"); + out.println("> testedAudioFileFormat.getType():"); + try { + AudioFileFormat.Type producedType = testedAudioFileFormat.getType(); + out.println("> PASSED: producedType = " + producedType); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + out.println("> testedAudioFileFormat.toString():"); + try { + String producedString = testedAudioFileFormat.toString(); + out.println("> PASSED: producedString = " + producedString); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + } catch (IllegalArgumentException illegArgExcept) { + out.println("> PASSED: expected IllegalArgumentException was thrown:"); + illegArgExcept.printStackTrace(out); + } catch (NullPointerException nullPE) { + out.println("> PASSED: expected NullPointerException was thrown:"); + nullPE.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println("\n>> public AudioFileFormat constructor for AudioFormat = null: "); + try { + testedAudioFileFormat = + new AudioFileFormat(testAudioFileFormatType, // AudioFileFormat.Type + nullAudioFormat, // AudioFormat + (int) 1024 // int frameLength + ); + out.println("> No any Exception was thrown!"); + out.println("> testedAudioFileFormat.getFormat():"); + try { + AudioFormat producedFormat = testedAudioFileFormat.getFormat(); + out.println("> PASSED: producedFormat = " + producedFormat); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + out.println("> testedAudioFileFormat.toString():"); + try { + String producedString = testedAudioFileFormat.toString(); + out.println("> PASSED: producedString = " + producedString); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + } catch (IllegalArgumentException illegArgExcept) { + out.println("> PASSED: expected IllegalArgumentException was thrown:"); + illegArgExcept.printStackTrace(out); + } catch (NullPointerException nullPE) { + out.println("> PASSED: expected NullPointerException was thrown:"); + nullPE.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println("\n>> protected AudioFileFormat constructor for AudioFileFormat.Type = null: "); + try { + testedAudioFileFormat = + new TestAudioFileFormat(nullAudioFileFormatType, // AudioFileFormat.Type + (int) 1024, // byteLength + testAudioFormat, // AudioFormat + (int) 1024 // int frameLength + ); + out.println("> No any Exception was thrown!"); + out.println("> testedAudioFileFormat.getType():"); + try { + AudioFileFormat.Type producedType = testedAudioFileFormat.getType(); + out.println("> PASSED: producedType = " + producedType); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + out.println("> testedAudioFileFormat.toString():"); + try { + String producedString = testedAudioFileFormat.toString(); + out.println("> PASSED: producedString = " + producedString); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + } catch (IllegalArgumentException illegArgExcept) { + out.println("> PASSED: expected IllegalArgumentException was thrown:"); + illegArgExcept.printStackTrace(out); + } catch (NullPointerException nullPE) { + out.println("> PASSED: expected NullPointerException was thrown:"); + nullPE.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println("\n>> protected AudioFileFormat constructor for AudioFormat = null: "); + try { + testedAudioFileFormat = + new TestAudioFileFormat(testAudioFileFormatType, // AudioFileFormat.Type + (int) 1024, // byteLength + nullAudioFormat, // AudioFormat + (int) 1024 // int frameLength + ); + out.println("> No any Exception was thrown!"); + out.println("> testedAudioFileFormat.getFormat():"); + try { + AudioFormat producedFormat = testedAudioFileFormat.getFormat(); + out.println("> PASSED: producedFormat = " + producedFormat); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + out.println("> testedAudioFileFormat.toString():"); + try { + String producedString = testedAudioFileFormat.toString(); + out.println("> PASSED: producedString = " + producedString); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + } catch (IllegalArgumentException illegArgExcept) { + out.println("> PASSED: expected IllegalArgumentException was thrown:"); + illegArgExcept.printStackTrace(out); + } catch (NullPointerException nullPE) { + out.println("> PASSED: expected NullPointerException was thrown:"); + nullPE.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + if (testResult == STATUS_FAILED) { + out.println("\n==> test FAILED!"); + } else { + out.println("\n==> test PASSED!"); + } + return testResult; + } +} + +class TestAudioFileFormat extends AudioFileFormat { + + TestAudioFileFormat(AudioFileFormat.Type type, int byteLength, + AudioFormat format, int frameLength) { + super(type, byteLength, format, frameLength); + } +} --- /dev/null 2016-10-24 21:40:54.000000000 +0300 +++ new/test/javax/sound/sampled/AudioFileFormat/Properties.java 2016-10-24 21:40:54.000000000 +0300 @@ -0,0 +1,144 @@ +/* + * 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.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.sound.midi.MidiFileFormat; +import javax.sound.midi.Sequence; +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; + +/** + * @test + * @bug 4666845 + * @summary RFE: Add properties to AudioFileFormat and MidiFileFormat + */ +public class Properties { + + static boolean g_failed = false; + + // all of p1 need to be in p2 + static boolean compare(Map p1, Map p2) { + boolean failed = false; + for(String key: (Set) p1.keySet()) { + out(" testing key: "+key); + if (!p2.containsKey(key)) { + out(" missing property: '"+key+"'. Failed"); + failed = true; + } + Object v1 = p1.get(key); + Object v2 = p2.get(key); + if (((v1 == null) && (v2 != null)) + || ((v1 != null) && (v2 == null)) + || !(v1.equals(v2))) { + out(" property '"+key+"' is different: " + +"expected='"+v1+"' " + +"actual='"+v2+"'. Failed"); + failed = true; + } + } + // test if we can modify p2 + try { + int oldSize = p2.size(); + p2.clear(); + if (oldSize > 0 && p2.size() == 0) { + out(" could clear the properties! Failed."); + failed = true; + } + } catch (Exception e) { + // correct + } + return failed; + } + + public static void main(String argv[]) throws Exception { + // don't need to catch exceptions: any exception is a + // failure of this test + + Map p = new HashMap(); + p.put("author", "Florian"); + p.put("duration", new Long(1000)); + p.put("MyProp", "test"); + + out("Testing AudioFileFormat properties:"); + // create an AudioFileFormat with properties + AudioFormat format = new AudioFormat( 44100.0f, 16, 2, true, false); + AudioFileFormat aff = + new AudioFileFormat(AudioFileFormat.Type.WAVE, + format, 1000, p); + // test that it has the properties + boolean failed = compare(p, aff.properties()); + // test getProperty() + Object o = aff.getProperty("author"); + if (o == null || !o.equals("Florian")) { + out(" getProperty did not report an existing property!"); + failed = true; + } + o = aff.getProperty("does not exist"); + if (o != null) { + out(" getProperty returned something for a non-existing property!"); + failed = true; + } + if (!failed) { + out(" OK"); + } else { + g_failed = true; + } + + + + out("Testing MidiFileFormat properties:"); + // create a MidiFileFormat with properties + MidiFileFormat mff = + new MidiFileFormat(0, Sequence.PPQ, 240, + 1000, 100, p); + // test that it has the properties + failed = compare(p, mff.properties()); + // test getProperty() + o = mff.getProperty("author"); + if (o == null || !o.equals("Florian")) { + out(" getProperty did not report an existing property!"); + failed = true; + } + o = mff.getProperty("does not exist"); + if (o != null) { + out(" getProperty returned something for a non-existing property!"); + failed = true; + } + if (!failed) { + out(" OK"); + } else { + g_failed = true; + } + + + if (g_failed) throw new Exception("Test FAILED!"); + System.out.println("Test passed."); + } + + static void out(String s) { + System.out.println(s); + } +} --- /dev/null 2016-10-24 21:40:55.000000000 +0300 +++ new/test/javax/sound/sampled/AudioFileFormat/TypeEquals.java 2016-10-24 21:40:55.000000000 +0300 @@ -0,0 +1,44 @@ +/* + * 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.AudioFileFormat; + +/** + * @test + * @bug 4925483 + * @summary RFE: equals() should compare string in Encoding and Type + */ +public class TypeEquals { + + public static void main(String argv[]) throws Exception { + // first test that we can create our own type + // (the constructor was made public) + AudioFileFormat.Type myType = new AudioFileFormat.Type("WAVE", "wav"); + + // then check if this one equals this new one + // with the static instance in AudioFileFormat.Type + if (!myType.equals(AudioFileFormat.Type.WAVE)) { + throw new Exception("Types do not equal!"); + } + } +} --- /dev/null 2016-10-24 21:40:56.000000000 +0300 +++ new/test/javax/sound/sampled/AudioFormat/AudioFormatBitSize.java 2016-10-24 21:40:55.000000000 +0300 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002, 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. + */ + +/** + * @test + * @bug 4754759 + * @summary AudioFormat does not handle uncommon bit sizes correctly + */ + +import javax.sound.sampled.AudioFormat; + +public class AudioFormatBitSize { + + public static void main(String[] args) throws Exception { + int bits = 18; + AudioFormat format = new AudioFormat(44100.0f, bits, 1, true, false); + if (format.getFrameSize() * 8 < bits) { + System.out.println("bits = "+bits+" do not fit into a "+format.getFrameSize()+" bytes sample!"); + throw new Exception("Test failed"); + } else + System.out.println("bits = "+bits+" fit OK into a "+format.getFrameSize()+" bytes sample!"); + System.out.println("Test passed"); + } +} --- /dev/null 2016-10-24 21:40:56.000000000 +0300 +++ new/test/javax/sound/sampled/AudioFormat/EncodingEquals.java 2016-10-24 21:40:56.000000000 +0300 @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * @test + * @bug 4925483 + * @summary RFE: equals() should compare string in Encoding and Type + */ +public class EncodingEquals { + + public static void main(String argv[]) throws Exception { + // first test that we can create our own encoding + // (the constructor was made public) + AudioFormat.Encoding myType = new AudioFormat.Encoding("PCM_SIGNED"); + + // then check if this one equals this new one + // with the static instance in AudioFormat.Encoding + if (!myType.equals(AudioFormat.Encoding.PCM_SIGNED)) { + throw new Exception("Encodings do not equal!"); + } + } +} --- /dev/null 2016-10-24 21:40:57.000000000 +0300 +++ new/test/javax/sound/sampled/AudioFormat/Properties.java 2016-10-24 21:40:57.000000000 +0300 @@ -0,0 +1,115 @@ +/* + * 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.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.sound.sampled.AudioFormat; + +/** + * @test + * @bug 4925767 + * @summary RFE: Add Properties to AudioFormat + */ +public class Properties { + + static boolean g_failed = false; + + // all of p1 need to be in p2 + static boolean compare(Map p1, Map p2) { + boolean failed = false; + for(String key: (Set) p1.keySet()) { + out(" testing key: "+key); + if (!p2.containsKey(key)) { + out(" missing property: '"+key+"'. Failed"); + failed = true; + } + Object v1 = p1.get(key); + Object v2 = p2.get(key); + if (((v1 == null) && (v2 != null)) + || ((v1 != null) && (v2 == null)) + || !(v1.equals(v2))) { + out(" property '"+key+"' is different: " + +"expected='"+v1+"' " + +"actual='"+v2+"'. Failed"); + failed = true; + } + } + // test if we can modify p2 + try { + int oldSize = p2.size(); + p2.clear(); + if (oldSize > 0 && p2.size() == 0) { + out(" could clear the properties! Failed."); + failed = true; + } + } catch (Exception e) { + // correct + } + return failed; + } + + + public static void main(String argv[]) throws Exception { + // don't need to catch exceptions: any exception is a + // failure of this test + + Map p = new HashMap(); + p.put("bitrate", new Integer(128)); + p.put("quality", new Integer(10)); + p.put("MyProp", "test"); + + out("Testing AudioFileFormat properties:"); + // create an AudioFileFormat with properties + AudioFormat format = + new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, + 44100.0f, 16, 2, 4, 44100.0f, false, p); + // test that it has the properties + boolean failed = compare(p, format.properties()); + // test getProperty() + Object o = format.getProperty("MyProp"); + if (o == null || !o.equals("test")) { + out(" getProperty did not report an existing property!"); + failed = true; + } + o = format.getProperty("does not exist"); + if (o != null) { + out(" getProperty returned something for a non-existing property!"); + failed = true; + } + if (!failed) { + out(" OK"); + } else { + g_failed = true; + } + + if (g_failed) throw new Exception("Test FAILED!"); + System.out.println("Test passed."); + } + + static void out(String s) { + System.out.println(s); + } + +} --- /dev/null 2016-10-24 21:40:58.000000000 +0300 +++ new/test/javax/sound/sampled/AudioInputStream/AISReadFraction.java 2016-10-24 21:40:58.000000000 +0300 @@ -0,0 +1,237 @@ +/* + * 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.IOException; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4948663 + * @summary AudioInputStream does not use the original stream passed to its constructor + */ +public class AISReadFraction { + + static int failed = 0; + static byte[] testData = new byte[256]; + static boolean DEBUG = false; + + static AudioFormat[] formats = { + new AudioFormat(44100.0f, 8, 1, false, false), // frameSize = 1 + new AudioFormat(44100.0f, 8, 2, false, false), // frameSize = 2 + new AudioFormat(44100.0f, 16, 1, true, false), // frameSize = 2 + new AudioFormat(44100.0f, 24, 1, true, false), // frameSize = 3 + new AudioFormat(44100.0f, 16, 2, true, false), // frameSize = 4 + new AudioFormat(44100.0f, 8, 5, false, false), // frameSize = 5 + new AudioFormat(44100.0f, 16, 3, true, false), // frameSize = 6 + new AudioFormat(44100.0f, 8, 7, false, false), // frameSize = 7 + new AudioFormat(44100.0f, 32, 2, true, false) // frameSize = 8 + }; + + + public static void main(String args[]) throws Exception { + for (int i = 0; i0) throw new Exception("Test FAILED!"); + out("Test passed."); + } + + static void doTest(AudioFormat format, boolean doMark) { + out("Test with"+(doMark?"":"out")+" marking. Audio format: " + +"sampleSize="+format.getSampleSizeInBits()+"bits " + +"channels="+format.getChannels()+" " + +"frameSize="+format.getFrameSize()+"byte(s)"); + int maxReadBytes = (testData.length / format.getFrameSize()) * format.getFrameSize(); + InputStream is = new FractionalIS(testData, doMark); + AudioInputStream ais = new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED); + // first some general tests + if (ais.markSupported() && !doMark) { + out(" #AIS reports markSupported, but underlying stream cannot! FAILED"); + failed ++; + } + if (!ais.markSupported() && doMark) { + out(" #AIS does not report markSupported, but underlying stream can mark! FAILED"); + failed++; + } + byte[] data = new byte[1000]; + int frameSize = format.getFrameSize(); + int counter = 5; + int totalReadBytes = 0; + boolean hasRead0 = false; + boolean hasMarked = false; + boolean hasReset = false; + int markPos = 0; + while (true) { + try { + int toBeRead = frameSize * counter; + counter += 3; + if (counter > 14) { + counter -= 14; + } + int read = ais.read(data, 0, toBeRead); + if (DEBUG) out(" -> ais.read(data, 0, "+toBeRead+"): "+read+" (frameSize="+frameSize+")"); + if ((totalReadBytes == maxReadBytes) && (read != -1) + && ((read > 0) || hasRead0)) { + if (read == 0) { + out(" #stream was read to the end ("+maxReadBytes+"), but ais.read returned repeatedly 0 bytes. FAILED"); + } else { + out(" #stream was read to the end ("+maxReadBytes+"), but ais.read returned "+read+" bytes... FAILED"); + } + failed++; + break; + } + if (read > 0) { + verifyReadBytes(data, totalReadBytes, read); + if ((read % frameSize) != 0) { + out(" #Read non-integral number of frames: "+read+" bytes, frameSize="+frameSize+" bytes. FAILED"); + failed++; + } + totalReadBytes += read; + hasRead0 = false; + } + else if (read == 0) { + //out(" wanted to read "+toBeRead+" at position "+totalReadBytes+", but got 0 bytes!"); + if (hasRead0) { + out(" read 0 twice in a row! FAILED"); + failed++; + break; + } + hasRead0 = true; + } else { + // end of stream + out(" End of stream reached. Total read bytes: "+totalReadBytes); + if (totalReadBytes != maxReadBytes) { + out(" #Failed: should have read "+maxReadBytes+" bytes! FAILED."); + failed++; + } + break; + } + + // test marking + if (totalReadBytes > 50 && !hasMarked && !hasReset && doMark) { + out(" Marking at position "+totalReadBytes); + hasMarked = true; + ais.mark(0); + markPos = totalReadBytes; + } + if (totalReadBytes > 100 && hasMarked && !hasReset && doMark) { + out(" Resetting at position "+totalReadBytes+" back to "+markPos); + hasReset = true; + ais.reset(); + totalReadBytes = markPos; + } + + } catch (IOException e) { + out(" #caught unexpected exception:"); + e.printStackTrace(); + failed++; + } + } + } + + static void verifyReadBytes(byte[] data, int offset, int len) { + int firstWrongByte = -1; + for (int i = 0; i < len; i++) { + int expected = ((offset + i) % 128); + if (data[i] != expected) { + out(" read data is not correct! offset="+offset+" expected="+expected+" actual="+data[i]); + failed++; + break; + } + } + } + + + public static void out(String s) { + System.out.println(s); + } + + + static class FractionalIS extends InputStream { + byte[] data; + int pos = 0; + boolean canMark; + // a counter how many bytes are not returned + int missingBytes = 0; + int markPos = -1; + + FractionalIS(byte[] data, boolean canMark) { + this.data = data; + this.canMark = canMark; + } + + public int read() throws IOException { + if (pos >= data.length) { + return -1; + } + return data[pos++] & 0xFF; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (++missingBytes > 5) { + missingBytes = 0; + } + int reducedLen = len - missingBytes; + if (reducedLen <= 0) reducedLen = 1; + if (DEBUG) out(" FIS.read(data, 0, "+len+"): reducing len to "+reducedLen+" bytes."); + int ret = super.read(b, off, reducedLen); + if (DEBUG) out(" returning "+ret+" bytes. Now at pos="+pos); + return ret; + } + + public void mark(int readlimit) { + markPos = pos; + if (DEBUG) out(" FIS.mark(): marking at "+pos); + } + + public void reset() throws IOException { + if (!canMark) { + throw new IOException("reset not supported!"); + } + if (markPos == -1) { + throw new IOException("Mark position not set!"); + } + pos = markPos; + if (DEBUG) out(" FIS.reset(): now back at "+pos); + } + + public boolean markSupported() { + return canMark; + } + + } + +} --- /dev/null 2016-10-24 21:40:59.000000000 +0300 +++ new/test/javax/sound/sampled/AudioInputStream/bug6188860.java 2016-10-24 21:40:58.000000000 +0300 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, 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.IOException; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 6188860 + * @summary Tests that method AudioInputStream.read() returns right value + */ +public class bug6188860 { + + public static void main(String[] args) throws Exception { + byte[] testData = new byte[256]; + + // fill data + for (int i = 0; i < testData.length; i++) + testData[i] = (byte) (i % 128); + + InputStream streamSrc = new TestInputStream(testData); + AudioFormat format = new AudioFormat(44100.0f, 8, 1, false, false); // frameSize = 1 + AudioInputStream streamAudio = new AudioInputStream(streamSrc, format, AudioSystem.NOT_SPECIFIED); + + int nErrCount = 0; + int nTotal = 0; + + int dataSrc, dataRead; + while (nTotal < (testData.length - 1)) { + dataRead = streamAudio.read(); + if (dataRead < 0) { + System.out.println("end of stream"); + break; + } + + dataSrc = testData[nTotal]; + + if (dataRead != dataSrc) { + System.out.println("" + nTotal + " - mismatch :" + dataRead + " <> " + dataSrc); + nErrCount++; + } + nTotal++; + } + + System.out.println("Total: " + nTotal + "; Mismatches: " + nErrCount); + + if (nErrCount > 0) { + throw new RuntimeException("test failed: " + nErrCount + " mismatches of total " + nTotal + " bytes."); + } + System.out.println("Test sucessfully passed."); + } + + + static class TestInputStream extends InputStream { + byte[] data; + int pos = 0; + + TestInputStream(byte[] data) { + this.data = data; + } + + public int read() throws IOException { + if (pos >= data.length) { + return -1; + } + return data[pos++] & 0xFF; + } + } + +} --- /dev/null 2016-10-24 21:40:59.000000000 +0300 +++ new/test/javax/sound/sampled/AudioSystem/AudioFileTypes/AudioFileTypeUniqueness.java 2016-10-24 21:40:59.000000000 +0300 @@ -0,0 +1,52 @@ +/* + * 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.AudioFileFormat; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4883060 + * @summary AudioSystem.getAudioFileTypes returns duplicates + */ +public class AudioFileTypeUniqueness { + + public static void main(String[] args) throws Exception { + boolean foundDuplicates = false; + AudioFileFormat.Type[] aTypes = AudioSystem.getAudioFileTypes(); + for (int i = 0; i < aTypes.length; i++) + { + for (int j = 0; j < aTypes.length; j++) + { + if (aTypes[i].equals(aTypes[j]) && i != j) { + foundDuplicates = true; + } + } + } + if (foundDuplicates) { + throw new Exception("Test failed"); + } else { + System.out.println("Test passed"); + } + } +} --- /dev/null 2016-10-24 21:41:00.000000000 +0300 +++ new/test/javax/sound/sampled/AudioSystem/AudioFileTypes/ShowAudioFileTypes.java 2016-10-24 21:41:00.000000000 +0300 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2001, 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.AudioFileFormat; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4303037 + * @summary Shows the existing audio file types of AudioSystem and checks + * whether there are some at all + */ +public class ShowAudioFileTypes { + + public static void main(String[] args) throws Exception { + AudioFileFormat.Type[] aTypes = AudioSystem.getAudioFileTypes(); + System.out.println(aTypes.length+" supported target types:"); + for (int i = 0; i < aTypes.length; i++) + { + System.out.println(" "+(i+1)+". " + aTypes[i]+" with ext. '"+aTypes[i].getExtension()+"'"); + } + if (aTypes.length<3) { + throw new Exception("Test failed"); + } else { + System.out.println("Test passed"); + } + } +} --- /dev/null 2016-10-24 21:41:01.000000000 +0300 +++ new/test/javax/sound/sampled/AudioSystem/DefaultMixers.java 2016-10-24 21:41:00.000000000 +0300 @@ -0,0 +1,198 @@ +/* + * 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.util.List; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.Port; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; +import javax.sound.sampled.spi.MixerProvider; + +import com.sun.media.sound.JDK13Services; + +/** + * @test + * @bug 4776511 + * @summary RFE: Setting the default MixerProvider. Test the retrieving of lines + * with defaut mixer properties. + * @modules java.desktop/com.sun.media.sound + */ +public class DefaultMixers { + + private static final String ERROR_PROVIDER_CLASS_NAME = "abc"; + private static final String ERROR_INSTANCE_NAME = "def"; + + private static final Class[] lineClasses = { + SourceDataLine.class, + TargetDataLine.class, + Clip.class, + Port.class, + }; + + public static void main(String[] args) throws Exception { + boolean allOk = true; + Mixer.Info[] infos; + + out("Testing Mixers retrieved via AudioSystem"); + infos = AudioSystem.getMixerInfo(); + allOk &= testMixers(infos, null); + + out("Testing MixerProviders"); + List providers = JDK13Services.getProviders(MixerProvider.class); + for (int i = 0; i < providers.size(); i++) { + MixerProvider provider = (MixerProvider) providers.get(i); + infos = provider.getMixerInfo(); + allOk &= testMixers(infos, provider.getClass().getName()); + } + + if (! allOk) { + throw new Exception("Test failed"); + } else { + out("Test passed"); + } + } + + private static boolean testMixers(Mixer.Info[] infos, + String providerClassName) { + boolean allOk = true; + + for (int i = 0; i < infos.length; i++) { + Mixer mixer = null; + try { + mixer = AudioSystem.getMixer(infos[i]); + } catch (NullPointerException e) { + out("Exception thrown; Test NOT failed."); + e.printStackTrace(); + } + for (int j = 0; j < lineClasses.length; j++) { + if (mixer.isLineSupported(new Line.Info(lineClasses[j]))) { + allOk &= testMixer(mixer, lineClasses[j], + providerClassName); + } + } + } + return allOk; + } + + private static boolean testMixer(Mixer mixer, Class lineType, + String providerClassName) { + boolean allOk = true; + String instanceName = mixer.getMixerInfo().getName(); + + // no error + allOk &= testMixer(mixer, lineType, + providerClassName, instanceName); + + // erroneous provider class name, correct instance name + allOk &= testMixer(mixer, lineType, + ERROR_PROVIDER_CLASS_NAME, instanceName); + + // erroneous provider class name, no instance name + allOk &= testMixer(mixer, lineType, + ERROR_PROVIDER_CLASS_NAME, ""); + + // erroneous provider class name, erroneous instance name + allOk &= testMixer(mixer, lineType, + ERROR_PROVIDER_CLASS_NAME, ERROR_INSTANCE_NAME); + + return allOk; + } + + private static boolean testMixer(Mixer mixer, Class lineType, + String providerClassName, + String instanceName) { + boolean allOk = true; + + try { + String propertyValue = (providerClassName != null) ? providerClassName: "" ; + propertyValue += "#" + instanceName; + out("property value: " + propertyValue); + System.setProperty(lineType.getName(), propertyValue); + Line line = null; + Line.Info info = null; + Line.Info[] infos; + AudioFormat format = null; + if (lineType == SourceDataLine.class || lineType == Clip.class) { + infos = mixer.getSourceLineInfo(); + format = getFirstLinearFormat(infos); + info = new DataLine.Info(lineType, format); + } else if (lineType == TargetDataLine.class) { + infos = mixer.getTargetLineInfo(); + format = getFirstLinearFormat(infos); + info = new DataLine.Info(lineType, format); + } else if (lineType == Port.class) { + /* Actually, a Ports Mixer commonly has source infos + as well as target infos. We ignore this here, since we + just need a random one. */ + infos = mixer.getSourceLineInfo(); + for (int i = 0; i < infos.length; i++) { + if (infos[i] instanceof Port.Info) { + info = infos[i]; + break; + } + } + } + out("Line.Info: " + info); + line = AudioSystem.getLine(info); + out("line: " + line); + if (! lineType.isInstance(line)) { + out("type " + lineType + " failed: class should be '" + + lineType + "' but is '" + line.getClass() + "'!"); + allOk = false; + } + } catch (Exception e) { + out("Exception thrown; Test NOT failed."); + e.printStackTrace(); + } + return allOk; + } + + private static AudioFormat getFirstLinearFormat(Line.Info[] infos) { + for (int i = 0; i < infos.length; i++) { + if (infos[i] instanceof DataLine.Info) { + AudioFormat[] formats = ((DataLine.Info) infos[i]).getFormats(); + for (int j = 0; j < formats.length; j++) { + AudioFormat.Encoding encoding = formats[j].getEncoding(); + int sampleSizeInBits = formats[j].getSampleSizeInBits(); + if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED) && + sampleSizeInBits == 16 || + encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED) && + sampleSizeInBits == 16) { + return formats[j]; + } + } + } + } + return null; + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:41:01.000000000 +0300 +++ new/test/javax/sound/sampled/AudioSystem/DefaultProperties.java 2016-10-24 21:41:01.000000000 +0300 @@ -0,0 +1,164 @@ +/* + * 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 com.sun.media.sound.JDK13Services; + +/** + * @test + * @bug 4776511 + * @build DefaultProperties + * @run main/othervm DefaultProperties + * @summary RFE: Setting the default MixerProvider. Test the retrieving and + * parsing of properties. + * @modules java.desktop/com.sun.media.sound + */ +public class DefaultProperties { + + private static final Class[] lineTypeClasses = { + javax.sound.sampled.SourceDataLine.class, + javax.sound.sampled.TargetDataLine.class, + javax.sound.sampled.Clip.class, + javax.sound.sampled.Port.class, + }; + + public static void main(String[] args) throws Exception { + boolean allOk = true; + File file = new File(System.getProperty("test.src", "."), "testdata"); + System.setProperty("java.home", file.getCanonicalPath()); + + for (int i = 0; i < lineTypeClasses.length; i++) { + Class cls = lineTypeClasses[i]; + String propertyName = cls.getName(); + String result; + String provClassName; + String instanceName; + + // properties file, both provider class name and instance name + provClassName = "xyz"; + instanceName = "123"; + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (! instanceName.equals(result)) { + out("type " + cls + " failed: instance name should be '" + + instanceName + "' but is '" + result + "'!"); + allOk = false; + } + + // system property, provider class name only, no trailing hash + provClassName = "abc"; + System.setProperty(propertyName, provClassName); + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (result != null) { + out("type " + cls + " failed: instance name should be " + + "null but is '" + result + "'!"); + allOk = false; + } + + // system property, provider class name only, trailing hash + provClassName = "def"; + System.setProperty(propertyName, provClassName + "#"); + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (result != null) { + out("type " + cls + " failed: instance name should be " + + "null but is '" + result + "'!"); + allOk = false; + } + + // system property, instance name only + instanceName = "ghi"; + System.setProperty(propertyName, "#" + instanceName); + result = JDK13Services.getDefaultProviderClassName(cls); + if (result != null) { + out("type " + cls + " failed: provider class should be " + + "null but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (! instanceName.equals(result)) { + out("type " + cls + " failed: instance name should be '" + + instanceName + "' but is '" + result + "'!"); + allOk = false; + } + + // system property, both provider class and instance name + provClassName = "jkl"; + instanceName = "mno"; + System.setProperty(propertyName, provClassName + "#" + instanceName); + result = JDK13Services.getDefaultProviderClassName(cls); + if (! provClassName.equals(result)) { + out("type " + cls + " failed: provider class should be '" + + provClassName + "' but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (! instanceName.equals(result)) { + out("type " + cls + " failed: instance name should be '" + + instanceName + "' but is '" + result + "'!"); + allOk = false; + } + + // system property, empty + System.setProperty(propertyName, ""); + result = JDK13Services.getDefaultProviderClassName(cls); + if (result != null) { + out("type " + cls + " failed: provider class should be " + + "null but is '" + result + "'!"); + allOk = false; + } + result = JDK13Services.getDefaultInstanceName(cls); + if (result != null) { + out("type " + cls + " failed: instance name should be " + + "null but is '" + result + "'!"); + allOk = false; + } + } + if (! allOk) { + throw new Exception("Test failed"); + } else { + out("Test passed"); + } + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:41:02.000000000 +0300 +++ new/test/javax/sound/sampled/AudioSystem/ProviderCacheing.java 2016-10-24 21:41:02.000000000 +0300 @@ -0,0 +1,64 @@ +/* + * 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.util.List; +import com.sun.media.sound.JDK13Services; + +/** + * @test + * @bug 4776511 + * @summary RFE: Setting the default MixerProvider. Test the cacheing of + * providers. + * @modules java.desktop/com.sun.media.sound + */ +public class ProviderCacheing { + + private static final Class[] providerClasses = { + javax.sound.sampled.spi.AudioFileReader.class, + javax.sound.sampled.spi.AudioFileWriter.class, + javax.sound.sampled.spi.FormatConversionProvider.class, + javax.sound.sampled.spi.MixerProvider.class, + }; + + public static void main(String[] args) throws Exception { + boolean allCached = true; + for (int i = 0; i < providerClasses.length; i++) { + List list0 = JDK13Services.getProviders(providerClasses[i]); + List list1 = JDK13Services.getProviders(providerClasses[i]); + if (list0 == list1) { + out("Providers should not be cached for " + providerClasses[i]); + allCached = false; + } + } + + if (! allCached) { + throw new Exception("Test failed"); + } else { + out("Test passed"); + } + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:41:03.000000000 +0300 +++ new/test/javax/sound/sampled/AudioSystem/testdata/conf/sound.properties 2016-10-24 21:41:03.000000000 +0300 @@ -0,0 +1,27 @@ +# +# 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. +# + +javax.sound.sampled.SourceDataLine=xyz#123 +javax.sound.sampled.TargetDataLine=xyz#123 +javax.sound.sampled.Clip=xyz#123 +javax.sound.sampled.Port=xyz#123 --- /dev/null 2016-10-24 21:41:04.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/ClipCloseLoss.java 2016-10-24 21:41:03.000000000 +0300 @@ -0,0 +1,163 @@ +/* + * 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4946913 + * @summary DirectClip doesn't kill the thread correctly, sometimes + * @run main/othervm ClipCloseLoss + * @key headful + */ +public class ClipCloseLoss { + static int frameCount = 441000; // lets say 10 seconds + static AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false); + static ByteArrayInputStream bais = + new ByteArrayInputStream(new byte[frameCount * format.getFrameSize()]); + + static int success = 0; + static boolean failed = false; + + public static void run(Mixer m) { + Clip clip = null; + try { + if (m == null) { + out("Using default mixer"); + clip = (Clip) AudioSystem.getClip(); + } else { + out("Using mixer: "+m); + DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED); + clip = (Clip) m.getLine(info); + } + out(" got clip: "+clip); + if (!clip.getClass().toString().contains("Direct")) { + out(" no direct audio clip -> do not test."); + return; + } + + out(" open"); + bais.reset(); + clip.open(new AudioInputStream(bais, format, frameCount)); + + out(" clip.close()"); + //long t = System.currentTimeMillis(); + clip.close(); + //if (System.currentTimeMillis() - t > 1950) { + // out(" clip.close needed more than 2 seconds! Causes failure of this test."); + // failed = true; + //} + out(" clip closed"); + success++; + } catch (LineUnavailableException luae) { + // line not available, test not failed + System.err.println(luae); + } catch (IllegalArgumentException iae) { + // line not available, test not failed + System.err.println(iae); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static int getClipThreadCount() { + int ret = 0; + ThreadGroup tg = Thread.currentThread().getThreadGroup(); + while (tg.getParent() != null) { tg = tg.getParent(); } + Thread[] threads = new Thread[500]; + int count = tg.enumerate(threads, true); + for (int i = 0; i < count; i++) { + if (threads[i].getName().contains("Direct") + && threads[i].getName().contains("Clip")) { + out("Found Direct Clip thread object: "+threads[i]); + ret++; + } + } + return ret; + } + + public static void main(String[] args) throws Exception { + if (isSoundcardInstalled()) { + bais.mark(0); + run(null); + Mixer.Info[] infos = AudioSystem.getMixerInfo(); + for (int i = 0; i 0) { + out("Unused clip threads exist! Causes test failure"); + failed = true; + } + if (failed) throw new Exception("Test FAILED!"); + if (success > 0) { + out("Test passed."); + } else { + System.err.println("Test could not execute: please install an audio device"); + } + } + } + + /** + * Returns true if at least one soundcard is correctly installed + * on the system. + */ + public static boolean isSoundcardInstalled() { + boolean result = false; + try { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + if (mixers.length > 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } + + public static void out(String s) { + /*long t = System.nanoTime() / 1000000l; + String ts = ""+(t % 1000); + while (ts.length() < 3) ts = "0"+ts; + System.out.println(""+(t/1000)+":"+ts+" "+s); + System.out.flush();*/ + System.out.println(s); + } +} --- /dev/null 2016-10-24 21:41:04.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/ClipFlushCrash.java 2016-10-24 21:41:04.000000000 +0300 @@ -0,0 +1,226 @@ +/* + * 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4946945 + * @summary Crash in javasound while running TicTacToe demo applet tiger b26 + */ +public class ClipFlushCrash { + static int frameCount = 441000; // lets say 10 seconds + static AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false); + static ByteArrayInputStream bais = + new ByteArrayInputStream(new byte[frameCount * format.getFrameSize()]); + + static int success = 0; + + public static void run(Mixer m) { + Clip clip = null; + try { + if (m == null) { + out("Using default mixer"); + clip = (Clip) AudioSystem.getClip(); + } else { + out("Using mixer: "+m); + DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED); + clip = (Clip) m.getLine(info); + } + out(" got clip: "+clip); + if (!clip.getClass().toString().contains("Direct")) { + out(" no direct audio clip -> do not test."); + return; + } + + out(" open"); + bais.reset(); + clip.open(new AudioInputStream(bais, format, frameCount)); + + AT at1 = new AT(clip, "flush thread", 123) { + public void doAction() throws Exception { + log("flush"); + clip.flush(); + } + }; + AT at2 = new AT(clip, "setFramePosition thread", 67) { + public void doAction() throws Exception { + int pos = (int) (Math.random() * clip.getFrameLength()); + log("setPosition to frame "+pos); + clip.setFramePosition(pos); + } + }; + AT at3 = new AT(clip, "start/stop thread", 300) { + public void doAction() throws Exception { + if (clip.isRunning()) { + log("stop"); + clip.stop(); + } else { + log("start"); + clip.setFramePosition(0); + clip.start(); + } + } + }; + AT at4 = new AT(clip, "open/close thread", 600) { + public synchronized void doAction() throws Exception { + log("close"); + clip.close(); + wait(50); + if (!terminated) { + log("open"); + bais.reset(); + clip.open(new AudioInputStream(bais, format, frameCount)); + } + } + }; + + out(" clip.start"); + clip.start(); + out(" for 10 seconds, call start/stop, setFramePosition, and flush from other threads"); + at1.start(); + at2.start(); + at3.start(); + at4.start(); + try { + Thread.sleep(10000); + } catch (InterruptedException ie) {} + out(" finished."); + at1.terminate(); + at2.terminate(); + at3.terminate(); + at4.terminate(); + out(" clip.close()"); + clip.close(); + success++; + } catch (LineUnavailableException luae) { + // line not available, test not failed + System.err.println(luae); + } catch (IllegalArgumentException iae) { + // line not available, test not failed + System.err.println(iae); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static void main(String[] args) throws Exception { + if (isSoundcardInstalled()) { + bais.mark(0); + run(null); + Mixer.Info[] infos = AudioSystem.getMixerInfo(); + for (int i = 0; i 0) { + out("No crash -> Test passed"); + } else { + System.err.println("Test could not execute: please install an audio device"); + } + } + } + + /** + * Returns true if at least one soundcard is correctly installed + * on the system. + */ + public static boolean isSoundcardInstalled() { + boolean result = false; + try { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + if (mixers.length > 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } + + public static void out(String s) { + /*long t = System.nanoTime() / 1000000l; + String ts = ""+(t % 1000); + while (ts.length() < 3) ts = "0"+ts; + System.out.println(""+(t/1000)+":"+ts+" "+s); + System.out.flush();*/ + System.out.println(s); + } + + private abstract static class AT extends Thread { + protected boolean terminated = false; + protected Clip clip; + private int waitTime; + + public AT(Clip clip, String name, int waitTime) { + super(name); + this.clip = clip; + this.waitTime = waitTime; + } + + public abstract void doAction() throws Exception; + + public void run() { + log("start"); + while (!terminated) { + try { + synchronized(this) { + wait(waitTime); + } + if (!terminated) { + doAction(); + } + } catch(Exception e) { + log("exception: "+e); + } + } + log("exit"); + } + + public synchronized void terminate() { + log("terminate"); + terminated = true; + notifyAll(); + } + + protected void log(String s) { + //out(" "+Thread.currentThread().getId()+" "+getName()+": "+s); + out(" "+getName()+": "+s); + } + } +} --- /dev/null 2016-10-24 21:41:05.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/Drain/ClipDrain.java 2016-10-24 21:41:05.000000000 +0300 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2002, 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4732218 + * @summary Clip.drain does not actually block until all I/O is complete as + * documented. + */ +public class ClipDrain { + static int successfulTests = 0; + static AudioFormat format = new AudioFormat(8000, 16, 1, true, false); + // create a 10-second file + static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 10)]; + + static int TOLERANCE_MS = 2500; // how many milliseconds too short is tolerated... + + private static void doMixerClip(Mixer mixer) throws Exception { + boolean waitedEnough=false; + try { + DataLine.Info info = new DataLine.Info(Clip.class, format); + Clip clip = (Clip) mixer.getLine(info); + clip.open(format, soundData, 0, soundData.length); + + // sanity + if (clip.getMicrosecondLength()/1000 < 9900) { + throw new Exception("clip's microsecond length should be at least 9900000, but it is "+clip.getMicrosecondLength()); + } + long start = System.currentTimeMillis(); + + System.out.println(" ---------- start --------"); + clip.start(); + // give time to actually start it. ALSA implementation needs that... + Thread.sleep(300); + System.out.println("drain ... "); + clip.drain(); + long elapsedTime = System.currentTimeMillis() - start; + System.out.println("close ... "); + clip.close(); + System.out.println("... done"); + System.out.println("Playback duration: "+elapsedTime+" milliseconds."); + waitedEnough = elapsedTime >= ((clip.getMicrosecondLength() / 1000) - TOLERANCE_MS); + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + return; + } + if (!waitedEnough) { + throw new Exception("Drain did not wait long enough to play entire clip."); + } + successfulTests++; + } + + + private static void doAll() throws Exception { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + for (int i=0; i 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:41:06.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/Duration/ClipDuration.java 2016-10-24 21:41:05.000000000 +0300 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2001, 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4237703 + * @summary Check that Clip.getMicrosecondLength() returns correct value. + */ +public class ClipDuration { + + public static int run(Mixer m) { + int res=1; // failed + int frameCount = 441000; // lets say 10 seconds + AudioFormat f = new AudioFormat(44100.0f, 16, 2, true, false); + AudioInputStream audioInputStream = + new AudioInputStream(new ByteArrayInputStream(new byte[frameCount * f.getFrameSize()]), + f, frameCount); + AudioFormat format = audioInputStream.getFormat(); + Clip m_clip = null; + try { + if (m == null) { + m_clip = (Clip) AudioSystem.getClip(); + } else { + DataLine.Info info = new DataLine.Info(Clip.class, format, AudioSystem.NOT_SPECIFIED); + m_clip = (Clip) m.getLine(info); + } + System.out.println("Got clip: "+m_clip); + m_clip.open(audioInputStream); + long microseconds=m_clip.getMicrosecondLength(); + System.out.println("getFrameLength()="+m_clip.getFrameLength()+" frames"); + System.out.println("getMicrosecondLength()="+microseconds+" us"); + if (Math.abs(microseconds-10000000)<50) { + System.out.println("->Clip OK"); + res=0; // passes if less than 50us error + } + } catch (LineUnavailableException luae) { + System.err.println(luae); + res = 3; // line not available, test not failed + } catch (Throwable t) { + System.out.println("->Exception:"+t); + t.printStackTrace(); + res=2; // exception + } + if (m_clip != null) { + m_clip.close(); + } + return res; + } + + + + public static void main(String[] args) throws Exception { + if (isSoundcardInstalled()) { + int res=3; + res = run(null); + Mixer.Info[] infos = AudioSystem.getMixerInfo(); + for (int i = 0; i 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:41:06.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/Endpoint/ClipSetEndPoint.java 2016-10-24 21:41:06.000000000 +0300 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2005, 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4385928 + * @summary Verify that an endpoint -1 in Clip does not throw an exception + */ +//public class test048 extends TRTest +public class ClipSetEndPoint { + + private Clip theClip; + + boolean testPassed = true; + + //_______________________________________________ + // Method: runTest + //_______________________________________________ + public boolean runTest() { + AudioInputStream theAudioInputStream = new AudioInputStream( + new ByteArrayInputStream(new byte[2000]), + new AudioFormat(8000.0f, 8, 1, false, false), 2000); // + + AudioFormat theAudioFormat = theAudioInputStream.getFormat(); + + DataLine.Info info = new DataLine.Info(Clip.class, theAudioFormat, + AudioSystem.NOT_SPECIFIED); + try { + theClip = (Clip) AudioSystem.getLine(info); + theClip.open(theAudioInputStream); + + int theStartLoopPoint = 0; + int theEndLoopPoint = -1; // -1 signifies the last frame + + theClip.setLoopPoints(theStartLoopPoint, theEndLoopPoint); + //theClip.start(); + } catch (LineUnavailableException e) { + e.printStackTrace(); + testPassed = true; + } catch (Exception e) { + e.printStackTrace(); + testPassed = false; + } + return testPassed; + } + + //_______________________________________________ + // Method: main + //_______________________________________________ + public static void main(String[] args) throws Exception { + if (isSoundcardInstalled()) { + ClipSetEndPoint thisTest = new ClipSetEndPoint(); + boolean testResult = thisTest.runTest(); + if (testResult) { + System.out.println("Test passed"); + } else { + System.out.println("Test failed"); + throw new Exception("Test failed"); + } + } + } + + /** + * Returns true if at least one soundcard is correctly installed + * on the system. + */ + public static boolean isSoundcardInstalled() { + boolean result = false; + try { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + if (mixers.length > 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: " + e); + } + if (!result) { + System.err.println( + "Soundcard does not exist or sound drivers not installed!"); + System.err.println( + "This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:41:07.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/Open/ClipOpenBug.java 2016-10-24 21:41:07.000000000 +0300 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2001, 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; + +/** + * @test + * @bug 4479444 + * @summary Verify that the error string of Clip.open() is meaningful + */ +public class ClipOpenBug { + + public static void main(String args[]) throws Exception { + boolean res = true; + try { + AudioInputStream ais = new AudioInputStream( + new ByteArrayInputStream(new byte[2000]), + new AudioFormat(8000.0f, 8, 1, false, false), 2000); // + AudioFormat format = ais.getFormat(); + DataLine.Info info = new DataLine.Info(Clip.class, format, + ((int) ais.getFrameLength() + * format + .getFrameSize())); + Clip clip = (Clip) AudioSystem.getLine(info); + clip.open(); + FloatControl rateControl = (FloatControl) clip.getControl( + FloatControl.Type.SAMPLE_RATE); + int c = 0; + while (c++ < 10) { + clip.stop(); + clip.setFramePosition(0); + clip.start(); + for (float frq = 22000; frq < 44100; frq = frq + 100) { + try { + Thread.currentThread().sleep(20); + } catch (Exception e) { + break; + } + rateControl.setValue(frq); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + res = ex.getMessage().indexOf( + "This method should not have been invoked!") < 0; + } + if (res) { + System.out.println("Test passed"); + } else { + System.out.println("Test failed"); + throw new Exception("Test failed"); + } + } +} --- /dev/null 2016-10-24 21:41:08.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/bug5070081.java 2016-10-24 21:41:08.000000000 +0300 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2005, 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.Clip; +import javax.sound.sampled.DataLine; + +/* + * @test + * @bug 5070081 + * @summary Tests that javax.sound.sampled.Clip does not loses position through + * stop/start + * @key headful + */ +public class bug5070081 { + + static AudioFormat format = new AudioFormat(22050, 8, 1, false, false); + // create a 3-second file + static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 3)]; + + static final int LOOP_COUNT = 5; + + static boolean test() throws Exception { + DataLine.Info info = new DataLine.Info(Clip.class, format); + Clip clip = (Clip)AudioSystem.getLine(info); + clip.open(format, soundData, 0, soundData.length); + + boolean bSuccess = true; + + long nLengthMS = clip.getMicrosecondLength()/1000; + + System.out.println(" Clip length:"); + System.out.println(" frames: " + clip.getFrameLength()); + System.out.println(" seconds: " + nLengthMS/1000.0); + + clip.start(); // start playing + Thread.sleep(1000); // wait a sec + long time1 = System.currentTimeMillis(); + long pos1 = clip.getFramePosition(); // store the position + System.out.println(" Position before stop: " + pos1); + clip.stop(); // and then stop + long pos2 = clip.getFramePosition(); // 2nd try + long time2 = System.currentTimeMillis(); + System.out.println(" Position after stop: " + pos2); + + System.out.println(" d(time): " + Math.abs(time2-time1) + " ms;" + + "d(clip pos): " + Math.abs(pos2 - pos1) + " ms."); + + long nDerivation = Math.abs(pos2 - pos1) - Math.abs(time2-time1); + // add 50 ms for deviation (delay for stopping and errors due timer precision) + if (nDerivation > 50) { + System.out.println(" ERROR(1): The deviation is too much: " + nDerivation + " ms"); + bSuccess = false; + } + + Thread.sleep(1000); + clip.start(); // start again + Thread.sleep(100); + while(clip.isRunning()); // wait for the sound to finish + + int nEndPos = clip.getFramePosition(); + System.out.println(" Position at end: " + nEndPos); + if (nEndPos > clip.getFrameLength()) { + System.out.println(" ERROR(2): end position if out of range"); + bSuccess = false; + } + + clip.close(); + + return bSuccess; + } + + public static void main(String[] args) throws Exception { + for (int count=1; count <= LOOP_COUNT; count++) + { + System.out.println("loop " + count + "/" + LOOP_COUNT); + if (!test()) + { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED."); + } + } + + System.out.println("Test passed sucessfully"); + } +} --- /dev/null 2016-10-24 21:41:09.000000000 +0300 +++ new/test/javax/sound/sampled/Clip/bug6251460.java 2016-10-24 21:41:08.000000000 +0300 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2005, 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; +import javax.sound.sampled.LineUnavailableException; + +/** + * @test + * @bug 6251460 8047222 + * @requires (os.family == "windows" | os.family == "mac") + * @summary Tests that JavaSound plays short sounds (less then 1 second) + */ +public class bug6251460 { + private static final class MutableBoolean { + public boolean value; + + public MutableBoolean(boolean initialValue) { + value = initialValue; + } + } + + // static helper routines + static long startTime = currentTimeMillis(); + static long currentTimeMillis() { + return System.nanoTime() / 1000000L; + } + static void log(String s) { + long time = currentTimeMillis() - startTime; + long ms = time % 1000; + time /= 1000; + long sec = time % 60; + time /= 60; + long min = time % 60; + time /= 60; + System.out.println("" + + (time < 10 ? "0" : "") + time + + ":" + (min < 10 ? "0" : "") + min + + ":" + (sec < 10 ? "0" : "") + sec + + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms + + " " + s); + } + + + static private int countErrors = 0; + static private final int LOOP_COUNT = 30; + + static AudioFormat format = new AudioFormat(8000, 16, 1, true, false); + // create a 250-ms clip + static byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * 0.25)]; + + static protected void test() + throws LineUnavailableException, InterruptedException { + DataLine.Info info = new DataLine.Info(Clip.class, format); + Clip clip = (Clip)AudioSystem.getLine(info); + final MutableBoolean clipStoppedEvent = new MutableBoolean(false); + clip.addLineListener(new LineListener() { + @Override + public void update(LineEvent event) { + if (event.getType() == LineEvent.Type.STOP) { + synchronized (clipStoppedEvent) { + clipStoppedEvent.value = true; + clipStoppedEvent.notifyAll(); + } + } + } + }); + clip.open(format, soundData, 0, soundData.length); + + long lengthClip = clip.getMicrosecondLength() / 1000; + log("Clip length " + lengthClip + " ms"); + log("Playing..."); + for (int i=1; i<=LOOP_COUNT; i++) { + long startTime = currentTimeMillis(); + log(" Loop " + i); + clip.start(); + + synchronized (clipStoppedEvent) { + while (!clipStoppedEvent.value) { + clipStoppedEvent.wait(); + } + clipStoppedEvent.value = false; + } + + long endTime = currentTimeMillis(); + long lengthPlayed = endTime - startTime; + + if (lengthClip > lengthPlayed + 20) { + log(" ERR: Looks like sound didn't play: played " + lengthPlayed + " ms instead " + lengthClip); + countErrors++; + } else { + log(" OK: played " + lengthPlayed + " ms"); + } + clip.setFramePosition(0); + + } + log("Played " + LOOP_COUNT + " times, " + countErrors + " errors detected."); + } + + public static void main(String[] args) throws InterruptedException { + try { + test(); + } catch (LineUnavailableException | IllegalArgumentException + | IllegalStateException ignored) { + System.out.println("Test is not applicable. Automatically passed"); + return; + } + if (countErrors > 0) { + throw new RuntimeException( + "Test FAILED: " + countErrors + " error detected (total " + + LOOP_COUNT + ")"); + } + } +} --- /dev/null 2016-10-24 21:41:09.000000000 +0300 +++ new/test/javax/sound/sampled/Controls/CompoundControl/ToString.java 2016-10-24 21:41:09.000000000 +0300 @@ -0,0 +1,98 @@ +/* + * 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.CompoundControl; +import javax.sound.sampled.Control; + +/** + * @test + * @bug 4629190 + * @summary CompoundControl: getMemberControls() and toString() throw + * NullPointerException + */ +public class ToString { + public static void main(String args[]) throws Exception { + System.out.println(); + System.out.println(); + System.out.println("4629190: CompoundControl: getMemberControls() and toString() throw NullPointerException"); + + String firstControlTypeName = "first_Control_Type_Name"; + String secondControlTypeName = "second_Control_Type_Name"; + String thirdControlTypeName = "third_Control_Type_Name"; + + Control.Type firstControlType = new TestControlType(firstControlTypeName); + Control.Type secondControlType = new TestControlType(secondControlTypeName); + Control.Type thirdControlType = new TestControlType(thirdControlTypeName); + + Control firstControl = new TestControl(firstControlType); + Control secondControl = new TestControl(secondControlType); + Control thirdControl = new TestControl(thirdControlType); + + String testCompoundControlTypeName = "CompoundControl_Type_Name"; + CompoundControl.Type testCompoundControlType + = new TestCompoundControlType(testCompoundControlTypeName); + + Control[] setControls = { firstControl, secondControl, thirdControl }; + CompoundControl testedCompoundControl + = new TestCompoundControl(testCompoundControlType, setControls); + + // this may throw exception if bug applies + Control[] producedControls = testedCompoundControl.getMemberControls(); + System.out.println("Got "+producedControls.length+" member controls."); + + // this may throw exception if bug applies + String producedString = testedCompoundControl.toString(); + System.out.println("toString() returned: "+producedString); + + System.out.println("Test passed."); + } + +} + +class TestControl extends Control { + + TestControl(Control.Type type) { + super(type); + } +} + +class TestControlType extends Control.Type { + + TestControlType(String name) { + super(name); + } +} + +class TestCompoundControl extends CompoundControl { + + TestCompoundControl(CompoundControl.Type type, Control[] memberControls) { + super(type, memberControls); + } +} + +class TestCompoundControlType extends CompoundControl.Type { + + TestCompoundControlType(String name) { + super(name); + } +} --- /dev/null 2016-10-24 21:41:10.000000000 +0300 +++ new/test/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java 2016-10-24 21:41:10.000000000 +0300 @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2001, 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4385654 + * @summary Check that the MASTER_GAIN control has a valid precision + */ +//public class test047 extends TRTest +public class FloatControlBug { + + private Clip theClip; + + boolean testPassed = true; + + private AudioFormat.Encoding theEncoding = AudioFormat.Encoding.PCM_SIGNED; + + private float theSampleRate = 44100; + + private int theSampleSize = 16; + + private int theNumberOfChannels = 1; + + private int theFrameSize = 2; + + private float theFrameRate = 44100; + + private boolean isBigEndian = false; + + //_______________________________________________ + // Method: runTest + //_______________________________________________ + public boolean runTest() { + AudioInputStream theAudioInputStream = new AudioInputStream( + new ByteArrayInputStream(new byte[0]), + new AudioFormat(44100.0f, 16, 2, true, false), 441000); + + AudioFormat theAudioFormat = theAudioInputStream.getFormat(); + + DataLine.Info info = new DataLine.Info(Clip.class, theAudioFormat, + AudioSystem.NOT_SPECIFIED); + try { + theClip = (Clip) AudioSystem.getLine(info); + theClip.open(theAudioInputStream); + FloatControl theFloatControl = (FloatControl) (theClip.getControl( + FloatControl.Type.MASTER_GAIN)); + float theFloatControlPrecision = theFloatControl.getPrecision(); + System.out.println( + "theFloatControlPrecision: " + theFloatControlPrecision); + System.out.println("Minimum: " + theFloatControl.getMinimum()); + System.out.println("Maximum: " + theFloatControl.getMaximum()); + System.out.println("Value : " + theFloatControl.getValue()); + testPassed = theFloatControlPrecision > 0; + } catch (LineUnavailableException e) { + e.printStackTrace(); + testPassed = true; + } catch (Exception e) { + e.printStackTrace(); + testPassed = false; + } + return testPassed; + } + + //_______________________________________________ + // Method: main + //_______________________________________________ + public static void main(String[] args) throws Exception { + //test047 thisTest = new test047(); + if (isSoundcardInstalled()) { + FloatControlBug thisTest = new FloatControlBug(); + boolean testResult = thisTest.runTest(); + if (testResult) { + System.out.println("Test passed"); + } else { + System.out.println("Test failed"); + throw new Exception("Test failed"); + } + } + } + + /** + * Returns true if at least one soundcard is correctly installed + * on the system. + */ + public static boolean isSoundcardInstalled() { + boolean result = false; + try { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + if (mixers.length > 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: " + e); + } + if (!result) { + System.err.println( + "Soundcard does not exist or sound drivers not installed!"); + System.err.println( + "This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:41:11.000000000 +0300 +++ new/test/javax/sound/sampled/DataLine/DataLineInfoNegBufferSize.java 2016-10-24 21:41:10.000000000 +0300 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2004, 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 5021234 + * @summary Using -2 for buffer size will fail retrieval of lines + */ +public class DataLineInfoNegBufferSize { + + /** + * returns: + * 0: OK + * 1: IAE + * 2: other exception + * 3: line not available + */ + public static int run(Mixer m, int bufferSize) { + int res; + int frameCount = 441000; // lets say 10 seconds + AudioFormat f = new AudioFormat(44100.0f, 16, 2, true, false); + Clip clip = null; + try { + System.out.println("Requesting clip from Mixer " + +(m==null?"default":m.toString()) + +" with bufferSize"+bufferSize); + DataLine.Info info = new DataLine.Info(Clip.class, f, bufferSize); + if (m==null) { + clip = (Clip) AudioSystem.getLine(info); + } else { + clip = (Clip) m.getLine(info); + } + System.out.println("Got clip: "+clip+" with Buffer size "+clip.getBufferSize()); + + res = 0; + } catch (LineUnavailableException luae) { + System.out.println(luae); + res = 3; // line not available + } catch (IllegalArgumentException iae) { + System.out.println(iae); + res = 1; + } catch (Throwable t) { + System.out.println("->Exception:"+t); + t.printStackTrace(); + res=2; // other exception + } + return res; + } + + public static void main(String[] args) throws Exception { + if (isSoundcardInstalled()) { + int res=0; + int count = 0; + Mixer.Info[] infos = AudioSystem.getMixerInfo(); + for (int i = -1; i 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:41:11.000000000 +0300 +++ new/test/javax/sound/sampled/DataLine/LineDefFormat.java 2016-10-24 21:41:11.000000000 +0300 @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2004, 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * @test + * @bug 5053380 + * @summary Verify that getting a line initializes it with the format in + * DataLine.Info + */ +public class LineDefFormat { + + final static int samplerate = 22050; + static int passed = 0; + static int failed = 0; + + private static void doLine1(DataLine line, AudioFormat format) { + try { + System.out.println(" - got line: "+line); + System.out.println(" - line has format: "+line.getFormat()); + if (!line.getFormat().matches(format)) { + System.out.println(" ## Error: expected this format: "+format); + failed++; + } else { + passed++; + } + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + } + } + + private static void doLine2(DataLine line, AudioFormat format) { + try { + System.out.println(" - call to open()"); + line.open(); + try { + System.out.println(" - line has format: "+line.getFormat()); + if (!line.getFormat().matches(format)) { + System.out.println("## Error: expected this format: "+format); + failed++; + } else { + passed++; + } + } finally { + line.close(); + System.out.println(" - closed"); + } + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + } + } + + private static void doMixerClip(Mixer mixer, AudioFormat format) { + if (mixer==null) return; + try { + System.out.println("Clip from mixer "+mixer+":"); + System.out.println(" "+mixer.getMixerInfo()); + DataLine.Info info = new DataLine.Info( + Clip.class, + format); + + if (mixer.isLineSupported(info)) { + Clip clip = (Clip) mixer.getLine(info); + doLine1(clip, format); + } else { + System.out.println(" - Line not supported"); + } + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + } + } + + private static void doMixerSDL(Mixer mixer, AudioFormat format) { + if (mixer==null) return; + try { + System.out.println("SDL from mixer "+mixer+":"); + DataLine.Info info = new DataLine.Info( + SourceDataLine.class, + format); + + if (mixer.isLineSupported(info)) { + SourceDataLine sdl = (SourceDataLine) mixer.getLine(info); + doLine1(sdl, format); + doLine2(sdl, format); + } else { + System.out.println(" - Line not supported"); + } + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + } + } + + private static void doMixerTDL(Mixer mixer, AudioFormat format) { + if (mixer==null) return; + try { + System.out.println("TDL from mixer "+mixer+":"); + DataLine.Info info = new DataLine.Info( + TargetDataLine.class, + format); + if (mixer.isLineSupported(info)) { + TargetDataLine tdl = (TargetDataLine) mixer.getLine(info); + doLine1(tdl, format); + doLine2(tdl, format); + } else { + System.out.println(" - Line not supported"); + } + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + } + } + + private static void doAll() throws Exception { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + AudioFormat pcm; + for (int i=0; i 100) { + failed = true; + System.out.println("## FAILED: frame positions are not the same!"); + } + } finally { + sdl.close(); + } + } catch(LineUnavailableException e){ + System.out.println(e); + System.out.println("Cannot execute test."); + return; + } + if (failed) throw new Exception("Test FAILED!"); + System.out.println("Test Passed."); + } +} --- /dev/null 2016-10-24 21:41:13.000000000 +0300 +++ new/test/javax/sound/sampled/DirectAudio/TickAtEndOfPlay.java 2016-10-24 21:41:13.000000000 +0300 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2004, 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.SourceDataLine; + +/** + * @test + * @bug 5001959 + * @summary Short tick sound after finished playing with SourceDataLine + * @run main/manual TickAtEndOfPlay + */ +public class TickAtEndOfPlay { + + static boolean WorkAround1 = false; + static boolean WorkAround2 = false; + + public static void main(String[] args) throws Exception { + System.out.println("This test should only be run on Windows."); + System.out.println("Make sure that the speakers are connected and the volume is up."); + System.out.println("Close all other programs that may use the soundcard."); + + System.out.println("You'll hear a 2-second tone. when the tone finishes,"); + System.out.println(" there should be no noise. If you hear a short tick/noise,"); + System.out.println(" the bug still applies."); + + System.out.println("Press ENTER to continue."); + System.in.read(); + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("1")) WorkAround1 = true; + if (args[i].equals("2")) WorkAround2 = true; + } + if (WorkAround1) System.out.println("Using work around1: appending silence"); + if (WorkAround2) System.out.println("Using work around2: waiting before close"); + + int zerolen = 0; // how many 0-bytes will be appended to playback + if (WorkAround1) zerolen = 1000; + int seconds = 2; + int sampleRate = 8000; + double frequency = 1000.0; + double RAD = 2.0 * Math.PI; + AudioFormat af = new AudioFormat((float)sampleRate,8,1,true,true); + System.out.println("Format: "+af); + DataLine.Info info = new DataLine.Info(SourceDataLine.class,af); + SourceDataLine source = (SourceDataLine)AudioSystem.getLine(info); + System.out.println("Line: "+source); + if (source.toString().indexOf("MixerSourceLine")>=0) { + System.out.println("This test only applies to non-Java Sound Audio Engine!"); + return; + } + System.out.println("Opening..."); + source.open(af); + System.out.println("Starting..."); + source.start(); + int datalen = sampleRate * seconds; + byte[] buf = new byte[datalen+zerolen]; + for (int i=0; i 0 && !stopRequested) { + int avail = line.available(); + if (avail > 0) { + if (avail > remaining) + avail = remaining; + int written = line.write(data, data.length - remaining, avail); + remaining -= written; + log("WriteThread: " + written + " bytes written"); + } else { + delay(100); + } + } + if (remaining == 0) { + log("WriteThread: all data has been written, draining"); + line.drain(); + } else { + log("WriteThread: stop requested"); + } + log("WriteThread: stopping"); + line.stop(); + log("WriteThread: exiting"); + } + + public boolean isCompleted() { + return (remaining <= 0); + } + + public void requestStop() { + stopRequested = true; + } + } + + void testPlayback() throws LineUnavailableException { + // prepare audio data + AudioFormat format = new AudioFormat(22050, 8, 1, false, false); + byte[] soundData = new byte[(int) (format.getFrameRate() * format.getFrameSize() * DATA_LENGTH)]; + + // create & open source data line + //SourceDataLine line = AudioSystem.getSourceDataLine(format); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); + SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info); + + line.open(format); + + // start write data thread + WriteThread p1 = new WriteThread(line, soundData); + p1.start(); + + // start line + PlayThread p2 = new PlayThread(line); + p2.start(); + + // monitor line + long lineTime1 = line.getMicrosecondPosition() / 1000; + long realTime1 = currentTimeMillis(); + while (true) { + delay(500); + if (!line.isActive()) { + log("audio data played completely"); + break; + } + long lineTime2 = line.getMicrosecondPosition() / 1000; + long realTime2 = currentTimeMillis(); + long dLineTime = lineTime2 - lineTime1; + long dRealTime = realTime2 - realTime1; + log("line pos: " + lineTime2 + "ms" + ", thread is " + (p2.isAlive() ? "alive" : "DIED")); + if (dLineTime < 0) { + throw new RuntimeException("ERROR: line position have decreased from " + lineTime1 + " to " + lineTime2); + } + if (dRealTime < 450) { + // delay() has been interrupted? + continue; + } + lineTime1 = lineTime2; + realTime1 = realTime2; + } + } + + + // recording test classes/routines + + class RecordThread extends Thread { + TargetDataLine line; + public RecordThread(TargetDataLine line) { + this.line = line; + this.setDaemon(true); + } + + public void run() { + log("RecordThread: starting..."); + line.start(); + log("RecordThread: delaying " + (PLAYTHREAD_DELAY * 1000) + "ms..."); + delay(PLAYTHREAD_DELAY * 1000); + log("RecordThread: exiting..."); + } + } + + class ReadThread extends Thread { + TargetDataLine line; + byte[] data; + volatile int remaining; + public ReadThread(TargetDataLine line, byte[] data) { + this.line = line; + this.data = data; + remaining = data.length; + this.setDaemon(true); + } + + public void run() { + log("ReadThread: buffer size is " + data.length + " bytes"); + delay(200); + while ((remaining > 0) && line.isOpen()) { + int avail = line.available(); + if (avail > 0) { + if (avail > remaining) + avail = remaining; + int read = line.read(data, data.length - remaining, avail); + remaining -= read; + log("ReadThread: " + read + " bytes read"); + } else { + delay(100); + } + if (remaining <= 0) { + log("ReadThread: record buffer is full, exiting"); + break; + } + } + if (remaining > 0) { + log("ReadThread: line has been stopped, exiting"); + } + } + + public int getCount() { + return data.length - remaining; + } + public boolean isCompleted() { + return (remaining <= 0); + } + } + + void testRecord() throws LineUnavailableException { + // prepare audio data + AudioFormat format = new AudioFormat(22050, 8, 1, false, false); + + // create & open target data line + //TargetDataLine line = AudioSystem.getTargetDataLine(format); + DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); + TargetDataLine line = (TargetDataLine)AudioSystem.getLine(info); + + line.open(format); + + // start read data thread + byte[] data = new byte[(int) (format.getFrameRate() * format.getFrameSize() * DATA_LENGTH)]; + ReadThread p1 = new ReadThread(line, data); + p1.start(); + + // start line + //new RecordThread(line).start(); + RecordThread p2 = new RecordThread(line); + p2.start(); + + // monitor line + long endTime = currentTimeMillis() + DATA_LENGTH * 1000; + + long realTime1 = currentTimeMillis(); + long lineTime1 = line.getMicrosecondPosition() / 1000; + + while (realTime1 < endTime && !p1.isCompleted()) { + delay(100); + long lineTime2 = line.getMicrosecondPosition() / 1000; + long realTime2 = currentTimeMillis(); + long dLineTime = lineTime2 - lineTime1; + long dRealTime = realTime2 - realTime1; + log("line pos: " + lineTime2 + "ms" + ", thread is " + (p2.isAlive() ? "alive" : "DIED")); + if (dLineTime < 0) { + line.stop(); + line.close(); + throw new RuntimeException("ERROR: line position have decreased from " + lineTime1 + " to " + lineTime2); + } + if (dRealTime < 450) { + // delay() has been interrupted? + continue; + } + lineTime1 = lineTime2; + realTime1 = realTime2; + } + log("stopping line..."); + line.stop(); + line.close(); + + /* + log(""); + log(""); + log(""); + log("recording completed, delaying 5 sec"); + log("recorded " + p1.getCount() + " bytes, " + DATA_LENGTH + " seconds: " + (p1.getCount() * 8 / DATA_LENGTH) + " bit/sec"); + log(""); + log(""); + log(""); + delay(5000); + log("starting playing..."); + playRecorded(format, data); + */ + } + + void playRecorded(AudioFormat format, byte[] data) throws Exception { + //SourceDataLine line = AudioSystem.getSourceDataLine(format); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); + SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info); + + line.open(); + line.start(); + + int remaining = data.length; + while (remaining > 0) { + int avail = line.available(); + if (avail > 0) { + if (avail > remaining) + avail = remaining; + int written = line.write(data, data.length - remaining, avail); + remaining -= written; + log("Playing: " + written + " bytes written"); + } else { + delay(100); + } + } + + line.drain(); + line.stop(); + } + + // helper routines + static long startTime = currentTimeMillis(); + static long currentTimeMillis() { + //return System.nanoTime() / 1000000L; + return System.currentTimeMillis(); + } + static void log(String s) { + long time = currentTimeMillis() - startTime; + long ms = time % 1000; + time /= 1000; + long sec = time % 60; + time /= 60; + long min = time % 60; + time /= 60; + System.out.println("" + + (time < 10 ? "0" : "") + time + + ":" + (min < 10 ? "0" : "") + min + + ":" + (sec < 10 ? "0" : "") + sec + + "." + (ms < 10 ? "00" : (ms < 100 ? "0" : "")) + ms + + " (" + Thread.currentThread().getName() + ") " + s); + } + static void delay(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) {} + } +} --- /dev/null 2016-10-24 21:41:14.000000000 +0300 +++ new/test/javax/sound/sampled/FileTypeExtension/FileTypeExtensionTest.java 2016-10-24 21:41:14.000000000 +0300 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000, 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.AudioFileFormat; + +/** + * @test + * @bug 4300529 + * @summary Filename extension test. The filename extensions for file types + * AIFF-C, SND, and WAVE should not include a ".". + */ +public class FileTypeExtensionTest { + + public static void main(String[] args) throws Exception { + + AudioFileFormat.Type[] types = { AudioFileFormat.Type.AIFC, + AudioFileFormat.Type.AIFF, + AudioFileFormat.Type.AU, + AudioFileFormat.Type.SND, + AudioFileFormat.Type.WAVE }; + + boolean failed = false; + + System.out.println("\nDefined file types and extensions:"); + + for (int i = 0; i < types.length; i++) { + System.out.println("\n"); + System.out.println(" file type: " + types[i]); + System.out.println(" extension: " + types[i].getExtension()); + if( types[i].getExtension().charAt(0) == '.' ) { + failed = true; + } + } + + if (failed) { + System.err.println("Failed!"); + throw new Exception("File type extensions begin with ."); + } else { + System.err.println("Passed!"); + } + } +} --- /dev/null 2016-10-24 21:41:15.000000000 +0300 +++ new/test/javax/sound/sampled/LineEvent/LineInfoNPE.java 2016-10-24 21:41:15.000000000 +0300 @@ -0,0 +1,177 @@ +/* + * 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.Control; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; + +/** + * @test + * @bug 4672865 + * @summary LineEvent.toString() throws unexpected NullPointerException + */ +public class LineInfoNPE { + + static final int STATUS_PASSED = 0; + static final int STATUS_FAILED = 2; + static final int STATUS_TEMP = 95; + + public static void main(String argv[]) throws Exception { + int testExitStatus = run(argv, System.out); + if (testExitStatus != STATUS_PASSED) { + throw new Exception("test FAILED!"); + } + } + + public static int run(String argv[], java.io.PrintStream out) { + int testResult = STATUS_PASSED; + + out.println("\n==> Test for LineEvent class:"); + + Line testLine = new TestLine(); + Line nullLine = null; + + LineEvent.Type testLineEventType = LineEvent.Type.OPEN; + LineEvent.Type nullLineEventType = null; + + LineEvent testedLineEvent = null; + out.println("\n>> LineEvent constructor for Line = null: "); + try { + testedLineEvent = + new LineEvent(nullLine, // the source Line of this event + testLineEventType, // LineEvent.Type - the event type + (long) 1000 // position - the number processed of sample frames + ); + out.println("> No any Exception was thrown!"); + out.println("> testedLineEvent.getType():"); + try { + Line producedLine = testedLineEvent.getLine(); + out.println("> PASSED: producedLine = " + producedLine); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + out.println("> testedLineEvent.toString():"); + try { + String producedString = testedLineEvent.toString(); + out.println("> PASSED: producedString = " + producedString); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + } catch (IllegalArgumentException illegArgExcept) { + out.println("> PASSED: expected IllegalArgumentException was thrown:"); + illegArgExcept.printStackTrace(out); + } catch (NullPointerException nullPE) { + out.println("> PASSED: expected NullPointerException was thrown:"); + nullPE.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println("\n>> LineEvent constructor for LineEvent.Type = null: "); + try { + testedLineEvent = + new LineEvent(testLine, // the source Line of this event + nullLineEventType, // LineEvent.Type - the event type + (long) 1000 // position - the number processed of sample frames + ); + out.println("> No any Exception was thrown!"); + out.println("> testedLineEvent.getType():"); + try { + LineEvent.Type producedType = testedLineEvent.getType(); + out.println("> PASSED: producedType = " + producedType); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + out.println("> testedLineEvent.toString():"); + try { + String producedString = testedLineEvent.toString(); + out.println("> PASSED: producedString = " + producedString); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + } catch (IllegalArgumentException illegArgExcept) { + out.println("> PASSED: expected IllegalArgumentException was thrown:"); + illegArgExcept.printStackTrace(out); + } catch (NullPointerException nullPE) { + out.println("> PASSED: expected NullPointerException was thrown:"); + nullPE.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## FAILED: unexpected Exception was thrown:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + if ( testResult == STATUS_FAILED ) { + out.println("\n==> test FAILED!"); + } else { + out.println("\n==> test PASSED!"); + } + return testResult; + } +} // end of test class + +class TestLine implements Line { + + public void addLineListener(LineListener listener) { + } + + public void close() { + } + + public Control getControl(Control.Type control) { + return null; + } + + public Control[] getControls() { + return new Control[0]; + } + + public Line.Info getLineInfo() { + return null; + } + + public boolean isOpen() { + return false; + } + + public boolean isControlSupported(Control.Type control) { + return false; + } + + public void open() { + } + + public void removeLineListener(LineListener listener) { + } +} --- /dev/null 2016-10-24 21:41:16.000000000 +0300 +++ new/test/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java 2016-10-24 21:41:15.000000000 +0300 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2001, 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * @test + * @bug 4479441 + * @summary Verify that the lines report 16KHz and 32KHz capability + */ +public class Has16and32KHz { + + public static boolean ok32=false; + public static boolean ok16=false; + + public static void showMixerLines(Line.Info[] lineinfo) { + for (int j = 0; j < lineinfo.length; j++) { + boolean isSDL=false; // SourceDataLine + Line.Info thisInfo=lineinfo[j]; + System.out.println(" " + thisInfo); + String impl=""; + if (thisInfo.getLineClass().equals(SourceDataLine.class)) { + isSDL=true; + impl+="SourceDataLine"; + } + if (thisInfo.getLineClass().equals(Clip.class)) { + impl+="Clip"; + } + if (thisInfo.getLineClass().equals(DataLine.class)) { + impl+="DataLine"; + } + if (thisInfo.getLineClass().equals(TargetDataLine.class)) { + impl+="TargetDataLine"; + } + if (thisInfo.getLineClass().equals(Mixer.class)) { + impl+="Mixer"; + } + System.out.println(" implements "+impl); + try { + AudioFormat[] formats = ((DataLine.Info)lineinfo[j]).getFormats(); + for (int k = 0; k < formats.length; k++) { + System.out.println(" " + formats[k] + ", "+ formats[k].getFrameSize()+" bytes/frame"); + if (isSDL) { + if ((formats[k].getSampleRate()==AudioSystem.NOT_SPECIFIED) + || (formats[k].getSampleRate()==32000.0f)) { + ok32=true; + } + if ((formats[k].getSampleRate()==AudioSystem.NOT_SPECIFIED) + || (formats[k].getSampleRate()==16000.0f)) { + ok16=true; + } + } + } + } catch (ClassCastException e) { + } + } + } + + public static void main(String[] args) throws Exception { + boolean res=true; + + Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); + System.out.println(mixerInfo.length+" mixers on system."); + if (mixerInfo.length == 0) { + System.out.println("Cannot execute test. Not Failed!"); + } else { + for (int i = 0; i < mixerInfo.length; i++) { + Mixer mixer = AudioSystem.getMixer(mixerInfo[i]); + System.out.println(); + System.out.println(mixer+":"); + showMixerLines(mixer.getSourceLineInfo()); + showMixerLines(mixer.getTargetLineInfo()); + + + } + res=ok16 && ok32; + } + if (res) { + System.out.println("Test passed"); + } else { + System.out.println("Test failed"); + throw new Exception("Test failed"); + } + //ystem.exit(res?0:1); + } +} --- /dev/null 2016-10-24 21:41:16.000000000 +0300 +++ new/test/javax/sound/sampled/Lines/BufferSizeCheck.java 2016-10-24 21:41:16.000000000 +0300 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2002, 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.SourceDataLine; + +/** + * @test + * @bug 4661602 + * @summary Buffersize is checked when re-opening line + */ +public class BufferSizeCheck { + + public static void main(String[] args) throws Exception { + boolean realTest = false; + if (!isSoundcardInstalled()) { + return; + } + + try { + out("4661602: Buffersize is checked when re-opening line"); + AudioFormat format = new AudioFormat(44100, 16, 2, true, false); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); + SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info); + out("Opening with buffersize 12000..."); + sdl.open(format, 12000); + out("Opening with buffersize 11000..."); + realTest=true; + sdl.open(format, 11000); + try { + sdl.close(); + } catch(Throwable t) {} + } catch (Exception e) { + e.printStackTrace(); + // do not fail if no audio device installed - bug 4742021 + if (realTest || !(e instanceof LineUnavailableException)) { + throw e; + } + } + out("Test passed"); + } + + static void out(String s) { + System.out.println(s); System.out.flush(); + } + + /** + * Returns true if at least one soundcard is correctly installed + * on the system. + */ + public static boolean isSoundcardInstalled() { + boolean result = false; + try { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + if (mixers.length > 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } +} --- /dev/null 2016-10-24 21:41:17.000000000 +0300 +++ new/test/javax/sound/sampled/Lines/ChangingBuffer.java 2016-10-24 21:41:17.000000000 +0300 @@ -0,0 +1,165 @@ +/* + * 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; + +/** + * @test + * @bug 4515126 + * @summary Verify that the buffer passed to SourceDataLine.write() and + * Clip.open() will not be changed + */ +public class ChangingBuffer { + + final static int samplerate = 44100; + final static byte[] buffer = new byte[16384]; + static int successfulTests = 0; + + private static void makeBuffer() { + for (int i=0; i passed for this line"); + System.out.println(""); + } + + private static void checkBufferClip() throws Exception { + for (int i=0; i passed for this clip"); + System.out.println(""); + } + + private static boolean doMixerClip(Mixer mixer, AudioFormat format) { + if (mixer==null) return false; + try { + System.out.println("Trying mixer "+mixer+":"); + DataLine.Info info = new DataLine.Info( + Clip.class, + format, + (int) samplerate); + + Clip clip = (Clip) mixer.getLine(info); + System.out.println(" - got clip: "+clip); + System.out.println(" - open with format "+format); + clip.open(format, buffer, 0, buffer.length); + System.out.println(" - playing..."); + clip.start(); + System.out.println(" - waiting while it's active..."); + while (clip.isActive()) + Thread.sleep(100); + System.out.println(" - waiting 100millis"); + Thread.sleep(100); + System.out.println(" - drain1"); + clip.drain(); + System.out.println(" - drain2"); + clip.drain(); + System.out.println(" - stop"); + clip.stop(); + System.out.println(" - close"); + clip.close(); + System.out.println(" - closed"); + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + return false; + } + return true; + } + + private static boolean doMixerSDL(Mixer mixer, AudioFormat format) { + if (mixer==null) return false; + try { + System.out.println("Trying mixer "+mixer+":"); + DataLine.Info info = new DataLine.Info( + SourceDataLine.class, + format, + (int) samplerate); + + SourceDataLine sdl = (SourceDataLine) mixer.getLine(info); + System.out.println(" - got sdl: "+sdl); + System.out.println(" - open with format "+format); + sdl.open(format); + System.out.println(" - start..."); + sdl.start(); + System.out.println(" - write..."); + sdl.write(buffer, 0, buffer.length); + Thread.sleep(200); + System.out.println(" - drain..."); + sdl.drain(); + System.out.println(" - stop..."); + sdl.stop(); + System.out.println(" - close..."); + sdl.close(); + System.out.println(" - closed"); + } catch (Throwable t) { + System.out.println(" - Caught exception. Not failed."); + System.out.println(" - "+t.toString()); + return false; + } + return true; + } + + private static void doAll(boolean bigEndian) throws Exception { + AudioFormat pcm = new AudioFormat( + AudioFormat.Encoding.PCM_SIGNED, + samplerate, 16, 1, 2, samplerate, bigEndian); + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + for (int i=0; i 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //DialogOrient + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test4218609.pass(); + } + else + { + Test4218609.fail(); + } + } + + }// TestDialog class --- /dev/null 2016-10-24 21:41:19.000000000 +0300 +++ new/test/javax/sound/sampled/Lines/ClipOpenException.java 2016-10-24 21:41:19.000000000 +0300 @@ -0,0 +1,148 @@ +/* + * 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.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * @test + * @bug 4679187 + * @summary Clip.open() throws unexpected Exceptions. verifies that clip, + * sourcedataline and targetdataline throw IllegalArgumentExcepotion if + * any field in the format is AudioFormat.NOT_SPECIFIED + */ +public class ClipOpenException { + static boolean failed = false; + + static byte[] audioData = new byte[2048]; + static AudioFormat[] formats = { + new AudioFormat(AudioSystem.NOT_SPECIFIED, + AudioSystem.NOT_SPECIFIED, + AudioSystem.NOT_SPECIFIED, + true, false), + new AudioFormat(0, 0, 0, true, false) + }; + static AudioFormat infoFormat = new AudioFormat(44100.0f, + 16, + 1, + true, false); + static DataLine.Info clipInfo = new DataLine.Info(Clip.class, infoFormat); + static DataLine.Info sdlInfo = new DataLine.Info(SourceDataLine.class, infoFormat); + static DataLine.Info tdlInfo = new DataLine.Info(TargetDataLine.class, infoFormat); + + + public static void print(String s) { + System.out.print(s); + } + public static void println(String s) { + System.out.println(s); + } + + public static void test(Line line) { + for (int format = 0; format < formats.length; format++) { + try { + println(" Opening the line with format "+(format+1)); + if (line instanceof Clip) { + ((Clip) line).open(formats[format], audioData, 0, audioData.length); + } else + if (line instanceof SourceDataLine) { + ((SourceDataLine) line).open(formats[format]); + } else + if (line instanceof TargetDataLine) { + ((TargetDataLine) line).open(formats[format]); + } else { + println(" Unknown type of line: "+line.getClass()); + return; + } + println(" No exception! not OK."); + failed = true; + } catch (IllegalArgumentException iae) { + println(" IllegalArgumentException: "+iae.getMessage()); + println(" OK"); + } catch (LineUnavailableException lue) { + println(" LineUnavailableException: "+lue.getMessage()); + println(" Probably incorrect, but may happen if the test system is correctly set up."); + } catch (Exception e) { + println(" Unexpected Exception: "+e.toString()); + println(" NOT OK!"); + failed = true; + } + println(" Closing line."); + line.close(); + } + } + + public static void main(String[] args) throws Exception { + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + int succMixers = 0; + println("Using formats: "); + for (int i = 0 ; i Test for SourceDataLine.write() method for not open and not started line:"); + + Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo(); + + if ( installedMixersInfo == null ) { + out.println("## AudioSystem.getMixerInfo() returned unexpected result:"); + out.println("# expected: an array of Mixer.Info objects (may be array of length 0);"); + out.println("# produced: null;"); + return STATUS_FAILED; + } + + if ( installedMixersInfo.length == 0 ) { + // there are no mixers installed on the system - so this testcase can not be tested + return STATUS_PASSED; + } + + Mixer testedMixer = null; + for (int i=0; i < installedMixersInfo.length; i++) { + try { + testedMixer = AudioSystem.getMixer(installedMixersInfo[i]); + } catch (SecurityException securityException) { + // installed Mixer is unavailable because of security restrictions + continue; + } catch (Throwable thrown) { + out.println("## AudioSystem.getMixer() threw unexpected exception:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + + try { + testedMixer.open(); + } catch (LineUnavailableException lineUnavailableException) { + // testedMixer is not available due to resource restrictions + continue; + } catch (SecurityException securityException) { + // testedMixer is not available due to security restrictions + continue; + } catch (Throwable thrown) { + out.println("## Mixer.open() threw unexpected exception:"); + out.println("# Mixer = " + testedMixer); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + Line.Info supportedSourceLineInfo[] = null; + try { + supportedSourceLineInfo = testedMixer.getSourceLineInfo(); + } catch (Throwable thrown) { + out.println("## Mixer.getSourceLineInfo() threw unexpected exception:"); + out.println("# Mixer = " + testedMixer); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + testedMixer.close(); + continue; + } + if ( supportedSourceLineInfo == null ) { + out.println("## Mixer.getSourceLineInfo() returned null array"); + out.println("# Mixer = " + testedMixer); + testResult = STATUS_FAILED; + testedMixer.close(); + continue; + } + out.println("\n>>> testedMixer["+i+"] = " + testedMixer); + out.println("\n>> supportedSourceLineInfo.length = " + supportedSourceLineInfo.length); + + for (int j=0; j < supportedSourceLineInfo.length; j++) { + Line.Info testSourceLineInfo = supportedSourceLineInfo[j]; + + Line testSourceLine = null; + try { + testSourceLine = testedMixer.getLine(testSourceLineInfo); + } catch (LineUnavailableException lineUnavailableException) { + // line is not available due to resource restrictions + continue; + } catch (SecurityException securityException) { + // line is not available due to security restrictions + continue; + } catch (Throwable thrown) { + out.println("## Mixer.getLine(Line.Info) threw unexpected Exception:"); + out.println("# Mixer = " + testedMixer); + out.println("# Line.Info = " + testSourceLineInfo); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + + out.println("\n> testSourceLineInfo["+j+"] = " + testSourceLineInfo); + out.println("> testSourceLine = " + testSourceLine); + if ( ! (testSourceLine instanceof SourceDataLine) ) { + out.println("> testSourceLine is not SourceDataLine"); + continue; + } + + SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine; + AudioFormat lineAudioFormat = testedSourceLine.getFormat(); + + int bufferSizeToWrite = 1; + if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) { + bufferSizeToWrite = lineAudioFormat.getSampleSizeInBits()/8; + if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) { + bufferSizeToWrite++; + } + } + if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) { + bufferSizeToWrite = lineAudioFormat.getFrameSize(); + } + byte[] dataToWrite = new byte[bufferSizeToWrite]; + for (int k=0; k < bufferSizeToWrite; k++) { + dataToWrite[k] = (byte)1; + } + int offsetToWrite = 0; + + out.println + ("\n> check SourceDataLine.write() for not open line with correct length of data:"); + int writtenBytes = -1; + try { + writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite); + out.println("> Bytes written: number of written bytes = " + writtenBytes); + } catch (Throwable thrown) { + out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:"); + out.println("# Unexpected Exception is thrown"); + out.println("# Mixer = " + testedMixer); + out.println("# SourceDataLine = " + testedSourceLine); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println + ("\n> check SourceDataLine.write() for not open line with incorrect length of data:"); + writtenBytes = -1; + bufferSizeToWrite--; + try { + writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite); + out.println("> Bytes written: number of written bytes = " + writtenBytes); + } catch (IllegalArgumentException illegalArgumentException) { + out.println("> Permissible IllegalArgumentException for the present instance is thrown:"); + illegalArgumentException.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:"); + out.println("# Unexpected Exception is thrown"); + out.println("# Mixer = " + testedMixer); + out.println("# SourceDataLine = " + testedSourceLine); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println + ("\n> open tested line:"); + bufferSizeToWrite++; + try { + testedSourceLine.open(lineAudioFormat, bufferSizeToWrite); + out.println("> OK - line is opened"); + } catch (LineUnavailableException lineUnavailableException) { + out.println("> Line is not available due to resource restrictions:"); + lineUnavailableException.printStackTrace(out); + continue; + } catch (SecurityException securityException) { + out.println("> Line is not available due to security restrictions:"); + securityException.printStackTrace(out); + continue; + } catch (Throwable thrown) { + out.println("## SourceDataLine.open(AudioFormat format) failed:"); + out.println("# Unexpected Exception is thrown"); + out.println("# Mixer = " + testedMixer); + out.println("# SourceDataLine = " + testedSourceLine); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + + out.println + ("\n> check SourceDataLine.write() for not started line with correct length of data:"); + writtenBytes = -1; + try { + writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite); + out.println("> Bytes written: number of written bytes = " + writtenBytes); + } catch (Throwable thrown) { + out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:"); + out.println("# Unexpected Exception is thrown"); + out.println("# Mixer = " + testedMixer); + out.println("# SourceDataLine = " + testedSourceLine); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + out.println + ("\n> check SourceDataLine.write() for not started line with incorrect length of data:"); + writtenBytes = -1; + bufferSizeToWrite--; + try { + writtenBytes = testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite); + out.println("> Bytes written: number of written bytes = " + writtenBytes); + } catch (IllegalArgumentException illegalArgumentException) { + out.println("> Permissible IllegalArgumentException for the present instance is thrown:"); + illegalArgumentException.printStackTrace(out); + } catch (Throwable thrown) { + out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:"); + out.println("# Unexpected Exception is thrown"); + out.println("# Mixer = " + testedMixer); + out.println("# SourceDataLine = " + testedSourceLine); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + testedSourceLine.close(); + + } // for (int j=0; j < supportedSourceLineInfo.length; j++) + testedMixer.close(); + + } // for (int i=0; i < installedMixersInfo.length; i++) + + if ( testResult == STATUS_FAILED ) { + out.println("\n==> test FAILED!"); + } else { + out.println("\n==> test PASSED!"); + } + return testResult; + } +} --- /dev/null 2016-10-24 21:41:22.000000000 +0300 +++ new/test/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java 2016-10-24 21:41:22.000000000 +0300 @@ -0,0 +1,248 @@ +/* + * 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.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; + +/** + * @test + * @bug 4681384 + * @summary SourceDataLine.write() causes Unexpected Signal 11 in native code + * outside the VM + */ +public class SourceDataLineDefaultBufferSizeCrash { + + static final int STATUS_PASSED = 0; + static final int STATUS_FAILED = 2; + static final int STATUS_TEMP = 95; + + public static void main(String argv[]) throws Exception { + int testExitStatus = run(argv, System.out) + STATUS_TEMP; + } + + public static int run(String argv[], java.io.PrintStream out) throws Exception { + int testResult = STATUS_PASSED; + + int framesNumberToExceed = 2; + if ( argv.length > 0 ) { + try { + framesNumberToExceed = Integer.parseInt(argv[0]); + } + catch (NumberFormatException e) { + } + } + + out.println + ("\n==> Test for SourceDataLine.write() method:"); + + Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo(); + + if ( installedMixersInfo == null ) { + out.println("## AudioSystem.getMixerInfo() returned unexpected result:"); + out.println("# expected: an array of Mixer.Info objects (may be array of length 0);"); + out.println("# produced: null;"); + return STATUS_FAILED; + } + + if ( installedMixersInfo.length == 0 ) { + // there are no mixers installed on the system - + // so this testcase can not be tested + out.println("\n>>> There are no mixers installed on the system!"); + return STATUS_PASSED; + } + + out.println("\n>>> Number of mixers installed on the system = " + + installedMixersInfo.length); + Mixer installedMixer = null; + for (int i=0; i < installedMixersInfo.length; i++) { + try { + installedMixer = AudioSystem.getMixer(installedMixersInfo[i]); + } catch (SecurityException securityException) { + // installed Mixer is unavailable because of security restrictions + out.println("\n>>> installedMixer[" + i + + "] is unavailable because of security restrictions"); + continue; + } catch (Throwable thrown) { + out.println("\n## installedMixer[" + i + "] is unavailable because of"); + out.println("# AudioSystem.getMixer() threw unexpected exception:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + + out.println("\n>>> installedMixer["+i+"] = " + installedMixer); + try { + installedMixer.open(); + } catch (LineUnavailableException lineUnavailableException) { + // installedMixer is not available due to resource restrictions + out.println(">> installedMixer[" + i + + "] is not opened because of resource restrictions"); + continue; + } catch (SecurityException securityException) { + // installedMixer is not available due to security restrictions + out.println(">> installedMixer[" + i + + "] is not opened because of security restrictions"); + continue; + } catch (Throwable thrown) { + out.println("## installedMixer.open() throws unexpected exception:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + Line.Info supportedSourceLineInfo[] = null; + try { + supportedSourceLineInfo = installedMixer.getSourceLineInfo(); + } catch (Throwable thrown) { + out.println("## installedMixer.getSourceLineInfo() throws " + + "unexpected exception:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + installedMixer.close(); + continue; + } + if ( supportedSourceLineInfo == null ) { + out.println("## installedMixer.getSourceLineInfo() returned null array"); + out.println("# Mixer = " + installedMixer); + testResult = STATUS_FAILED; + installedMixer.close(); + continue; + } + out.println("\n>> Number of SourceLineInfo supported by installedMixer =" + + supportedSourceLineInfo.length); + + for (int j=0; j < supportedSourceLineInfo.length; j++) { + Line.Info testSourceLineInfo = supportedSourceLineInfo[j]; + + out.println("\n> testSourceLineInfo["+j+"] = " + testSourceLineInfo); + Line testSourceLine = null; + try { + testSourceLine = installedMixer.getLine(testSourceLineInfo); + } catch (LineUnavailableException lineUnavailableException) { + // line is not available due to resource restrictions + out.println("> Line for this SourceLine Info is not available " + + "due to resource restrictions"); + continue; + } catch (SecurityException securityException) { + // line is not available due to security restrictions + out.println("> Line for this SourceLine Info is not available " + + "due to security restrictions"); + continue; + } catch (Throwable thrown) { + out.println("## installedMixer.getLine(testSourceLineInfo) throws" + + "unexpected Exception:"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + + out.println("> testedSourceLine = " + testSourceLine); + if ( ! (testSourceLine instanceof SourceDataLine) ) { + out.println("> testSourceLine is not SourceDataLine"); + continue; + } + + SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine; + AudioFormat lineAudioFormat = testedSourceLine.getFormat(); + + out.println("\n> opening tested SourceLine:"); + try { + //testedSourceLine.open(lineAudioFormat, 2048); + testedSourceLine.open(lineAudioFormat); + out.println("> OK - line is opened with "+testedSourceLine.getBufferSize()+" bytes buffer"); + } catch (LineUnavailableException lineUnavailableException) { + out.println("> Line is not available due to resource restrictions:"); + lineUnavailableException.printStackTrace(out); + continue; + } catch (SecurityException securityException) { + out.println("> Line is not available due to security restrictions:"); + securityException.printStackTrace(out); + continue; + } catch (Throwable thrown) { + out.println("## SourceDataLine.open(AudioFormat format) failed:"); + out.println("# Unexpected Exception is thrown"); + out.println("# Mixer = " + installedMixer); + out.println("# SourceDataLine = " + testedSourceLine); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + continue; + } + + testedSourceLine.start(); + + int frameSize = 1; + if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) { + frameSize = lineAudioFormat.getFrameSize(); + } else { + if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) { + frameSize = lineAudioFormat.getSampleSizeInBits()/8; + if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) { + frameSize++; + } + } + } + int bufferSizeToWrite = testedSourceLine.available() + + (frameSize * framesNumberToExceed); + byte[] dataToWrite = new byte[bufferSizeToWrite]; + for (int k=0; k < bufferSizeToWrite; k++) { + dataToWrite[k] = (byte)1; + } + int offsetToWrite = 0; + + out.println("\n> check SourceDataLine.write() to write more data " + + "than can currently be written:"); + + out.println("> testedSourceLine.available() = " + testedSourceLine.available()); + out.println("> frame size = " + frameSize); + out.println("> number of bytes to write = " + bufferSizeToWrite); + int writtenBytes = -1; + try { + writtenBytes = + testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite); + out.println("> OK - number of written bytes = " + writtenBytes); + } catch (Throwable thrown) { + out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:"); + out.println("# Unexpected Exception is thrown"); + thrown.printStackTrace(out); + testResult = STATUS_FAILED; + } + + testedSourceLine.close(); + + } // for (int j=0; j < supportedSourceLineInfo.length; j++) + installedMixer.close(); + + } // for (int i=0; i < installedMixersInfo.length; i++) + + if ( testResult == STATUS_FAILED ) { + throw new Exception("Test FAILED!"); + } else { + out.println("\n==> test PASSED!"); + } + return testResult; + } + +} --- /dev/null 2016-10-24 21:41:23.000000000 +0300 +++ new/test/javax/sound/sampled/Lines/StopStart.java 2016-10-24 21:41:22.000000000 +0300 @@ -0,0 +1,282 @@ +/* + * 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 + * @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; i0) { + 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; i0) { + 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; i0) { + 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"); + } +} --- /dev/null 2016-10-24 21:41:23.000000000 +0300 +++ new/test/javax/sound/sampled/LinuxBlock/PlaySine.java 2016-10-24 21:41:23.000000000 +0300 @@ -0,0 +1,269 @@ +/* + * 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.io.IOException; + +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 + * @bug 4834461 + * @summary Applet hang when you load it during sound card is in use + * @run main/manual PlaySine + */ +public class PlaySine { + + static int sampleRate = 8000; + static double frequency = 2000.0; + static double RAD = 2.0 * Math.PI; + + static byte[] audioData = new byte[sampleRate/2]; + static SourceDataLine source; + static Mixer mixer = null; + + static AudioInputStream ais = null; + static AudioFormat audioFormat; + static String filename; + + public static void constructAIS() { + try { + ais = AudioSystem.getAudioInputStream(new File(filename)); + } catch (Exception e) { + println("ERROR: could not open "+filename+": "+e.getMessage()); + } + } + + public static void print(String s) { + System.out.print(s); + } + public static void println(String s) { + System.out.println(s); + } + + public static void key() { + println(""); + print("Press ENTER to continue..."); + try { + System.in.read(); + } catch (IOException ioe) { + } + } + + static int audioLen = -1; + static int audioOffset = -1; + + public static void writeData() { + if (audioLen == -1) { + audioLen = audioData.length; + } + if (audioOffset < 0) { + audioOffset = audioLen; + } + try { + if (audioOffset >= audioLen) { + audioOffset = 0; + if (ais!=null) { + do { + audioLen = ais.read(audioData, 0, audioData.length); + if (audioLen < 0) { + constructAIS(); + } + } while (audioLen < 0); + } + } + int toWrite = audioLen - audioOffset; + int written = source.write(audioData, audioOffset, toWrite); + audioOffset+=written; + } catch (Exception e) { + e.printStackTrace(); + } + } + + + public static int play(boolean shouldPlay) { + int res = 0; + DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); + try { + println("Getting line from mixer..."); + source = (SourceDataLine) mixer.getLine(info); + println("Opening line..."); + println(" -- if the program is hanging here, kill the process that has blocks the audio device now."); + source.open(audioFormat); + println("Starting line..."); + source.start(); + println("Writing audio data for 1 second..."); + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < 1000) { + writeData(); + Thread.sleep(100); + } + res = 1; + } catch (IllegalArgumentException iae) { + println("IllegalArgumentException: "+iae.getMessage()); + println("Sound device cannot handle this audio format."); + println("ERROR: Test environment not correctly set up."); + if (source!=null) { + source.close(); + } + return 3; + } catch (LineUnavailableException lue) { + println("LineUnavailableException: "+lue.getMessage()); + if (shouldPlay) { + println("ERROR: the line should be available now!."); + println(" Verify that you killed the other audio process."); + } else { + println("Correct behavior! the bug is fixed."); + } + res = 2; + } catch (Exception e) { + println("Unexpected Exception: "+e.toString()); + } + if (source != null) { + println("Draining..."); + try { + source.drain(); + } catch (NullPointerException npe) { + println("(NullPointerException: bug fixed in J2SE 1.4.2"); + } + println("Stopping..."); + source.stop(); + println("Closing..."); + source.close(); + source = null; + } + return res; + } + + public static void main(String[] args) throws Exception { + println("This is an interactive test. You can run it with a filename as argument"); + println("It is only meant to be run on linux, with the (old) OSS kernel drivers (/dev/dsp)"); + println("This test should not be run on systems with ALSA installed, or kernel 2.6 or higher."); + println(""); + println("The test verifies that Java Sound fails correctly if another process is blocking"); + println("the audio device."); + println(""); + println("Checking sanity..."); + Mixer.Info[] mixers=null; + + mixers = AudioSystem.getMixerInfo(); + for (int i=0; i=0 + && mixerName.indexOf("Engine")>=0) { + mixer = thisMixer; + break; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + if (mixer == null) { + if (mixers.length==0) { + System.out.println("ERROR: No mixers available!"); + } else { + println("ERROR: Java Sound Engine could not be found."); + } + println("Cannot run this test."); + return; + } + println(" ...using mixer "+mixer.getMixerInfo()); + + String osname = System.getProperty("os.name"); + if ((osname == null) || (osname.toLowerCase().indexOf("linux")<0)) { + println("ERROR: not running on linux (you are running on "+osname+")"); + return; + } + println(" ...running on "+osname); + println(" ...sanity test OK."); + + filename = null; + if (args.length>0) { + File f = new File(args[0]); + if (f.exists()) { + filename = args[0]; + println("Opening "+filename); + constructAIS(); + if (ais!=null) { + audioFormat = ais.getFormat(); + } + } + } + if (ais == null) { + println("Using self-generated sine wave for playback"); + audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true); + for (int i=0; i /dev/dsp"); + key(); + println("After you press ENTER now, the mixer will be opened."); + println("There are 3 possible cases that can occur:"); + println("1) you'll hear a sine wave"); + println(" -> you are running with mixing OSS drivers. "); + println(" Some soundcards only provide mixing OSS drivers."); + println(" Test environment not valid. "); + println(" Repeat on another machine where you can reproduce the bug first."); + println("2) this program stops doing anything after 'Opening line...'"); + println(" -> this is the bug."); + println(" Kill the command on the other console with Ctrl-C, this program"); + println(" should continue working then."); + println("3) this program reports a LineUnavailableException"); + println(" -> bug is fixed."); + println(" OR you run with non-blocking OSS drivers."); + println(" make sure that you can reproduce this bug first with e.g. J2SE 1.4.1"); + key(); + int playedFirst = play(false); + int playedSecond = 0; + + if (playedFirst == 2) { + println(""); + println("Now kill the other process with Ctrl-C."); + println("After that, this program should be able to play "); + println("the sine wave without problems."); + key(); + playedSecond = play(true); + } + println(""); + if (playedFirst == 1) { + println("Test FAILED."); + } + else if (playedFirst == 2 && playedSecond == 1) { + println("Test SUCCESSFUL"); + } else { + println("Test not failed (but not successful either...)."); + } + } +} --- /dev/null 2016-10-24 21:41:24.000000000 +0300 +++ new/test/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java 2016-10-24 21:41:24.000000000 +0300 @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; + +/** + * @test + * @bug 4498848 + * @summary Sound causes crashes on Linux (part 1) + */ +public class ClipLinuxCrash { + + static Clip clip; + + public static long bytes2Ms(long bytes, AudioFormat format) { + return (long) (bytes / format.getFrameRate() * 1000 + / format.getFrameSize()); + } + + static int staticLen = 1000; + + static boolean addLen = true; + + public static long start() throws Exception { + AudioFormat fmt = new AudioFormat(44100, 16, 2, true, false); + if (addLen) { + staticLen += (int) (staticLen / 5) + 1000; + } else { + staticLen -= (int) (staticLen / 5) + 1000; + } + if (staticLen > 8 * 44100 * 4) { + staticLen = 8 * 44100 * 4; + addLen = !addLen; + } + if (staticLen < 1000) { + staticLen = 1000; + addLen = !addLen; + } + int len = staticLen; + len -= (len % 4); + byte[] fakedata = new byte[len]; + InputStream is = new ByteArrayInputStream(fakedata); + AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, + 44100, 16, 2, 4, 44100, false); + AudioInputStream ais = new AudioInputStream(is, format, fakedata.length + / format.getFrameSize()); + + out(" preparing to play back " + len + " bytes == " + bytes2Ms(len, + format) + + "ms audio..."); + + DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat()); + clip = (Clip) AudioSystem.getLine(info); + clip.addLineListener(new LineListener() { + public void update(LineEvent e) { + if (e.getType() == LineEvent.Type.STOP) { + out(" calling close() from event dispatcher thread"); + ((Clip) e.getSource()).close(); + } else if (e.getType() == LineEvent.Type.CLOSE) { + } + } + }); + + out(" opening..."); + try { + clip.open(ais); + } catch (Throwable t) { + t.printStackTrace(); + clip.close(); + clip = null; + } + ais.close(); + if (clip != null) { + out(" starting..."); + clip.start(); + } + return bytes2Ms(fakedata.length, format); + } + + public static void main(String[] args) throws Exception { + if (AudioSystem.getMixerInfo().length == 0) { + System.out.println("Cannot execute test: no mixers installed!"); + System.out.println("Not Failed."); + return; + } + try { + int COUNT = 10; + out(); + out("4498848 Sound causes crashes on Linux (testing with Clip)"); + if (args.length > 0) { + COUNT = Integer.parseInt(args[0]); + } + for (int i = 0; i < COUNT; i++) { + out(" trial " + (i + 1) + "/" + COUNT); + start(); + int waitTime = 500 + (1000 * (i + % 2)); // every second + // time wait 1500, rather than 500ms. + out(" waiting for " + waitTime + + " ms for audio playback to stop..."); + Thread.sleep(waitTime); + out(" calling close() from main thread"); + if (clip != null) { + clip.close(); + } + // let the subsystem enough time to actually close the soundcard + out(" waiting for 2 seconds..."); + Thread.sleep(2000); + out(); + } + out(" waiting for 1 second..."); + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + out(" waiting for 1 second"); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + throw e; + } + out("Test passed"); + } + + static void out() { + out(""); + } + + static void out(String s) { + System.out.println(s); + System.out.flush(); + } + +} --- /dev/null 2016-10-24 21:41:25.000000000 +0300 +++ new/test/javax/sound/sampled/LinuxCrash/ClipLinuxCrash2.java 2016-10-24 21:41:24.000000000 +0300 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineEvent; +import javax.sound.sampled.LineListener; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4498848 + * @summary Sound causes crashes on Linux (part 3) + */ +public class ClipLinuxCrash2 implements LineListener{ + Clip clip; + int stopOccured; + static final Object lock = new Object(); + + public static long bytes2Ms(long bytes, AudioFormat format) { + return (long) (bytes/format.getFrameRate()*1000/format.getFrameSize()); + } + + static int staticLen=1000; + static boolean addLen=true; + + ClipLinuxCrash2() { + } + + public void update(LineEvent e) { + if (e.getType() == LineEvent.Type.STOP) { + stopOccured++; + out(" Test program: receives STOP event for clip="+clip.toString()+" no."+stopOccured); + out(" Test program: Calling close() in event dispatcher thread"); + clip.close(); + synchronized (lock) { + lock.notifyAll(); + } + } + else if (e.getType() == LineEvent.Type.CLOSE) { + out(" Test program: receives CLOSE event for "+clip.toString()); + synchronized (lock) { + lock.notifyAll(); + } + } + else if (e.getType() == LineEvent.Type.START) { + out(" Test program: receives START event for "+clip.toString()); + } + else if (e.getType() == LineEvent.Type.OPEN) { + out(" Test program: receives OPEN event for "+clip.toString()); + } + } + + public long start() throws Exception { + AudioFormat format = new AudioFormat(44100, 16, 2, true, false); + + if (addLen) { + staticLen+=(int) (staticLen/5)+1000; + } else { + staticLen-=(int) (staticLen/5)+1000; + } + if (staticLen>8*44100*4) { + staticLen = 8*44100*4; + addLen=!addLen; + } + if (staticLen<1000) { + staticLen = 1000; + addLen=!addLen; + } + int len = staticLen; + len -= (len % 4); + out(" Test program: preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio..."); + + byte[] fakedata=new byte[len]; + InputStream is = new ByteArrayInputStream(fakedata); + AudioInputStream ais = new AudioInputStream(is, format, fakedata.length/format.getFrameSize()); + + DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat()); + clip = (Clip) AudioSystem.getLine(info); + clip.addLineListener(this); + + out(" Test program: opening clip="+((clip==null)?"null":clip.toString())); + clip.open(ais); + ais.close(); + out(" Test program: starting clip="+((clip==null)?"null":clip.toString())); + clip.start(); + return bytes2Ms(fakedata.length, format); + } + + public static void main(String[] args) throws Exception { + if (!isSoundcardInstalled()) { + return; + } + + try { + int COUNT=10; + out(); + out("4498848 Sound causes crashes on Linux"); + if (args.length>0) { + COUNT=Integer.parseInt(args[0]); + } + for (int i=0; i 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } + +} --- /dev/null 2016-10-24 21:41:25.000000000 +0300 +++ new/test/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java 2016-10-24 21:41:25.000000000 +0300 @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2002, 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.LineEvent; +import javax.sound.sampled.LineListener; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; + +/** + * @test + * @bug 4498848 + * @summary Sound causes crashes on Linux (part 2) + */ +public class SDLLinuxCrash implements Runnable { + SourceDataLine sdl; + int size; + + SDLLinuxCrash(SourceDataLine sdl, int size) { + this.sdl = sdl; + this.size = size - (size % 4); + } + + public void run() { + int written=0; + //byte[] buffer = new byte[4096]; + byte[] buffer = data; + out(" starting data line feed thread."); + try { + while (written size) { + toWrite = size-written; + } + toWrite -= (toWrite % 4); + //out(" writing "+toWrite+" bytes."); + int thisWritten = sdl.write(buffer, 0, toWrite); + if (thisWritten8*44100*4) { + staticLen = 8*44100*4; + addLen=!addLen; + } + if (staticLen<1000) { + staticLen = 1000; + addLen=!addLen; + } + int len = staticLen; + len -= (len % 4); + out(" preparing to play back "+len+" bytes == "+bytes2Ms(len, format)+"ms audio..."); + + DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); + SourceDataLine sdl = (SourceDataLine) AudioSystem.getLine(info); + sdl.addLineListener(new LineListener() { + public void update(LineEvent e) { + if (e.getType() == LineEvent.Type.STOP) { + out(" calling close() from event dispatcher thread"); + ((SourceDataLine) e.getSource()).close(); + } + else if (e.getType() == LineEvent.Type.CLOSE) { + } + } + }); + + out(" opening..."); + sdl.open(); + out(" starting..."); + sdl.start(); + (new Thread(new SDLLinuxCrash(sdl, len))).start(); + return sdl; + } + + public static void main(String[] args) throws Exception { + if (!isSoundcardInstalled()) { + return; + } + + try { + int COUNT=10; + out(); + out("4498848 Sound causes crashes on Linux (testing with SourceDataLine)"); + if (args.length>0) { + COUNT=Integer.parseInt(args[0]); + } + for (int i=0; i 0) { + result = AudioSystem.getSourceDataLine(null) != null; + } + } catch (Exception e) { + System.err.println("Exception occured: "+e); + } + if (!result) { + System.err.println("Soundcard does not exist or sound drivers not installed!"); + System.err.println("This test requires sound drivers for execution."); + } + return result; + } + + + + static final byte[] data = new byte[] { + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, + 123, 110, 100, 60, 11, 10, 10, 10, 9, 9, + 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 60, 100, 110, 120, 122, 122 + }; + +} --- /dev/null 2016-10-24 21:41:26.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/BogusMixers.java 2016-10-24 21:41:26.000000000 +0300 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2002, 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.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4667064 + * @summary Java Sound provides bogus SourceDataLine and TargetDataLine + */ +public class BogusMixers { + + public static void main(String[] args) throws Exception { + try { + out("4667064: Java Sound provides bogus SourceDataLine and TargetDataLine"); + + Mixer.Info[] aInfos = AudioSystem.getMixerInfo(); + out(" available Mixers:"); + for (int i = 0; i < aInfos.length; i++) { + if (aInfos[i].getName().startsWith("Java Sound Audio Engine")) { + Mixer mixer = AudioSystem.getMixer(aInfos[i]); + Line.Info[] tlInfos = mixer.getTargetLineInfo(); + for (int ii = 0; ii 0) { + if (format.getSampleSizeInBits() == 8) { + // return the other signed'ness + if (isSigned) { + newEnc = AudioFormat.Encoding.PCM_UNSIGNED; + } else { + newEnc = AudioFormat.Encoding.PCM_SIGNED; + } + } else { + newEnc = format.getEncoding(); + newEndian = !newEndian; + } + if (newEnc != null) { + return new AudioFormat(newEnc, format.getSampleRate(), + format.getSampleSizeInBits(), + format.getChannels(), + format.getFrameSize(), + format.getFrameRate(), + newEndian); + } + } + return null; + } + + static void out(String s) { + System.out.println(s); System.out.flush(); + } +} --- /dev/null 2016-10-24 21:41:28.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/DirectSoundRepeatingBuffer.java 2016-10-24 21:41:27.000000000 +0300 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2004, 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.IOException; + +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.SourceDataLine; + +/** + * This is utility class for Test4997635. + */ +public class DirectSoundRepeatingBuffer { + + static int sampleRate = 8000; + static double frequency = 1000.0; + static double RAD = 2.0 * Math.PI; + + static byte[] audioData = new byte[sampleRate/8]; + static DataLine.Info info; + static SourceDataLine source; + + //static AudioInputStream ais = null; + static AudioFormat audioFormat; + //static String filename; + + public static void print(String s) { + System.out.print(s); + } + public static void println(String s) { + System.out.println(s); + } + + public static void key() { + println(""); + print("Press ENTER to continue..."); + try { + System.in.read(); + } catch (IOException ioe) { + } + println(""); + } + + public static void play(Mixer mixer) { + int res = 0; + try { + println("Getting SDL from mixer..."); + source = (SourceDataLine) mixer.getLine(info); + println("Opening SDL..."); + source.open(audioFormat); + println("Writing data to SDL..."); + source.write(audioData, 0, audioData.length); + println("Starting SDL..."); + source.start(); + println("Now open your ears:"); + println("- you should have heard a short tone,"); + println(" followed by silence."); + println("- if after a while you hear repeated tones,"); + println(" the bug is NOT fixed."); + println("- if the program remains silent after the "); + println(" initial tone, the bug is fixed."); + key(); + } catch (IllegalArgumentException iae) { + println("IllegalArgumentException: "+iae.getMessage()); + println("Sound device cannot handle this audio format."); + println("ERROR: Test environment not correctly set up."); + if (source!=null) { + source.close(); + source = null; + } + return; + } catch (LineUnavailableException lue) { + println("LineUnavailableException: "+lue.getMessage()); + println("This is normal for some mixers."); + } catch (Exception e) { + println("Unexpected Exception: "+e.toString()); + } + if (source != null) { + println("Stopping..."); + source.stop(); + println("Closing..."); + source.close(); + println("Closed."); + source = null; + } + } + + public static void main(String[] args) throws Exception { + println("This is an interactive test for DirectAudio."); + println("If the tone repeats, the test is failed."); + println(""); + println("Make sure that you have speakers connected"); + println("and that the system mixer is not muted."); + println(""); + println("Press a key to start the test."); + key(); + Mixer.Info[] mixers=null; + + println(" ...using self-generated sine wave for playback"); + audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true); + for (int i=0; inot a DirectAudio Mixer!"); + } else { + try { + Mixer mixer = AudioSystem.getMixer(mixers[i]); + if (!mixer.isLineSupported(info)) { + println(" ->doesn't support SourceDataLine!"); + } else { + succMixers++; + println(" -> is getting tested."); + play(mixer); + } + } catch (Exception e) { + println(" -> Exception occured: "+e); + e.printStackTrace(); + } + } + } + if (succMixers == 0) { + println("No DirectAudio mixers available! "); + println("Cannot run test."); + } + } +} --- /dev/null 2016-10-24 21:41:28.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java 2016-10-24 21:41:28.000000000 +0300 @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2004, 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.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @test + * @bug 4997635 + * @summary Win: SourceDataLine playback loops endlessly unless you manually + * stop() + * @build DirectSoundRepeatingBuffer + * @run main/manual Test4997635 + */ +public class Test4997635 { + + private static void init() throws Exception { + //*** Create instructions for the user here *** + + String[] instructions = + { + "To run the test follow these instructions:", + "1. Open a terminal window.", + "2. Type \"cd " + System.getProperty("test.classes") + "\".", + "3. Type \"" + System.getProperty("java.home") + "/bin/java DirectSoundRepeatingBuffer\".", + "4. Follow the instructions shown in the terminal window.", + "If no error occured during the test, and the java application ", + "in the termial exited successfully, press PASS, else press FAIL." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + } + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws Exception + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class Orient + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + Orient.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + Orient.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //DialogOrient + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test4997635.pass(); + } + else + { + Test4997635.fail(); + } + } + + }// TestDialog class --- /dev/null 2016-10-24 21:41:29.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/DirectSoundUnderrunSilence.java 2016-10-24 21:41:29.000000000 +0300 @@ -0,0 +1,161 @@ +/* + * 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.IOException; + +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.SourceDataLine; + +/** + * This is utility class for Test5032020. + */ +public class DirectSoundUnderrunSilence { + + static int sampleRate = 8000; + static double frequency = 1000.0; + static double RAD = 2.0 * Math.PI; + + static byte[] audioData = new byte[sampleRate/8]; + static DataLine.Info info; + static SourceDataLine source; + + //static AudioInputStream ais = null; + static AudioFormat audioFormat; + //static String filename; + + public static void print(String s) { + System.out.print(s); + } + public static void println(String s) { + System.out.println(s); + } + + public static void key() { + println(""); + print("Press ENTER to continue..."); + try { + System.in.read(); + } catch (IOException ioe) { + } + println(""); + } + + public static void play(Mixer mixer) { + int res = 0; + try { + println("Getting SDL from mixer..."); + source = (SourceDataLine) mixer.getLine(info); + println("Opening SDL..."); + source.open(audioFormat); + println("Writing data to SDL..."); + source.write(audioData, 0, audioData.length); + println("Starting SDL..."); + source.start(); + println("Now open your ears:"); + println("You should have heard a short tone,"); + println("followed by silence (no repeating tones)."); + key(); + source.write(audioData, 0, audioData.length); + println("Now you should have heard another short tone."); + println("If you did not hear a second tone, or more than 2 tones,"); + println("the test is FAILED."); + println("otherwise, if you heard a total of 2 tones, the bug is fixed."); + key(); + } catch (IllegalArgumentException iae) { + println("IllegalArgumentException: "+iae.getMessage()); + println("Sound device cannot handle this audio format."); + println("ERROR: Test environment not correctly set up."); + if (source!=null) { + source.close(); + source = null; + } + return; + } catch (LineUnavailableException lue) { + println("LineUnavailableException: "+lue.getMessage()); + println("This is normal for some mixers."); + } catch (Exception e) { + println("Unexpected Exception: "+e.toString()); + } + if (source != null) { + println("Stopping..."); + source.stop(); + println("Closing..."); + source.close(); + println("Closed."); + source = null; + } + } + + public static void main(String[] args) throws Exception { + println("This is an interactive test for DirectAudio."); + println("If it's impossible to play data after an underun, the test fails."); + println(""); + println("Make sure that you have speakers connected"); + println("and that the system mixer is not muted."); + println("Also stop all other programs playing sounds:"); + println("It has been seen that it alters the results."); + println(""); + println("Press a key to start the test."); + key(); + Mixer.Info[] mixers=null; + + println(" ...using self-generated sine wave for playback"); + audioFormat = new AudioFormat((float)sampleRate, 8, 1, true, true); + for (int i=0; inot a DirectAudio Mixer!"); + } else { + try { + Mixer mixer = AudioSystem.getMixer(mixers[i]); + if (!mixer.isLineSupported(info)) { + println(" ->doesn't support SourceDataLine!"); + } else { + succMixers++; + println(" -> is getting tested."); + play(mixer); + } + } catch (Exception e) { + println(" -> Exception occured: "+e); + e.printStackTrace(); + } + } + } + if (succMixers == 0) { + println("No DirectAudio mixers available! "); + println("Cannot run test."); + } + } + +} --- /dev/null 2016-10-24 21:41:30.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java 2016-10-24 21:41:29.000000000 +0300 @@ -0,0 +1,380 @@ +/* + * 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.awt.Button; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @test + * @bug 5032020 + * @summary Win: Direct Audio is silent after underrun + * @build DirectSoundUnderrunSilence + * @run main/manual Test5032020 + */ +public class Test5032020 { + + private static void init() throws Exception { + //*** Create instructions for the user here *** + + String[] instructions = + { + "To run the test follow these instructions:", + "1. Open a terminal window.", + "2. Type \"cd " + System.getProperty("test.classes") + "\".", + "3. Type \"" + System.getProperty("java.home") + "/bin/java DirectSoundUnderrunSilence\".", + "4. Follow the instructions shown in the terminal window.", + "If no error occured during the test, and the java application ", + "in the termial exited successfully, press PASS, else press FAIL." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + } + + /***************************************************** + Standard Test Machinery Section + DO NOT modify anything in this section -- it's a + standard chunk of code which has all of the + synchronisation necessary for the test harness. + By keeping it the same in all tests, it is easier + to read and understand someone else's test, as + well as insuring that all tests behave correctly + with the test harness. + There is a section following this for test-defined + classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws Exception + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + + }// class Orient + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException + { + } + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + Orient.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + Orient.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout + { + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.show(); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + + }// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener + { + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + show(); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //DialogOrient + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Test5032020.pass(); + } + else + { + Test5032020.fail(); + } + } + + }// TestDialog class --- /dev/null 2016-10-24 21:41:30.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/DisabledAssertionCrash.java 2016-10-24 21:41:30.000000000 +0300 @@ -0,0 +1,90 @@ +/* + * 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.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * @test + * @bug 4991672 + * @summary disabled assertion at maximum thread priority causes audio crash + * @run main/timeout=600 DisabledAssertionCrash + */ +public class DisabledAssertionCrash { + private static final int bufferSize = 1024; + + public static void main(String[] args) { + + System.out.println("This program hangs if priority is set,"); + System.out.println("and assertion is in the code."); + System.out.println("The program crashes the entire Windows system"); + System.out.println("if assertions are disabled."); + try { + Thread.currentThread().setPriority(Thread.MAX_PRIORITY); + AudioFormat audioFormat = new AudioFormat(44100,16,1,true,true); + Line.Info sourceDataLineInfo = new DataLine.Info(SourceDataLine.class,audioFormat); + SourceDataLine sourceDataLine = + (SourceDataLine) AudioSystem.getLine(sourceDataLineInfo); + System.out.println("SourceDataLine: "+sourceDataLine); + sourceDataLine.open(audioFormat, bufferSize); + sourceDataLine.start(); + Line.Info targetDataLineInfo = + new DataLine.Info(TargetDataLine.class,audioFormat); + TargetDataLine targetDataLine = + (TargetDataLine) AudioSystem.getLine(targetDataLineInfo); + System.out.println("TargetDataLine: "+targetDataLine); + targetDataLine.open(audioFormat, bufferSize); + targetDataLine.start(); + byte[] data = new byte[bufferSize]; + + // execute for 20 seconds + float bufferTime = (((float) data.length) / audioFormat.getFrameSize()) / audioFormat.getFrameRate(); + int count = (int) (20.0f / bufferTime); + System.out.println("Buffer time: "+(bufferTime * 1000)+" millis. "+count+" iterations."); + for (int i = 0; i < count; i++) { + int cnt = targetDataLine.read(data,0,data.length); + sourceDataLine.write(data,0,cnt); + assert cnt == data.length; + } + System.out.println("Successfully recorded/played "+count+" buffers. Passed"); + } catch(LineUnavailableException lue) { + System.out.println("Audio hardware is not available!"); + lue.printStackTrace(); + System.out.println("Cannot execute test. NOT failed."); + } catch(IllegalArgumentException iae) { + System.out.println("No audio hardware is installed!"); + iae.printStackTrace(); + System.out.println("Test system not correctly setup."); + System.out.println("Cannot execute test. NOT failed."); + } catch(Exception e) { + System.out.println("Unexpected Exception: "+e); + e.printStackTrace(); + System.out.println("Cannot execute test. NOT failed."); + } + } +} --- /dev/null 2016-10-24 21:41:31.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/NoSimpleInputDevice.java 2016-10-24 21:41:31.000000000 +0300 @@ -0,0 +1,70 @@ +/* + * 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.AudioSystem; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4936397 + * @summary Verify that there'll be either SimpleInputDevice OR DirectAudioDevice + */ +public class NoSimpleInputDevice { + + public static void main(String[] args) throws Exception { + out("4936397: Verify that there'll be either SimpleInputDevice OR DirectAudioDevice"); + boolean foundSimpleInputDevice = false; + boolean foundDirectAudioDevice = false; + + Mixer.Info[] aInfos = AudioSystem.getMixerInfo(); + for (int i = 0; i < aInfos.length; i++) { + try { + Mixer mixer = AudioSystem.getMixer(aInfos[i]); + String mixerClass = mixer.getClass().toString(); + if (mixerClass.indexOf("SimpleInputDevice") >= 0) { + out("Found SimpleInputDevice: "+aInfos[i]); + foundSimpleInputDevice = true; + } + if (mixerClass.indexOf("DirectAudioDevice") >= 0) { + out("Found DirectAudioDevice: "+aInfos[i]); + foundDirectAudioDevice = true; + } + } catch (Exception e) { + out("Unexpected exception: "+e); + } + } + if (aInfos.length == 0) { + out("[No mixers available] - cannot exercise this test."); + } else { + if (foundSimpleInputDevice && foundDirectAudioDevice) { + out("Found both types of capture devices!"); + throw new Exception("Test FAILED!"); + } + out("Did not find both types of capture devices. Test passed"); + } + } + + static void out(String s) { + System.out.println(s); System.out.flush(); + } +} --- /dev/null 2016-10-24 21:41:32.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/PhantomMixers.java 2016-10-24 21:41:32.000000000 +0300 @@ -0,0 +1,91 @@ +/* + * 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.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * @test + * @bug 4794104 + * @summary mixers are always present, independent of available soundcards + * @run main/manual PhantomMixers + */ +public class PhantomMixers { + + public static void main(String args[]) throws Exception { + int SDLformats = 0; + int TDLformats = 0; + Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); + for(int i=0; i " + (srcLineInfo.length + dstLineInfo.length) + " line"); + switch (count) { + case 0: System.out.println("s"); break; + case 1: System.out.println(""); break; + default: System.out.println("s:"); break; + } + int l; + for (l = 0; l < srcLineInfo.length; l++) { + System.out.println(" "+srcLineInfo[l].toString()); + if (srcLineInfo[l].getLineClass() == SourceDataLine.class + && (srcLineInfo[l] instanceof DataLine.Info)) { + SDLformats += ((DataLine.Info) srcLineInfo[l]).getFormats().length; + } + } + for (l = 0; l < dstLineInfo.length; l++) { + System.out.println(" "+dstLineInfo[l].toString()); + if (dstLineInfo[l].getLineClass() == TargetDataLine.class + && (dstLineInfo[l] instanceof DataLine.Info)) { + TDLformats += ((DataLine.Info) dstLineInfo[l]).getFormats().length; + } + } + } + if (mixerInfo.length == 0) { + System.out.println("[no mixers present]"); + } + System.out.println(""+SDLformats+" total formats for SourceDataLines"); + System.out.println(""+TDLformats+" total formats for TargetDataLines"); + System.out.println(""); + System.out.println("If there are audio devices correctly installed on your"); + System.out.println("system, you should see at least one Mixer, and in total"); + System.out.println("at least each one SourceDataLine and TargetDataLine, both"); + System.out.println("providing at least one format."); + System.out.println(""); + System.out.println("Now disable your soundcard and repeat the test."); + System.out.println("The corresponding mixer(s) should not provide any formats"); + System.out.println("anymore. If you disable all available soundcards"); + System.out.println("on your computer, the number of formats above should be"); + System.out.println("0 for both line types (although mixers are allowed to exist)."); + } +} --- /dev/null 2016-10-24 21:41:33.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java 2016-10-24 21:41:32.000000000 +0300 @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2004, 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.Line; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 5013897 + * @summary Verify that plughw: provides mono and 8-bit lines + */ +public class PlugHwMonoAnd8bitAvailable { + static int failed = 0; + static int testedFormats = 0; + + public static void main(String[] args) throws Exception { + out("5013897: Verify that plughw: provides mono and 8-bit lines"); + + Mixer.Info[] aInfos = AudioSystem.getMixerInfo(); + for (int i = 0; i < aInfos.length; i++) { + try { + Mixer mixer = AudioSystem.getMixer(aInfos[i]); + out("Mixer "+aInfos[i]); + if (aInfos[i].getName().contains("plughw")) { + checkLines(mixer, mixer.getSourceLineInfo()); + checkLines(mixer, mixer.getTargetLineInfo()); + } else { + out(" -> not plughw, ignored."); + } + } catch (Exception e) { + out("Unexpected exception when getting a mixer: "+e); + } + } + if (testedFormats == 0) { + out("[No appropriate lines available] - cannot exercise this test."); + } else { + if (failed>0) { + throw new Exception("Test FAILED!"); + } + out("Successfully verified "+testedFormats+" formats."); + out("Test passed"); + } + } + + public static void checkLines(Mixer mixer, Line.Info[] infos) { + for (int i = 0; i 16) { + // if a bit size larger than 16 is available, also 16-bit must be there + checkFormat(formats, getOtherBits(formats[f], 16)); + } else + if (formats[f].getSampleSizeInBits() > 8) { + // if a bit size larger than 8 is available, also 8-bit must be there + checkFormat(formats, getOtherBits(formats[f], 8)); + } + if (formats[f].getChannels() > 2) { + // if more than 2 channels, also 2 channels must be there + checkFormat(formats, getOtherChannels(formats[f], 2)); + } else + if (formats[f].getChannels() > 1) { + // if more than 1 channel, also 1 channel must be there + checkFormat(formats, getOtherChannels(formats[f], 1)); + } + } catch (Exception e1) { + out(" Unexpected exception when getting a format: "+e1); + } + } + } + if (testedFormats - thisTestedFormats == 0) { + out(" -->could not test any formats"); + } else if (failed - thisFailed == 0) { + out(" -->"+(testedFormats - thisTestedFormats)+" formats tested OK"); + } + + } else { + out(" --> not a DataLine"); + } + } catch (Exception e) { + out(" Unexpected exception when getting a line: "+e); + } + } + } + + public static void checkFormat(AudioFormat[] formats, AudioFormat format) { + testedFormats++; + for (int i = 0; i < formats.length; i++) { + if (formats[i].matches(format)) { + return; + } + } + out(" ## expected this format: "+format + +" ("+format.getChannels()+" channels, " + +"frameSize="+format.getFrameSize()+", " + +(format.isBigEndian()?"big endian":"little endian") + +")"); + failed++; + } + + // only works for PCM encodings + public static AudioFormat getOtherBits(AudioFormat format, int newBits) { + boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED); + return new AudioFormat(format.getSampleRate(), + newBits, + format.getChannels(), + isSigned, + (newBits>8)?format.isBigEndian():false); + } + + // only works for PCM encodings + public static AudioFormat getOtherChannels(AudioFormat format, int newChannels) { + int newFrameSize; + if (newChannels <= 0 || format.getChannels() <= 0 || format.getFrameSize() <= 0) { + newFrameSize = -1; + } else { + newFrameSize = format.getFrameSize() / format.getChannels() * newChannels; + } + return new AudioFormat(format.getEncoding(), + format.getSampleRate(), + format.getSampleSizeInBits(), + newChannels, + newFrameSize, + format.getFrameRate(), + format.isBigEndian()); + } + + + static void out(String s) { + System.out.println(s); System.out.flush(); + } +} --- /dev/null 2016-10-24 21:41:33.000000000 +0300 +++ new/test/javax/sound/sampled/Mixers/UnexpectedIAE.java 2016-10-24 21:41:33.000000000 +0300 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2004, 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.AudioSystem; +import javax.sound.sampled.Line; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.Mixer; + +/** + * @test + * @bug 4964288 + * @summary Unexpected IAE raised while getting TargetDataLine + */ +public class UnexpectedIAE { + + public static void main(String argv[]) throws Exception { + boolean success = true; + + Mixer.Info [] infos = AudioSystem.getMixerInfo(); + + for (int i=0; i 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"); + } +} --- /dev/null 2016-10-24 21:41:35.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileReader/AIFFCp037.java 2016-10-24 21:41:34.000000000 +0300 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; + +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4369044 + * @summary javax.sound.sampled.AudioSystem.getAudioInputStream() works wrong + * with Cp037 + */ +public class AIFFCp037 { + + public static void main(String args[]) throws Exception { + System.setProperty("file.encoding", "Cp037"); + // try to read this file with Cp037 encoding + AudioSystem.getAudioInputStream(new ByteArrayInputStream(SHORT_AIFF)); + System.out.println(" test passed."); + } + + public static String getString(byte b) { + //String res = Integer.toHexString(b & 0xFF).toUpperCase(); + //while (res.length()<2) res="0"+res; + //return res; + return String.valueOf(b); + } + + + public static void printFile(String filename) throws Exception { + File file = new File(filename); + FileInputStream fis = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + fis.read(data); + String s = ""; + for (int i=0; i72) { + System.out.println(s); + s=""; + } + } + System.out.println(s); + } + + public static byte[] SHORT_AIFF = { + 70, 79, 82, 77, 0, 0, 4, -54, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18, + 0, 1, 0, 0, 2, 78, 0, 16, 64, 12, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78, + 68, 0, 0, 4, -92, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -2, 0, -2, 0, 0, 0, 0, 0, + -3, 0, -5, 0, -2, 0, 3, 0, 1, 0, -3, 0, -5, 0, -6, 0, -6, 0, -5, 0, -2, 0, + -2, 0, -5, 0, -6, 0, -3, 0, 0, 0, 0, 0, -3, 0, -5, 0, -6, 0, -8, 0, -5, 0, + 1, 0, 4, 0, 1, 0, -5, 0, -8, 0, -3, 0, 3, 0, 4, 0, 0, 0, -8, 0, -11, 0, -8, + 0, -3, 0, 0, 0, 0, 0, 1, 0, 0, 0, -5, 0, -9, 0, -8, 0, 0, 0, 6, 0, 7, 0, + 0, 0, -8, 0, -11, 0, -8, 0, 0, 0, 4, 0, 6, 0, 3, 0, -2, 0, -5, 0, -5, 0, + 0, 0, 6, 0, 6, 0, 1, 0, -5, 0, -3, 0, 1, 0, 6, 0, 6, 0, 1, 0, -3, 0, -3, + 0, 0, 0, 3, 0, 3, 0, 0, 0, -3, 0, -2, 0, 3, 0, 6, 0, 4, 0, 0, 0, -2, 0, -2, + 0, 1, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -3, 0, 1, 0, 6, + 0, 6, 0, 1, 0, 0, 0, 1, 0, 0, 0, -2, 0, -2, 0, 3, 0, 4, 0, 0, 0, -5, 0, -3, + 0, 1, 0, 4, 0, 4, 0, 0, 0, -2, 0, 1, 0, 1, 0, -2, 0, -6, 0, -6, 0, -2, 0, + 6, 0, 7, 0, 4, 0, 0, 0, -5, 0, -6, 0, -5, 0, 0, 0, 4, 0, 4, 0, 0, 0, -5, + 0, -8, 0, -8, 0, -5, 0, 1, 0, 3, 0, 1, 0, -3, 0, -6, 0, -6, 0, -5, 0, -5, + 0, -3, 0, 1, 0, 3, 0, 1, 0, -2, 0, -5, 0, -5, 0, -5, 0, -3, 0, 3, 0, 6, 0, + 6, 0, 0, 0, -3, 0, -3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 4, 0, 0, 0, -3, 0, -5, + 0, -2, 0, 1, 0, -2, 0, -2, 0, 1, 0, 4, 0, 1, 0, -3, 0, -2, 0, 0, 0, 0, 0, + -3, 0, -6, 0, -5, 0, 0, 0, 3, 0, 0, 0, -3, 0, -5, 0, -5, 0, -2, 0, -2, 0, + -5, 0, -6, 0, -3, 0, 1, 0, 1, 0, -2, 0, -8, 0, -8, 0, -3, 0, 1, 0, 3, 0, + 1, 0, -5, 0, -8, 0, -6, 0, -2, 0, 3, 0, 4, 0, -2, 0, -5, 0, -6, 0, -3, 0, + -2, 0, -2, 0, -2, 0, -2, 0, -3, 0, -5, 0, -6, 0, -5, 0, -2, 0, 0, 0, 0, 0, + -2, 0, -3, 0, -5, 0, -5, 0, -3, 0, -3, 0, -2, 0, -2, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 1, 0, 1, 0, -2, 0, -5, 0, -3, 0, 1, 0, 4, 0, 6, 0, 4, 0, 1, 0, 0, 0, + 0, 0, 3, 0, 4, 0, 1, 0, -3, 0, -3, 0, 1, 0, 6, 0, 4, 0, 1, 0, -3, 0, -5, + 0, -2, 0, 3, 0, 6, 0, 7, 0, 1, 0, -5, 0, -5, 0, 1, 0, 7, 0, 6, 0, 3, 0, 1, + 0, -2, 0, -5, 0, -5, 0, -2, 0, 3, 0, 3, 0, 3, 0, 0, 0, -3, 0, -5, 0, -3, + 0, 0, 0, 6, 0, 9, 0, 4, 0, -2, 0, -6, 0, -5, 0, -2, 0, 3, 0, 4, 0, 3, 0, + -2, 0, -6, 0, -3, 0, 1, 0, 3, 0, -3, 0, -6, 0, 0, 0, 4, 0, 1, 0, -6, 0, -9, + 0, -5, 0, 1, 0, 1, 0, 0, 0, -2, 0, -3, 0, -5, 0, -6, 0, -5, 0, 0, 0, 3, 0, + 3, 0, -2, 0, -6, 0, -6, 0, -3, 0, -2, 0, -2, 0, -5, 0, -6, 0, -5, 0, -2, + 0, 0, 0, -2, 0, -3, 0, -3, 0, -3, 0, -2, 0, 0, 0, 1, 0, 0, 0, -2, 0, -2, + 0, -3, 0, -5, 0, -5, 0, -2, 0, 0, 0, 3, 0, 3, 0, 0, 0, -3, 0, -3, 0, 0, 0, + -2, 0, -5, 0, -3, 0, 0, 0, 1, 0, -3, 0, -8, 0, -6, 0, -2, 0, -2, 0, -6, 0, + -6, 0, -5, 0, -3, 0, -3, 0, -6, 0, -6, 0, -3, 0, -3, 0, -3, 0, -3, 0, 0, + 0, 1, 0, -3, 0, -6, 0, -3, 0, 1, 0, 0, 0, -6, 0, -9, 0, -9, 0, -6, 0, -2, + 0, 1, 0, 3, 0, -3, 0, -5, 0, -3, 0, -2, 0, -3, 0, -6, 0, -5, 0, -2, 0, -2, + 0, -5, 0, -5, 0, -2, 0, -2, 0, -5, 0, -6, 0, -6, 0, -2, 0, -2, 0, -2, 0, + -3, 0, -5, 0, -5, 0, -3, 0, 1, 0, 0, 0, 1, 0, 1, 0, 3, 0, 6, 0, 6, 0, 3, + 0, -6, 0, -12, 0, -8, 0, 1, 0, 9, 0, 7, 0, 1, 0, -3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 3, 0, 6, 0, 7, 0, 3, 0, -3, 0, -5, 0, 0, 0, 4, 0, 4, 0, 3, 0, 1, 0, + 3, 0, 3, 0, 0, 0, -2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0, 1, 0, 0, 0, + 0, 0, 3, 0, 1, 0, -2, 0, -2, 0, 1, 0, 1, 0, -3, 0, -3, 0, 0, 0, 4, 0, 6, + 0, 6, 0, 3, 0, -3, 0, -8, 0, -5, 0, 1, 0, 3, 0, 1, 0, 1, 0, 0, 0, -3, 0, + -6, 0, -5, 0, 1, 0, 3, 0, -2, 0, -3, 0, 0, 0, 1, 0, 1, 0, -3, 0, -5, 0, -2, + 0, -2, 0, -2, 0, 0, 0, 1, 0, 1, 0, -2, 0, -5, 0, -8, 0, -6, 0, -5, 0, -2, + 0, 1, 0, 0, 0, -5, 0, -6, 0, 0, 0, 4, 0, 1, 0, -5, 0, -5, 0, -3, 0, -2, 0, + -3, 0, -3, 0, 0, 0, 0, 0, -2, 0, -3, 0, -2, 0, 1, 0, -2, 0, -5, 0, -3, 0, + 0, 0, 3, 0, 0, 0, -3, 0, -3, 0, -3, 0, -3, 0, -3, 0, 0, 0, 3, 0, 4, 0, -2, + 0, -8, 0, -8, 0, -5, 0, 3, 0, 3, 0, -2, 0, -6, 0, -8, 0, -3, 0, 1, 0, 0, + 0, -5, 0, -5, 0, -2, 0, -2, 0, -3, 0, -5, 0, -3, 0, 0, 0, 0, 0, -2, 0, -5, + 0, -6, 0, -5, 0, -3, 0, 0, 0, 0, 0, -3, 0, -3, 0, -5, 0, -5, 0, -6, 0, -6, + 0, -6, 0, -5, 0, 0, 0, 1, 0, 0, 0, -5, 0, -6, 0, -5, 0, -2, 0, -2, 0, -3, + 0, -5, 0, -8, 0, -9, 0, -6, 0, -2, 0, 0, 0, -2, 0, -5, 0, -5, 0, -2, 0, 3, + 0, 4, 0, 0, 0, -2, 0, -2, 0, 1, 0, 1, 0, 1, 0, 3, 0 + }; + +} --- /dev/null 2016-10-24 21:41:35.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileReader/AIFFLargeHeader.java 2016-10-24 21:41:35.000000000 +0300 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; + +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4399551 + * @summary Repost of bug candidate: cannot replay aif file. AIFF headers were + * checked for certain size also tests that ulaw encoded AIFC files can + * be read. + */ +public class AIFFLargeHeader { + + public static void main(String args[]) throws Exception { + System.out.println(); + System.out.println(); + System.out.println("4399551: Repost of bug candidate: cannot replay aif file (Review ID: 108108)"); + // try to read this file + AudioSystem.getAudioInputStream(new ByteArrayInputStream(SHORT_AIFC_ULAW)); + System.out.println(" test passed."); + } + + public static String getString(byte b) { + //String res = Integer.toHexString(b & 0xFF).toUpperCase(); + //while (res.length()<2) res="0"+res; + //return res; + return String.valueOf(b); + } + + + public static void printFile(String filename) throws Exception { + File file = new File(filename); + FileInputStream fis = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + fis.read(data); + String s = ""; + for (int i=0; i72) { + System.out.println(s); + s=""; + } + } + System.out.println(s); + } + + public static byte[] SHORT_AIFC_ULAW = { + 70, 79, 82, 77, 0, 0, 2, 50, 65, 73, 70, 67, 70, 86, 69, 82, 0, 0, 0, 4, + -94, -128, 81, 64, 67, 79, 77, 77, 0, 0, 0, 30, 0, 1, 0, 1, 118, -9, 0, 16, + 64, 12, -84, 68, 0, 0, 0, 0, 0, 0, 117, 108, 97, 119, 7, 117, 110, 107, 110, + 111, 119, 110, 83, 83, 78, 68, 0, 0, 1, -13, 0, 0, 0, 0, 0, 0, 0, 0, 103, + 103, 103, -1, -1, 91, 77, 103, -45, -25, 91, 77, 73, 73, 77, 103, 103, 77, + 73, 91, -1, -1, 91, 77, 73, 65, 77, -25, -51, -25, 77, 65, 91, -45, -51, + -1, 65, 58, 65, 91, -1, -1, -25, -1, 77, 62, 65, -1, -59, -63, -1, 65, 58, + 65, -1, -51, -59, -45, 103, 77, 77, -1, -59, -59, -25, 77, 91, -25, -59, + -59, -25, 91, 91, -1, -45, -45, -1, 91, 103, -45, -59, -51, -1, 103, 103, + -25, -25, -45, -45, -1, -1, -1, -1, 103, 91, -25, -59, -59, -25, -1, -25, + -1, 103, 103, -45, -51, -1, 77, 91, -25, -51, -51, -1, 103, -25, -25, 103, + 73, 73, 103, -59, -63, -51, -1, 77, 73, 77, -1, -51, -51, -1, 77, 65, 65, + 77, -25, -45, -25, 91, 73, 73, 77, 77, 91, -25, -45, -25, 103, 77, 77, 77, + 91, -45, -59, -59, -1, 91, 91, -1, -25, -1, -45, -51, -1, 91, 77, 103, -25, + 103, 103, -25, -51, -25, 91, 103, -1, -1, 91, 73, 77, -1, -45, -1, 91, 77, + 77, 103, 103, 77, 73, 91, -25, -25, 103, 65, 65, 91, -25, -45, -25, 77, 65, + 73, 103, -45, -51, 103, 77, 73, 91, 103, 103, 103, 103, 91, 77, 73, 77, 103, + -1, -1, 103, 91, 77, 77, 91, 91, 103, 103, -1, -25, -25, -1, -25, -25, 103, + 77, 91, -25, -51, -59, -51, -25, -1, -1, -45, -51, -25, 91, 91, -25, -59, + -51, -25, 91, 77, 103, -45, -59, -63, -25, 77, 77, -25, -63, -59, -45, -25, + 103, 77, 77, 103, -45, -45, -45, -1, 91, 77, 91, -1, -59, -68, -51, 103, + 73, 77, 103, -45, -51, -45, 103, 73, 91, -25, -45, 91, 73, -1, -51, -25, + 73, 62, 77, -25, -25, -1, 103, 91, 77, 73, 77, -1, -45, -45, 103, 73, 73, + 91, 103, 103, 77, 73, 77, 103, -1, 103, 91, 91, 91, 103, -1, -25, -1, 103, + 103, 91, 77, 77, 103, -1, -45, -45, -1, 91, 91, -1, 103, 77, 91, -1, -25, + 91, 65, 73, 103, 103, 73, 73, 77, 91, 91, 73, 73, 91, 91, 91, 91, -1, -25, + 91, 73, 91, -25, -1, 73, 62, 62, 73, 103, -25, -45, 91, 77, 91, 103, 91, + 73, 77, 103, 103, 77, 77, 103, 103, 77, 73, 73, 103, 103, 103, 91, 77, 77, + 91, -25, -1, -25, -25, -45, -59, -59, -45, 73, 56, 65, -25, -68, -63, -25, + 91, -1, -45, -1, -1, -45, -59, -63, -1, 103, 103, -25, -25, 103, 91, -1, + -45, -51, -25, 103, 91, 91, 103, -25, -25, -25, 103, 73, 77, -1, -51, -45, + 103, 91, 103, -25, -1, 91, 91, 91, -1, -45, -51, -25, 91, 77, 103, -1, -1, + 91, -1, -1, -1, 103, 91, 91, 73, 77, 103, -25, -25, 103, 91, 103, 103, 103, + -1, -45, -1, 77, 77, -1 + }; + +} --- /dev/null 2016-10-24 21:41:36.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileReader/Aiff12bit.java 2016-10-24 21:41:36.000000000 +0300 @@ -0,0 +1,78 @@ +/* + * 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.ByteArrayInputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4895934 + * @summary AudioInputStream.getFrameLength returns wrong value for 12-bit AIFF + * file + */ +public class Aiff12bit { + + public static void test(byte[] file) throws Exception { + InputStream inputStream = new ByteArrayInputStream(file); + AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream); + + if (aff.getFormat().getSampleSizeInBits() != 12) { + throw new Exception("Wrong sample size. test FAILED"); + } + if (aff.getFormat().getFrameSize() != 2) { + throw new Exception("Wrong frame size. test FAILED"); + } + if (aff.getFrameLength() != 100) { + throw new Exception("Wrong file length. test FAILED"); + } + } + + public static void main(String[] args) throws Exception { + test(AIFF_12BIT); + + System.out.println("Test passed."); + } + + public static byte[] AIFF_12BIT = { + 70, 79, 82, 77, 0, 0, 0, -10, 65, 73, 70, 70, 67, 79, 77, 77, + 0, 0, 0, 18, 0, 1, 0, 0, 0, 100, 0, 12, 64, 8, -6, 0, + 0, 0, 0, 0, 0, 0, 83, 83, 78, 68, 0, 0, 0, -48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 48, 0, 64, + 0, 80, 0, 96, 0, 112, 0, -128, 0, -112, 0, -96, 0, -80, 0, -64, + 0, -48, 0, -32, 0, -16, 1, 0, 1, 16, 1, 32, 1, 48, 1, 64, + 1, 80, 1, 96, 1, 112, 1, -128, 1, -112, 1, -96, 1, -80, 1, -64, + 1, -48, 1, -32, 1, -16, 2, 0, 2, 16, 2, 32, 2, 48, 2, 64, + 2, 80, 2, 96, 2, 112, 2, -128, 2, -112, 2, -96, 2, -80, 2, -64, + 2, -48, 2, -32, 2, -16, 3, 0, 3, 16, 3, 32, 3, 48, 3, 64, + 3, 80, 3, 96, 3, 112, 3, -128, 3, -112, 3, -96, 3, -80, 3, -64, + 3, -48, 3, -32, 3, -16, 4, 0, 4, 16, 4, 32, 4, 48, 4, 64, + 4, 80, 4, 96, 4, 112, 4, -128, 4, -112, 4, -96, 4, -80, 4, -64, + 4, -48, 4, -32, 4, -16, 5, 0, 5, 16, 5, 32, 5, 48, 5, 64, + 5, 80, 5, 96, 5, 112, 5, -128, 5, -112, 5, -96, 5, -80, 5, -64, + 5, -48, 5, -32, 5, -16, 6, 0, 6, 16, 6, 32, 6, 48, + }; + +} --- /dev/null 2016-10-24 21:41:37.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileReader/AuNotSpecified.java 2016-10-24 21:41:37.000000000 +0300 @@ -0,0 +1,61 @@ +/* + * 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.ByteArrayInputStream; + +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4940459 + * @summary AudioInputStream.getFrameLength() returns 0 instead of NOT_SPECIFIED + */ +public class AuNotSpecified { + public static boolean failed = false; + + public static void main(String[] params) throws Exception { + + AudioInputStream is = + AudioSystem.getAudioInputStream(new + ByteArrayInputStream(new byte[] { + (byte)0x2E, (byte)0x73, (byte)0x6E, (byte)0x64, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x18, + (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x03, + (byte)0x00, (byte)0x00, (byte)0x1F, (byte)0x40, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, + })); + if (is.getFrameLength() != AudioSystem.NOT_SPECIFIED) { + System.out.println("frame length should be NOT_SPECIFIED, but is: "+is.getFrameLength()); + failed=true; + } + //assertTrue(is.getFrameLength() == AudioSystem.NOT_SPECIFIED); + //assertTrue(is.read(new byte[8]) == 8); + //assertTrue(is.read(new byte[2]) == -1); + if (failed) throw new Exception("Test FAILED!"); + System.out.println("Test Passed."); + } +} --- /dev/null 2016-10-24 21:41:38.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileReader/AuZeroLength.java 2016-10-24 21:41:37.000000000 +0300 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4629669 + * @summary AU file reader: problems with empty files + */ +public class AuZeroLength { + + public static String getString(byte b) { + //String res = Integer.toHexString(b & 0xFF).toUpperCase(); + //while (res.length()<2) res="0"+res; + //return res; + return String.valueOf(b); + } + + + public static void printFile(String filename) throws Exception { + File file = new File(filename); + FileInputStream fis = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + fis.read(data); + String s = ""; + for (int i=0; i72) { + System.out.println(s); + s=""; + } + } + System.out.println(s); + } + + public static void test(byte[] file) throws Exception { + InputStream inputStream = new ByteArrayInputStream(file); + AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream); + + if (aff.getFrameLength() != 0) { + throw new Exception("File length is "+aff.getFrameLength()+" instead of 0. test FAILED"); + } + System.out.println(aff.getType()+" file length is 0."); + } + + public static void main(String[] args) throws Exception { + test(ZERO_AU); + test(ZERO_WAV); + test(ZERO_AIFF); + + System.out.println("Test passed."); + } + + public static byte[] ZERO_AU = { + 46, 115, 110, 100, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -84, 68, 0, + 0, 0, 1, 116, 101, 115, 116, 46, 119, 97, 118 + }; + + public static byte[] ZERO_WAV = { + 82, 73, 70, 70, 36, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, + 0, 1, 0, 1, 0, 68, -84, 0, 0, -120, 88, 1, 0, 2, 0, 16, 0, 100, 97, 116, + 97, 0, 0, 0, 0 + }; + + public static byte[] ZERO_AIFF = { + 70, 79, 82, 77, 0, 0, 0, 46, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18, + 0, 1, 0, 0, 0, 0, 0, 16, 64, 14, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78, 68, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0 + }; + +} --- /dev/null 2016-10-24 21:41:38.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileReader/OpenWaveFile.java 2016-10-24 21:41:38.000000000 +0300 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URL; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4489272 + * @summary AudioSystem.getAudioFileFormat() fails for InputStream, but works + * for URL + */ +public class OpenWaveFile { + + static void check(Object source) throws Exception { + AudioFileFormat aff2 = null; + if (source instanceof File) { + aff2 = AudioSystem.getAudioFileFormat((File) source); + } + else if (source instanceof InputStream) { + aff2 = AudioSystem.getAudioFileFormat((InputStream) source); + } + else if (source instanceof URL) { + aff2 = AudioSystem.getAudioFileFormat((URL) source); + } else throw new Exception("wrong source. Test FAILED"); + System.out.println("Got: "+aff2); + if (aff2.getFormat().getSampleSizeInBits()==-1) { + throw new Exception("wrong audio format. Test FAILED"); + } + } + + public static void main(String args[]) throws Exception { + //check(new File(args[0])); + //check(new URL("file", "", args[0])); + check(new ByteArrayInputStream(SHORT_AU)); + check(new ByteArrayInputStream(SHORT_WAVE)); + check(new ByteArrayInputStream(SHORT_AIFF)); + System.out.println("Test passed."); + + //printFile(args[0]); + } + + public static String getString(byte b) { + //String res = Integer.toHexString(b & 0xFF).toUpperCase(); + //while (res.length()<2) res="0"+res; + //return res; + return String.valueOf(b); + } + + + public static void printFile(String filename) throws Exception { + File file = new File(filename); + FileInputStream fis = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + fis.read(data); + String s = ""; + for (int i=0; i72) { + System.out.println(s); + s=""; + } + } + System.out.println(s); + } + + public static byte[] SHORT_WAVE = { + 82, 73, 70, 70, -120, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, + 0, 0, 1, 0, 1, 0, 34, 86, 0, 0, 34, 86, 0, 0, 1, 0, 8, 0, 100, 97, 116, 97, + 100, 0, 0, 0, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, -128, -128, -128, -128, -128, -128, -128, -128, 127, 127, -128, 127, + 127, 127, -128, -128, -128, -128, 127, 127, -128, -128, 127, -128, -128, + -128, 127, 127, 127, -128, -128, -128, 127, 127, 127, 127, -128, -128, -128, + -128, -128, -128, 127, 127, 127, -128, -128, -128, -128, -128, 127, -128, + -128, 127, -128, -128, 127, 127, -128, -128, 127, 127, -128, -128, -128, + -128, -128, 127, 127, -128, -128, -128, 127, 127, 127, -128, 127, -128, -128, + 127, 127, 127, -128, -128, -128, 127, 127, -128, -128, + }; + + public static byte[] SHORT_AU = { + 46, 115, 110, 100, 0, 0, 0, 24, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 86, 34, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, + -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, + 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, 0, + -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, 0, 0, + }; + + public static byte[] SHORT_AIFF = { + 70, 79, 82, 77, 0, 0, 0, -110, 65, 73, 70, 70, 67, 79, 77, 77, 0, 0, 0, 18, + 0, 1, 0, 0, 0, 100, 0, 8, 64, 13, -84, 68, 0, 0, 0, 0, 0, 0, 83, 83, 78, + 68, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, + -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, + -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, + 0, -1, -1, 0, 0, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, + 0, 0, + }; +} --- /dev/null 2016-10-24 21:41:39.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileWriter/AUwithULAW.java 2016-10-24 21:41:39.000000000 +0300 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4391108 + * @summary Writing au files with ulaw encoding is broken + */ +public class AUwithULAW { + public static void main(String args[]) throws Exception { + System.out.println(); + System.out.println(); + System.out.println("4391108: Writing au files with ulaw encoding is broken"); + byte[] fakedata=new byte[1234]; + InputStream is = new ByteArrayInputStream(fakedata); + AudioFormat inFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, false); + + AudioInputStream ais = new AudioInputStream(is, inFormat, fakedata.length); + + ByteArrayOutputStream out = new ByteArrayOutputStream(1500); + System.out.println(" ulaw data will be written as AU to stream..."); + int t = AudioSystem.write(ais, AudioFileFormat.Type.AU, out); + byte[] writtenData = out.toByteArray(); + is = new ByteArrayInputStream(writtenData); + System.out.println(" Get AudioFileFormat of written file"); + AudioFileFormat fileformat = AudioSystem.getAudioFileFormat(is); + AudioFileFormat.Type type = fileformat.getType(); + System.out.println(" The file format type: "+type); + if (fileformat.getFrameLength()!=fakedata.length + && fileformat.getFrameLength()!=AudioSystem.NOT_SPECIFIED) { + throw new Exception("The written file's frame length is "+fileformat.getFrameLength()+" but should be "+fakedata.length+" !"); + } + ais = AudioSystem.getAudioInputStream(is); + System.out.println(" Got Stream with format: "+ais.getFormat()); + System.out.println(" test passed."); + } +} --- /dev/null 2016-10-24 21:41:40.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileWriter/AiffSampleRate.java 2016-10-24 21:41:39.000000000 +0300 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4914639 + * @summary JavaSound writes wrong sample rates to AIFF files + */ +public class AiffSampleRate { + + private static final float[] testSampleRates = + {8000.0F, 8000.0F + 0.011F, 8193.975F, 10000.0F, 11025.0F, 12000.0F, + 16000.0F, 22050.0F, 24000.0F, 32000.0F, 44100.0F - 1.22222F, 44100.0F, + 47888.888F, 48000.0F, 96000.0F, 192000.0F}; + + public static void main(String[] args) throws Exception { + boolean isTestPassed = true; + + out("#4914639: JavaSound writes wrong sample rates to AIFF files"); + for (int i = 0; i < testSampleRates.length; i++) { + isTestPassed &= testSampleRate(testSampleRates[i]); + } + if (isTestPassed) { + out("Test PASSED."); + } else { + throw new Exception("Test FAILED."); + } + } + + private static boolean testSampleRate(float sampleRate) { + boolean result = true; + + try { + // create AudioInputStream with sample rate of 10000 Hz + ByteArrayInputStream data = new ByteArrayInputStream(new byte[1]); + AudioFormat format = new AudioFormat(sampleRate, 8, 1, true, true); + AudioInputStream stream = new AudioInputStream(data, format, 1); + + // write to AIFF file + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + AudioSystem.write(stream, AudioFileFormat.Type.AIFF, outputStream); + byte[] fileData = outputStream.toByteArray(); + InputStream inputStream = new ByteArrayInputStream(fileData); + AudioFileFormat aff = AudioSystem.getAudioFileFormat(inputStream); + if (! equals(sampleRate, aff.getFormat().getFrameRate())) { + out("error for sample rate " + sampleRate); + result = false; + } + } catch (Exception e) { + out(e); + out("Test NOT FAILED"); + } + return result; + } + + private static boolean equals(float f1, float f2) { + return Math.abs(f2 - f1) < 1.0E-9; + } + + private static void out(Throwable t) { + t.printStackTrace(System.out); + } + + private static void out(String message) { + System.out.println(message); + } +} --- /dev/null 2016-10-24 21:41:40.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileWriter/RIFFHeader.java 2016-10-24 21:41:40.000000000 +0300 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4636355 + * @summary Check that RIFF headers are written with extra data length field. + */ +public class RIFFHeader { + + public static void main(String args[]) throws Exception { + System.out.println(); + System.out.println(); + System.out.println("4636355: Check that RIFF headers are written with extra data length field."); + byte[] fakedata=new byte[1234]; + MyByteArrayInputStream is = new MyByteArrayInputStream(fakedata); + AudioFormat inFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, true); + + AudioInputStream ais = new AudioInputStream((InputStream) is, inFormat, fakedata.length); + ByteArrayOutputStream out = new ByteArrayOutputStream(1500); + System.out.println(" ulaw data will be written as WAVE to stream..."); + int t = AudioSystem.write(ais, AudioFileFormat.Type.WAVE, out); + byte[] writtenData = out.toByteArray(); + // now header must have at least 46 bytes + System.out.println(" Length should be "+(fakedata.length+46)+" bytes: "+writtenData.length); + // re-read this file + is = new MyByteArrayInputStream(writtenData); + System.out.println(" Get AudioFileFormat of written file"); + AudioFileFormat fileformat = AudioSystem.getAudioFileFormat(is); + AudioFileFormat.Type type = fileformat.getType(); + System.out.println(" The file format type: "+type); + if (fileformat.getFrameLength()!=fakedata.length + && fileformat.getFrameLength()!=AudioSystem.NOT_SPECIFIED) { + throw new Exception("The written file's frame length is "+fileformat.getFrameLength()+" but should be "+fakedata.length+" !"); + } + ais = AudioSystem.getAudioInputStream(is); + System.out.println(" Got Stream with format: "+ais.getFormat()); + if (is.getPos()<46) { + throw new Exception("After reading the header, stream position must be at least 46, but is "+is.getPos()+" !"); + } + System.out.println(" test passed."); + } + + static class MyByteArrayInputStream extends ByteArrayInputStream { + + MyByteArrayInputStream(byte[] data) { + super(data); + } + + int getPos() { + return pos; + } + } +} --- /dev/null 2016-10-24 21:41:41.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileWriter/WaveBigEndian.java 2016-10-24 21:41:41.000000000 +0300 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2006, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 5001952 + * @summary Writing WAVE with big endian data produces corrupt file. WAVE should + * always write signed 16-bit, little endian, regardless of the + * endianness of the input data. + */ +public class WaveBigEndian { + + static boolean failed = false; + + public static byte[] writeDataAndGetAIS(boolean bigEndian) throws Exception { + if (bigEndian) { + out("Create WAVE file from big endian data..."); + } else { + out("Create WAVE file from little endian data..."); + } + byte[] data = new byte[3000]; + for (int i = 0; i < data.length; i+=2) { + if (bigEndian) { + data[i] = (byte) i; + data[i+1] = (byte) (i+1); + } else { + data[i] = (byte) (i+1); + data[i+1] = (byte) i; + } + } + AudioFormat format = new AudioFormat(44100.0f, 16, 1, true, bigEndian); + InputStream is = new ByteArrayInputStream(data); + AudioInputStream ais = new AudioInputStream(is, format, data.length); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + int written = AudioSystem.write(ais, AudioFileFormat.Type.WAVE, os); + data = os.toByteArray(); + out("Wrote "+written+" bytes, got "+data.length+" bytes in written file."); + is = new ByteArrayInputStream(data); + ais = AudioSystem.getAudioInputStream(is); + out("Got AIS with length = "+ais.getFrameLength()+" frames."); + return data; + } + + + public static void main(String args[]) throws Exception { + byte[] data1 = writeDataAndGetAIS(false); + byte[] data2 = writeDataAndGetAIS(true); + + if (data1.length != data2.length) { + out("# data1.length != data2.length!"); + failed = true; + } else { + for (int i = 0 ; i < data1.length; i++) { + if (data1[i] != data2[i]) { + out("# At index "+i+": le="+(data1[i] & 0xFF)+" be="+(data2[i] & 0xFF)+" !"); + failed = true; + } + } + } + + if (failed) throw new Exception("Test FAILED!"); + out("Files are identical."); + out("test passed"); + } + + static void out(String s) { + System.out.println(s); + } +} --- /dev/null 2016-10-24 21:41:42.000000000 +0300 +++ new/test/javax/sound/sampled/spi/AudioFileWriter/WriteAuUnspecifiedLength.java 2016-10-24 21:41:42.000000000 +0300 @@ -0,0 +1,47 @@ +/* + * 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4351296 + * @summary Cannot write AudioInputStream with unspecified length + */ +public class WriteAuUnspecifiedLength { + + public static void main(String argv[]) throws Exception { + AudioFormat format = new AudioFormat(44100, 16, 2, true, true); + InputStream is = new ByteArrayInputStream(new byte[1000]); + AudioInputStream ais = new AudioInputStream(is, format, AudioSystem.NOT_SPECIFIED); + AudioSystem.write(ais, AudioFileFormat.Type.AU, new ByteArrayOutputStream()); + System.out.println("Test passed."); + } +} --- /dev/null 2016-10-24 21:41:42.000000000 +0300 +++ new/test/javax/sound/sampled/spi/FormatConversionProvider/AlawUlaw.java 2016-10-24 21:41:42.000000000 +0300 @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2002, 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.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +/** + * @test + * @bug 4714846 + * @summary JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness + */ +public class AlawUlaw { + static ByteArrayInputStream in; + static int byteLength = 1000; + + static boolean failed = false; + + public static void main(String[] args) throws Exception { + // generate some random data + byte[] soundData = new byte[byteLength]; + for (int i=0; i