[Audio-engine-dev] Bug in RealTimeSequencer when used with Gervill

Alex Menkov alex.menkov at sun.com
Thu Feb 7 07:21:30 PST 2008


Karl,

Yes, it's real mis-synchronization of the code.
I've created a CR for the bug.
I'm going to update the code along with RealTimeSequencer code cleaning 
(removing obsolete references to Beatnik code).

Regards
Alex

Karl Helgason wrote:
> I found a bug in RealTimeSequencer when used with Gervill.
> The doAutoConnect opens Gervill synthesizer explicitly
> when it is supposed to open Gervill implicitly.
> 
> Here is the code that reproduced the bug:
> 
> // When we call MidiSystem.getSequencer()
> // a instance of  RealTimeSequencer is created
> // that is connected to Gervill Receiver opened implicitly
> Sequencer seqr = MidiSystem.getSequencer();
> seqr.open();
> 
> // When we call seqr.close the Receiver is also closed and
> // hence the gervill synthesizer is also closed because the
> // receiver was opened implicitly.
> seqr.close();
> 
> // Here is the bug, RealTimeSequencer tries to auto connect
> // again, but opens the Gervill synthesizer explicitly
> // before it tries to get instance of Receiver opened implicitly.
> seqr.open();
> 
> // Gervill synthesizer is never closed
> // when we finally call seqr.close,
> // because it was opened explicitly above.
> seqr.close();
> 
> --------------------------------------
> The error lies here below:
> The doAutoConnect performs synth.open();
> before it tries to get Receiver opened implicity
> by calling getReceiverReferenceCounting.
> 
>     private void doAutoConnect() {
>         if (Printer.trace) Printer.trace(">> RealTimeSequencer: doAutoConnect()");
>         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
>         //            algorithm needs to be used!
>         try {
>             Synthesizer synth = MidiSystem.getSynthesizer();
>             synth.open();
>             if (synth instanceof ReferenceCountingDevice) {
>                 rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting();
>                 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 {
>                 rec = synth.getReceiver();
>             }
>         } catch (Exception e) {
>             // something went wrong with synth
>         }
>         if (rec == null) {
>             // then try to connect to the default Receiver
>             try {
>                 rec = MidiSystem.getReceiver();
>             } catch (Exception e) {
>                 // something went wrong. Nothing to do then!
>             }
>         }
>         if (rec != null) {
>             autoConnectedReceiver = rec;
>             try {
>                 getTransmitter().setReceiver(rec);
>             } catch (Exception e) {}
>         }
>         if (Printer.trace) Printer.trace("<< RealTimeSequencer: doAutoConnect() succeeded");
>     }
> 
> ------------------------
> Here is a example of corrected RealTimeSequencer.
> It now works like MidiSystem.getSequencer(boolean).
> e.g. is now correctly synch'ed with MidiSystem.getReceiver(boolean).
> 
> 
>     private void doAutoConnect() {
>         if (Printer.trace) Printer.trace(">> RealTimeSequencer: doAutoConnect()");
>         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
>         //            algorithm needs to be used!
>         try {
>             Synthesizer synth = MidiSystem.getSynthesizer();
>             if (synth instanceof ReferenceCountingDevice) {
>                 rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting();
>                 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 {
>                     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
>         }
>         if (rec == null) {
>             // then try to connect to the default Receiver
>             try {
>                 rec = MidiSystem.getReceiver();
>             } catch (Exception e) {
>                 // something went wrong. Nothing to do then!
>             }
>         }
>         if (rec != null) {
>             autoConnectedReceiver = rec;
>             try {
>                 getTransmitter().setReceiver(rec);
>             } catch (Exception e) {}
>         }
>         if (Printer.trace) Printer.trace("<< RealTimeSequencer: doAutoConnect() succeeded");
>     }
> _______________________________________________
> audio-engine-dev mailing list
> audio-engine-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/audio-engine-dev



More information about the audio-engine-dev mailing list