OpenJDK / zgc / zgc
changeset 8528:f496950c5d98
6660470: RealTimeSequencer incorrectly opens (implicitly) synthesizer
Reviewed-by: stayer
author | amenkov |
---|---|
date | Thu, 03 Mar 2011 15:57:53 +0300 |
parents | 4b82a41f91bc |
children | 041fad0cabfc |
files | jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java jdk/src/share/classes/javax/sound/midi/MidiSystem.java jdk/test/javax/sound/midi/Sequencer/SequencerImplicitSynthOpen.java |
diffstat | 3 files changed, 120 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java Thu Mar 03 15:45:47 2011 +0300 +++ b/jdk/src/share/classes/com/sun/media/sound/RealTimeSequencer.java Thu Mar 03 15:57:53 2011 +0300 @@ -775,15 +775,22 @@ Receiver rec = null; // first try to connect to the default synthesizer // IMPORTANT: this code needs to be synch'ed with - // MidiSystem.getReceiver(boolean), because the same + // MidiSystem.getSequencer(boolean), because the same // algorithm needs to be used! try { Synthesizer synth = MidiSystem.getSynthesizer(); - synth.open(); if (synth instanceof ReferenceCountingDevice) { rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting(); } else { - rec = synth.getReceiver(); + synth.open(); + try { + rec = synth.getReceiver(); + } finally { + // make sure that the synth is properly closed + if (rec == null) { + synth.close(); + } + } } } catch (Exception e) { // something went wrong with synth
--- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Thu Mar 03 15:45:47 2011 +0300 +++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Thu Mar 03 15:57:53 2011 +0300 @@ -441,13 +441,6 @@ Synthesizer synth = getSynthesizer(); if (synth instanceof ReferenceCountingDevice) { rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting(); - // only use MixerSynth if it could successfully load a soundbank - if (synth.getClass().toString().contains("com.sun.media.sound.MixerSynth") - && (synth.getDefaultSoundbank() == null)) { - // don't use this receiver if no soundbank available - rec = null; - synth.close(); - } } else { synth.open(); try {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Sequencer/SequencerImplicitSynthOpen.java Thu Mar 03 15:57:53 2011 +0300 @@ -0,0 +1,110 @@ +/** + * @test + * @bug 6660470 + * @summary Tests that sequencer correctly opens/closes (implicitly) devices + * @author Alex Menkov + */ + +import java.util.List; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiDeviceReceiver; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Transmitter; + +public class SequencerImplicitSynthOpen { + + static int TEST_COUNT = 5; + + public static void main(String[] args) { + try { + log("getting sequencer..."); + Sequencer sequencer = MidiSystem.getSequencer(); + log(" - got " + getDeviceStr(sequencer)); + + // obtain connected device (usually synthesizer) + MidiDevice synth = getConnectedDevice(sequencer); + if (synth == null) { + log("could not get connected device, returning"); + return; + } + + log("connected device: " + getDeviceStr(synth)); + + int success = 0; + for (int i=0; i<TEST_COUNT; i++) { + if (test(sequencer)) { + success++; + } + } + + if (success != TEST_COUNT) { + throw new RuntimeException("test FAILS"); + } + } catch (MidiUnavailableException ex) { + // this is not a failure + log("Could not get Sequencer"); + } + log("test PASSED."); + } + + static boolean test(Sequencer sequencer) throws MidiUnavailableException { + log(""); + log("opening sequencer..."); + sequencer.open(); // opens connected synthesizer implicitly + MidiDevice synth = getConnectedDevice(sequencer); + log(" connected device: " + getDeviceStr(synth)); + + log("closing sequencer..."); + sequencer.close(); // closes the synth implicitly + log(" synth is " + getDeviceStr(synth)); + MidiDevice synth2 = getConnectedDevice(sequencer); + log(" currently connected device: " + getDeviceStr(synth2)); + + if (synth != null && synth.isOpen()) { + log("FAIL."); + return false; + } + log("OK."); + return true; + } + + static MidiDevice getConnectedDevice(Sequencer sequencer) { + List<Transmitter> trans = sequencer.getTransmitters(); + log(" sequencer has " + trans.size() + " opened transmitters:"); + for (Transmitter tr: trans) { + Receiver r = tr.getReceiver(); + log(" " + getClassStr(tr) + " connected to " + getClassStr(r)); + if (r instanceof MidiDeviceReceiver) { + MidiDeviceReceiver recv = (MidiDeviceReceiver)r; + MidiDevice dev = recv.getMidiDevice(); + log(" - receiver of " + getClassStr(dev)); + return dev; + } else { + log(" - does NOT implement MidiDeviceReceiver"); + } + } + return null; + } + + static String getClassStr(Object o) { + if (o == null) { + return "<null>"; + } + return o.getClass().getName(); + } + + static String getDeviceStr(MidiDevice dev) { + if (dev == null) { + return "NULL"; + } + return getClassStr(dev) + ", " + (dev.isOpen() ? "OPENED" : "CLOSED"); + } + + static void log(String s) { + System.out.println(s); + } + +}