diff --git a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java index 4a4734d241c16..97bafe3f9a6ac 100644 --- a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java +++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java @@ -474,7 +474,7 @@ protected void finalize() { This is necessary for Receivers retrieved via MidiSystem.getReceiver() (which opens the device implicitely). */ - protected abstract class AbstractReceiver implements Receiver { + protected abstract class AbstractReceiver implements MidiDeviceReceiver { private boolean open = true; @@ -508,6 +508,10 @@ public void close() { AbstractMidiDevice.this.closeInternal(this); } + public MidiDevice getMidiDevice() { + return AbstractMidiDevice.this; + } + protected boolean isOpen() { return open; } @@ -529,7 +533,7 @@ protected boolean isOpen() { * Also, it has some optimizations regarding sending to the Receivers, * for known Receivers, and managing itself in the TransmitterList. */ - protected class BasicTransmitter implements Transmitter { + protected class BasicTransmitter implements MidiDeviceTransmitter { private Receiver receiver = null; TransmitterList tlist = null; @@ -568,6 +572,9 @@ public void close() { } } + public MidiDevice getMidiDevice() { + return AbstractMidiDevice.this; + } } // class BasicTransmitter diff --git a/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiverEnvelope.java b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiverEnvelope.java new file mode 100644 index 0000000000000..9a962bbd4127a --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiverEnvelope.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ +package com.sun.media.sound; + +import javax.sound.midi.*; + + +/** + * Helper class which allows to convert {@code Receiver} + * to {@code MidiDeviceReceiver}. + * + * @author Alex Menkov + */ +public class MidiDeviceReceiverEnvelope implements MidiDeviceReceiver { + + private final MidiDevice device; + private final Receiver receiver; + + /** + * Creates a new {@code MidiDeviceReceiverEnvelope} object which + * envelops the specified {@code Receiver} + * and is owned by the specified {@code MidiDevice}. + * + * @param device the owner {@code MidiDevice} + * @param receiver the {@code Receiver} to be enveloped + */ + public MidiDeviceReceiverEnvelope(MidiDevice device, Receiver receiver) { + if (device == null || receiver == null) { + throw new NullPointerException(); + } + this.device = device; + this.receiver = receiver; + } + + // Receiver implementation + public void close() { + receiver.close(); + } + + public void send(MidiMessage message, long timeStamp) { + receiver.send(message, timeStamp); + } + + // MidiDeviceReceiver implementation + public MidiDevice getMidiDevice() { + return device; + } + + /** + * Obtains the receiver enveloped + * by this {@code MidiDeviceReceiverEnvelope} object. + * + * @return the enveloped receiver + */ + public Receiver getReceiver() { + return receiver; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/MidiDeviceTransmitterEnvelope.java b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceTransmitterEnvelope.java new file mode 100644 index 0000000000000..e20d430a042cd --- /dev/null +++ b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceTransmitterEnvelope.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ +package com.sun.media.sound; + +import javax.sound.midi.*; + + +/** + * Helper class which allows to convert {@code Transmitter} + * to {@code MidiDeviceTransmitter}. + * + * @author Alex Menkov + */ +public class MidiDeviceTransmitterEnvelope implements MidiDeviceTransmitter { + + private final MidiDevice device; + private final Transmitter transmitter; + + /** + * Creates a new {@code MidiDeviceTransmitterEnvelope} object which + * envelops the specified {@code Transmitter} + * and is owned by the specified {@code MidiDevice}. + * + * @param device the owner {@code MidiDevice} + * @param transmitter the {@code Transmitter} to be enveloped + */ + public MidiDeviceTransmitterEnvelope(MidiDevice device, Transmitter transmitter) { + if (device == null || transmitter == null) { + throw new NullPointerException(); + } + this.device = device; + this.transmitter = transmitter; + } + + // Transmitter implementation + public void setReceiver(Receiver receiver) { + transmitter.setReceiver(receiver); + } + + public Receiver getReceiver() { + return transmitter.getReceiver(); + } + + public void close() { + transmitter.close(); + } + + + // MidiDeviceReceiver implementation + public MidiDevice getMidiDevice() { + return device; + } + + /** + * Obtains the transmitter enveloped + * by this {@code MidiDeviceTransmitterEnvelope} object. + * + * @return the enveloped transmitter + */ + public Transmitter getTransmitter() { + return transmitter; + } +} diff --git a/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java index e7c230e512231..03a0067f4adb1 100644 --- a/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java +++ b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java @@ -27,6 +27,7 @@ import java.util.TreeMap; import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiDeviceReceiver; import javax.sound.midi.MidiMessage; import javax.sound.midi.ShortMessage; diff --git a/jdk/src/share/classes/javax/sound/midi/MidiDevice.java b/jdk/src/share/classes/javax/sound/midi/MidiDevice.java index 0a8fed4785538..1e9f225d94324 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiDevice.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiDevice.java @@ -204,6 +204,9 @@ public interface MidiDevice extends AutoCloseable { * MIDI data. The returned receiver must be closed when the application * has finished using it. * + *
Usually the returned receiver implements + * the {@code MidiDeviceReceiver} interface. + * *
Obtaining a Receiver
with this method does not
* open the device. To be able to use the device, it has to be
* opened explicitly by calling {@link #open}. Also, closing the
@@ -223,6 +226,10 @@ public interface MidiDevice extends AutoCloseable {
* connected with this MidiDevice.
* A receiver can be removed
* from the device by closing it.
+ *
+ *
Usually the returned receivers implement + * the {@code MidiDeviceReceiver} interface. + * * @return an unmodifiable list of the open receivers * @since 1.5 */ @@ -234,6 +241,9 @@ public interface MidiDevice extends AutoCloseable { * MIDI data The returned transmitter must be closed when the application * has finished using it. * + *
Usually the returned transmitter implements + * the {@code MidiDeviceTransmitter} interface. + * *
Obtaining a Transmitter
with this method does not
* open the device. To be able to use the device, it has to be
* opened explicitly by calling {@link #open}. Also, closing the
@@ -253,6 +263,10 @@ public interface MidiDevice extends AutoCloseable {
* connected with this MidiDevice.
* A transmitter can be removed
* from the device by closing it.
+ *
+ *
Usually the returned transmitters implement + * the {@code MidiDeviceTransmitter} interface. + * * @return an unmodifiable list of the open transmitters * @since 1.5 */ diff --git a/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java b/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java similarity index 78% rename from jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java rename to jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java index 9c76783db60da..9ea1df7c38e0c 100644 --- a/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -22,20 +22,18 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.sun.media.sound; -import javax.sound.midi.MidiDevice; -import javax.sound.midi.Receiver; +package javax.sound.midi; /** - * A Receiver with reference to it's MidiDevice object. + *
{@code MidiDeviceReceiver} is a {@code Receiver} which represents + * a MIDI input connector of a {@code MidiDevice} + * (see {@link MidiDevice#getReceiver()}). * - * @author Karl Helgason + * @since 1.7 */ public interface MidiDeviceReceiver extends Receiver { - - /** Obtains the MidiDevice object associated with this Receiver. + /** Obtains a MidiDevice object which is an owner of this Receiver. */ public MidiDevice getMidiDevice(); - } diff --git a/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java b/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java new file mode 100644 index 0000000000000..b6a827188e27e --- /dev/null +++ b/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package javax.sound.midi; + + +/** + *
{@code MidiDeviceTransmitter} is a {@code Transmitter} which represents + * a MIDI input connector of a {@code MidiDevice} + * (see {@link MidiDevice#getTransmitter()}). + * + * @since 1.7 + */ +public interface MidiDeviceTransmitter extends Transmitter { + + /** Obtains a MidiDevice object which is an owner of this Transmitter. + */ + public MidiDevice getMidiDevice(); +} diff --git a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java index f865d92eb8ae1..8c0b5d9ebb5fa 100644 --- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java +++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java @@ -47,6 +47,8 @@ import com.sun.media.sound.JDK13Services; import com.sun.media.sound.ReferenceCountingDevice; import com.sun.media.sound.AutoConnectSequencer; +import com.sun.media.sound.MidiDeviceReceiverEnvelope; +import com.sun.media.sound.MidiDeviceTransmitterEnvelope; /** @@ -225,6 +227,8 @@ public static MidiDevice getMidiDevice(MidiDevice.Info info) throws MidiUnavaila /** * Obtains a MIDI receiver from an external MIDI port * or other default device. + * The returned receiver always implements + * the {@code MidiDeviceReceiver} interface. * *
If the system property
* javax.sound.midi.Receiver
@@ -261,6 +265,9 @@ public static Receiver getReceiver() throws MidiUnavailableException {
} else {
receiver = device.getReceiver();
}
+ if (!(receiver instanceof MidiDeviceReceiver)) {
+ receiver = new MidiDeviceReceiverEnvelope(device, receiver);
+ }
return receiver;
}
@@ -268,6 +275,8 @@ public static Receiver getReceiver() throws MidiUnavailableException {
/**
* Obtains a MIDI transmitter from an external MIDI port
* or other default source.
+ * The returned transmitter always implements
+ * the {@code MidiDeviceTransmitter} interface.
*
*
If the system property
* javax.sound.midi.Transmitter
@@ -301,6 +310,9 @@ public static Transmitter getTransmitter() throws MidiUnavailableException {
} else {
transmitter = device.getTransmitter();
}
+ if (!(transmitter instanceof MidiDeviceReceiver)) {
+ transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
+ }
return transmitter;
}
diff --git a/jdk/test/javax/sound/midi/MidiDeviceConnectors/TestAllDevices.java b/jdk/test/javax/sound/midi/MidiDeviceConnectors/TestAllDevices.java
new file mode 100644
index 0000000000000..fa1d964e1df32
--- /dev/null
+++ b/jdk/test/javax/sound/midi/MidiDeviceConnectors/TestAllDevices.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2010, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 4933700
+ * @summary Tests that default devices return MidiDeviceTransmitter/Receiver and returned objects return correct MidiDevice
+ * @compile -source 1.7 TestAllDevices.java
+ * @run main TestAllDevices
+ * @author Alex Menkov
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDeviceReceiver;
+import javax.sound.midi.MidiDeviceTransmitter;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+
+public class TestAllDevices {
+
+ static boolean failed = false;
+
+ public static void main(String[] args) throws Exception {
+ out("default receiver:");
+ try {
+ Receiver recv = MidiSystem.getReceiver();
+ out(" receiver: " + recv);
+ if (recv instanceof MidiDeviceReceiver) {
+ out(" OK");
+ } else {
+ out(" ERROR: not an instance of MidiDeviceReceiver");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" receiver: MidiUnavailableException (test NOT failed)");
+ }
+
+ out("default transmitter:");
+ try {
+ Transmitter tran = MidiSystem.getTransmitter();
+ out(" transmitter: " + tran);
+ if (tran instanceof MidiDeviceTransmitter) {
+ out(" OK");
+ } else {
+ out(" ERROR: not an instance of MidiDeviceTransmitter");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" transmitter: MidiUnavailableException (test NOT failed)");
+ }
+
+ MidiDevice.Info[] infos = MidiSystem .getMidiDeviceInfo();
+ for (MidiDevice.Info info: infos) {
+ out(info.toString() + ":");
+ try {
+ MidiDevice dev = MidiSystem.getMidiDevice(info);
+ dev.open();
+
+ try {
+ Receiver recv = dev.getReceiver();
+ out(" receiver: " + recv);
+ if (recv instanceof MidiDeviceReceiver) {
+ MidiDeviceReceiver devRecv = (MidiDeviceReceiver)recv;
+ MidiDevice retDev = devRecv.getMidiDevice();
+ if (retDev == dev) {
+ out(" OK");
+ } else {
+ out(" ERROR: getMidiDevice returned incorrect device: " + retDev);
+ failed = true;
+ }
+ } else {
+ out(" ERROR: not an instance of MidiDeviceReceiver");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" receiver: MidiUnavailableException (test NOT failed)");
+ }
+
+ try {
+ Transmitter tran = dev.getTransmitter();
+ out(" transmitter: " + tran);
+ if (tran instanceof MidiDeviceTransmitter) {
+ MidiDeviceTransmitter devTran = (MidiDeviceTransmitter)tran;
+ MidiDevice retDev = devTran.getMidiDevice();
+ if (retDev == dev) {
+ out(" OK");
+ } else {
+ out(" ERROR: getMidiDevice retur4ned incorrect device: " + retDev);
+ failed = true;
+ }
+ } else {
+ out(" ERROR: not an instance of MidiDeviceTransmitter");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" transmitter: MidiUnavailableException (test NOT failed)");
+ }
+
+ dev.close();
+ } catch (MidiUnavailableException ex) {
+ out(" device: MidiUnavailableException (test NOT failed)");
+ }
+ }
+
+ if (failed) {
+ throw new Exception("Test failed.");
+ }
+ }
+
+ static void out(String s) {
+ System.out.println(s);
+ }
+
+}