< prev index next >

src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDevice.java

Print this page

        

*** 24,37 **** */ package com.sun.media.sound; import java.util.ArrayList; - import java.util.List; import java.util.Collections; ! import javax.sound.midi.*; /** * Abstract AbstractMidiDevice class representing functionality shared by * MidiInDevice and MidiOutDevice objects. --- 24,44 ---- */ package com.sun.media.sound; import java.util.ArrayList; import java.util.Collections; + import java.util.List; ! import javax.sound.midi.InvalidMidiDataException; ! import javax.sound.midi.MidiDevice; ! import javax.sound.midi.MidiDeviceReceiver; ! import javax.sound.midi.MidiDeviceTransmitter; ! import javax.sound.midi.MidiMessage; ! import javax.sound.midi.MidiUnavailableException; ! import javax.sound.midi.Receiver; ! import javax.sound.midi.Transmitter; /** * Abstract AbstractMidiDevice class representing functionality shared by * MidiInDevice and MidiOutDevice objects.
*** 41,55 **** * @author Matthias Pfisterer * @author Florian Bomers */ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice { - // STATIC VARIABLES private static final boolean TRACE_TRANSMITTER = false; - // INSTANCE VARIABLES - private ArrayList<Receiver> receiverList; private TransmitterList transmitterList; // lock to protect receiverList and transmitterList --- 48,59 ----
*** 60,89 **** // DEVICE ATTRIBUTES private final MidiDevice.Info info; - // DEVICE STATE private volatile boolean open; private int openRefCount; /** List of Receivers and Transmitters that opened the device implicitely. */ private List<Object> openKeepingObjects; /** ! * This is the device handle returned from native code */ protected volatile long id; - - - // CONSTRUCTOR - - /** * Constructs an AbstractMidiDevice with the specified info object. * @param info the description of the device */ /* --- 64,87 ---- // DEVICE ATTRIBUTES private final MidiDevice.Info info; // DEVICE STATE private volatile boolean open; private int openRefCount; /** List of Receivers and Transmitters that opened the device implicitely. */ private List<Object> openKeepingObjects; /** ! * This is the device handle returned from native code. */ protected volatile long id; /** * Constructs an AbstractMidiDevice with the specified info object. * @param info the description of the device */ /*
*** 97,129 **** openRefCount = 0; if(Printer.trace) Printer.trace("<< AbstractMidiDevice CONSTRUCTOR completed"); } - // MIDI DEVICE METHODS public final MidiDevice.Info getDeviceInfo() { return info; } /** Open the device from an application program. * Setting the open reference count to -1 here prevents Transmitters and Receivers that * opened the device implicitly from closing it. The only way to close the device after * this call is a call to close(). */ public final void open() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: open()"); synchronized(this) { openRefCount = -1; doOpen(); } if (Printer.trace) Printer.trace("< AbstractMidiDevice: open() completed"); } - - /** Open the device implicitly. * This method is intended to be used by AbstractReceiver * and BasicTransmitter. Actually, it is called by getReceiverReferenceCounting() and * getTransmitterReferenceCounting(). These, in turn, are called by MidiSytem on calls to * getReceiver() and getTransmitter(). The former methods should pass the Receiver or --- 95,126 ---- openRefCount = 0; if(Printer.trace) Printer.trace("<< AbstractMidiDevice CONSTRUCTOR completed"); } // MIDI DEVICE METHODS + @Override public final MidiDevice.Info getDeviceInfo() { return info; } /** Open the device from an application program. * Setting the open reference count to -1 here prevents Transmitters and Receivers that * opened the device implicitly from closing it. The only way to close the device after * this call is a call to close(). */ + @Override public final void open() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: open()"); synchronized(this) { openRefCount = -1; doOpen(); } if (Printer.trace) Printer.trace("< AbstractMidiDevice: open() completed"); } /** Open the device implicitly. * This method is intended to be used by AbstractReceiver * and BasicTransmitter. Actually, it is called by getReceiverReferenceCounting() and * getTransmitterReferenceCounting(). These, in turn, are called by MidiSytem on calls to * getReceiver() and getTransmitter(). The former methods should pass the Receiver or
*** 144,154 **** doOpen(); } if (Printer.trace) Printer.trace("< AbstractMidiDevice: openInternal() completed"); } - private void doOpen() throws MidiUnavailableException { if (Printer.trace) Printer.trace("> AbstractMidiDevice: doOpen()"); synchronized(this) { if (! isOpen()) { implOpen(); --- 141,150 ----
*** 156,176 **** } } if (Printer.trace) Printer.trace("< AbstractMidiDevice: doOpen() completed"); } ! public final void close() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: close()"); synchronized (this) { doClose(); openRefCount = 0; } if (Printer.trace) Printer.trace("< AbstractMidiDevice: close() completed"); } - /** Close the device for an object that implicitely opened it. * This method is intended to be used by Transmitter.close() and Receiver.close(). * Those methods should pass this for the object parameter. Since Transmitters or Receivers * do not know if their device has been opened implicitely because of them, they call this * method in any case. This method now is able to seperate Receivers/Transmitters that opened --- 152,171 ---- } } if (Printer.trace) Printer.trace("< AbstractMidiDevice: doOpen() completed"); } ! @Override public final void close() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: close()"); synchronized (this) { doClose(); openRefCount = 0; } if (Printer.trace) Printer.trace("< AbstractMidiDevice: close() completed"); } /** Close the device for an object that implicitely opened it. * This method is intended to be used by Transmitter.close() and Receiver.close(). * Those methods should pass this for the object parameter. Since Transmitters or Receivers * do not know if their device has been opened implicitely because of them, they call this * method in any case. This method now is able to seperate Receivers/Transmitters that opened
*** 194,204 **** } } if (Printer.trace) Printer.trace("< AbstractMidiDevice: closeInternal() completed"); } - public final void doClose() { if (Printer.trace) Printer.trace("> AbstractMidiDevice: doClose()"); synchronized(this) { if (isOpen()) { implClose(); --- 189,198 ----
*** 206,221 **** } } if (Printer.trace) Printer.trace("< AbstractMidiDevice: doClose() completed"); } ! public final boolean isOpen() { return open; } - protected void implClose() { synchronized (traRecLock) { if (receiverList != null) { // close all receivers for(int i = 0; i < receiverList.size(); i++) { --- 200,214 ---- } } if (Printer.trace) Printer.trace("< AbstractMidiDevice: doClose() completed"); } ! @Override public final boolean isOpen() { return open; } protected void implClose() { synchronized (traRecLock) { if (receiverList != null) { // close all receivers for(int i = 0; i < receiverList.size(); i++) {
*** 228,291 **** transmitterList.close(); } } } - /** * This implementation always returns -1. * Devices that actually provide this should over-ride * this method. */ public long getMicrosecondPosition() { return -1; } - /** Return the maximum number of Receivers supported by this device. Depending on the return value of hasReceivers(), this method returns either 0 or -1. Subclasses should rather override hasReceivers() than override this method. */ public final int getMaxReceivers() { if (hasReceivers()) { return -1; } else { return 0; } } - /** Return the maximum number of Transmitters supported by this device. Depending on the return value of hasTransmitters(), this method returns either 0 or -1. Subclasses should override hasTransmitters(). */ public final int getMaxTransmitters() { if (hasTransmitters()) { return -1; } else { return 0; } } - /** Retrieve a Receiver for this device. This method returns the value returned by createReceiver(), if it doesn't throw an exception. Subclasses should rather override createReceiver() than override this method. If createReceiver returns a Receiver, it is added to the internal list of Receivers (see getReceiversList) */ public final Receiver getReceiver() throws MidiUnavailableException { Receiver receiver; synchronized (traRecLock) { receiver = createReceiver(); // may throw MidiUnavailableException getReceiverList().add(receiver); } return receiver; } ! @SuppressWarnings("unchecked") // Cast of result of clone public final List<Receiver> getReceivers() { List<Receiver> recs; synchronized (traRecLock) { if (receiverList == null) { --- 221,284 ---- transmitterList.close(); } } } /** * This implementation always returns -1. * Devices that actually provide this should over-ride * this method. */ + @Override public long getMicrosecondPosition() { return -1; } /** Return the maximum number of Receivers supported by this device. Depending on the return value of hasReceivers(), this method returns either 0 or -1. Subclasses should rather override hasReceivers() than override this method. */ + @Override public final int getMaxReceivers() { if (hasReceivers()) { return -1; } else { return 0; } } /** Return the maximum number of Transmitters supported by this device. Depending on the return value of hasTransmitters(), this method returns either 0 or -1. Subclasses should override hasTransmitters(). */ + @Override public final int getMaxTransmitters() { if (hasTransmitters()) { return -1; } else { return 0; } } /** Retrieve a Receiver for this device. This method returns the value returned by createReceiver(), if it doesn't throw an exception. Subclasses should rather override createReceiver() than override this method. If createReceiver returns a Receiver, it is added to the internal list of Receivers (see getReceiversList) */ + @Override public final Receiver getReceiver() throws MidiUnavailableException { Receiver receiver; synchronized (traRecLock) { receiver = createReceiver(); // may throw MidiUnavailableException getReceiverList().add(receiver); } return receiver; } ! @Override @SuppressWarnings("unchecked") // Cast of result of clone public final List<Receiver> getReceivers() { List<Receiver> recs; synchronized (traRecLock) { if (receiverList == null) {
*** 296,321 **** } } return recs; } - /** * This implementation uses createTransmitter, which may throw an exception. * If a transmitter is returned in createTransmitter, it is added to the internal * TransmitterList */ public final Transmitter getTransmitter() throws MidiUnavailableException { Transmitter transmitter; synchronized (traRecLock) { transmitter = createTransmitter(); // may throw MidiUnavailableException getTransmitterList().add(transmitter); } return transmitter; } ! @SuppressWarnings("unchecked") // Cast of result of clone public final List<Transmitter> getTransmitters() { List<Transmitter> tras; synchronized (traRecLock) { if (transmitterList == null --- 289,314 ---- } } return recs; } /** * This implementation uses createTransmitter, which may throw an exception. * If a transmitter is returned in createTransmitter, it is added to the internal * TransmitterList */ + @Override public final Transmitter getTransmitter() throws MidiUnavailableException { Transmitter transmitter; synchronized (traRecLock) { transmitter = createTransmitter(); // may throw MidiUnavailableException getTransmitterList().add(transmitter); } return transmitter; } ! @Override @SuppressWarnings("unchecked") // Cast of result of clone public final List<Transmitter> getTransmitters() { List<Transmitter> tras; synchronized (traRecLock) { if (transmitterList == null
*** 326,348 **** } } return tras; } - - // HELPER METHODS - final long getId() { return id; } - // REFERENCE COUNTING /** Retrieve a Receiver and open the device implicitly. This method is called by MidiSystem.getReceiver(). */ public final Receiver getReceiverReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getReceiver() throws an exception, openInternal() should not be called! */ --- 319,338 ---- } } return tras; } final long getId() { return id; } // REFERENCE COUNTING /** Retrieve a Receiver and open the device implicitly. This method is called by MidiSystem.getReceiver(). */ + @Override public final Receiver getReceiverReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getReceiver() throws an exception, openInternal() should not be called! */
*** 352,365 **** AbstractMidiDevice.this.openInternal(receiver); } return receiver; } - /** Retrieve a Transmitter and open the device implicitly. This method is called by MidiSystem.getTransmitter(). */ public final Transmitter getTransmitterReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getTransmitter() throws an exception, openInternal() should not be called! */ --- 342,355 ---- AbstractMidiDevice.this.openInternal(receiver); } return receiver; } /** Retrieve a Transmitter and open the device implicitly. This method is called by MidiSystem.getTransmitter(). */ + @Override public final Transmitter getTransmitterReferenceCounting() throws MidiUnavailableException { /* Keep this order of commands! If getTransmitter() throws an exception, openInternal() should not be called! */
*** 369,416 **** AbstractMidiDevice.this.openInternal(transmitter); } return transmitter; } - /** Return the list of objects that have opened the device implicitely. */ private synchronized List<Object> getOpenKeepingObjects() { if (openKeepingObjects == null) { openKeepingObjects = new ArrayList<>(); } return openKeepingObjects; } - - // RECEIVER HANDLING METHODS - /** Return the internal list of Receivers, possibly creating it first. */ private List<Receiver> getReceiverList() { synchronized (traRecLock) { if (receiverList == null) { ! receiverList = new ArrayList<Receiver>(); } } return receiverList; } - /** Returns if this device supports Receivers. Subclasses that use Receivers should override this method to return true. They also should override createReceiver(). @return true, if the device supports Receivers, false otherwise. */ protected boolean hasReceivers() { return false; } - /** Create a Receiver object. throwing an exception here means that Receivers aren't enabled. Subclasses that use Receivers should override this method with one that returns objects implementing Receiver. Classes overriding this method should also override hasReceivers() --- 359,400 ---- AbstractMidiDevice.this.openInternal(transmitter); } return transmitter; } /** Return the list of objects that have opened the device implicitely. */ private synchronized List<Object> getOpenKeepingObjects() { if (openKeepingObjects == null) { openKeepingObjects = new ArrayList<>(); } return openKeepingObjects; } // RECEIVER HANDLING METHODS /** Return the internal list of Receivers, possibly creating it first. */ private List<Receiver> getReceiverList() { synchronized (traRecLock) { if (receiverList == null) { ! receiverList = new ArrayList<>(); } } return receiverList; } /** Returns if this device supports Receivers. Subclasses that use Receivers should override this method to return true. They also should override createReceiver(). @return true, if the device supports Receivers, false otherwise. */ protected boolean hasReceivers() { return false; } /** Create a Receiver object. throwing an exception here means that Receivers aren't enabled. Subclasses that use Receivers should override this method with one that returns objects implementing Receiver. Classes overriding this method should also override hasReceivers()
*** 418,429 **** */ protected Receiver createReceiver() throws MidiUnavailableException { throw new MidiUnavailableException("MIDI IN receiver not available"); } - - // TRANSMITTER HANDLING /** Return the internal list of Transmitters, possibly creating it first. */ final TransmitterList getTransmitterList() { --- 402,411 ----
*** 433,454 **** } } return transmitterList; } - /** Returns if this device supports Transmitters. Subclasses that use Transmitters should override this method to return true. They also should override createTransmitter(). @return true, if the device supports Transmitters, false otherwise. */ protected boolean hasTransmitters() { return false; } - /** Create a Transmitter object. throwing an exception here means that Transmitters aren't enabled. Subclasses that use Transmitters should override this method with one that returns objects implementing Transmitters. Classes overriding this method should also override hasTransmitters() --- 415,434 ----
*** 456,479 **** */ protected Transmitter createTransmitter() throws MidiUnavailableException { throw new MidiUnavailableException("MIDI OUT transmitter not available"); } - // ABSTRACT METHODS - protected abstract void implOpen() throws MidiUnavailableException; - /** ! * close this device if discarded by the garbage collector */ protected final void finalize() { close(); } - // INNER CLASSES - /** Base class for Receivers. Subclasses that use Receivers must use this base class, since it contains magic necessary to manage implicit closing the device. This is necessary for Receivers retrieved via MidiSystem.getReceiver() (which opens the device implicitely). --- 436,455 ---- */ protected Transmitter createTransmitter() throws MidiUnavailableException { throw new MidiUnavailableException("MIDI OUT transmitter not available"); } protected abstract void implOpen() throws MidiUnavailableException; /** ! * close this device if discarded by the garbage collector. */ + @Override protected final void finalize() { close(); } /** Base class for Receivers. Subclasses that use Receivers must use this base class, since it contains magic necessary to manage implicit closing the device. This is necessary for Receivers retrieved via MidiSystem.getReceiver() (which opens the device implicitely).
*** 548,597 **** private void setTransmitterList(TransmitterList tlist) { this.tlist = tlist; } public final void setReceiver(Receiver receiver) { if (tlist != null && this.receiver != receiver) { if (Printer.debug) Printer.debug("Transmitter "+toString()+": set receiver "+receiver); tlist.receiverChanged(this, this.receiver, receiver); this.receiver = receiver; } } public final Receiver getReceiver() { return receiver; } - /** Close the Transmitter. * Here, the call to the magic method closeInternal() takes place. * Therefore, subclasses that override this method must call * 'super.close()'. */ public final void close() { AbstractMidiDevice.this.closeInternal(this); if (tlist != null) { tlist.receiverChanged(this, this.receiver, null); tlist.remove(this); tlist = null; } } public final MidiDevice getMidiDevice() { return AbstractMidiDevice.this; } } // class BasicTransmitter - /** ! * a class to manage a list of transmitters */ final class TransmitterList { ! private final ArrayList<Transmitter> transmitters = new ArrayList<Transmitter>(); private MidiOutDevice.MidiOutReceiver midiOutReceiver; // how many transmitters must be present for optimized // handling private int optimizedReceiverCount = 0; --- 524,575 ---- private void setTransmitterList(TransmitterList tlist) { this.tlist = tlist; } + @Override public final void setReceiver(Receiver receiver) { if (tlist != null && this.receiver != receiver) { if (Printer.debug) Printer.debug("Transmitter "+toString()+": set receiver "+receiver); tlist.receiverChanged(this, this.receiver, receiver); this.receiver = receiver; } } + @Override public final Receiver getReceiver() { return receiver; } /** Close the Transmitter. * Here, the call to the magic method closeInternal() takes place. * Therefore, subclasses that override this method must call * 'super.close()'. */ + @Override public final void close() { AbstractMidiDevice.this.closeInternal(this); if (tlist != null) { tlist.receiverChanged(this, this.receiver, null); tlist.remove(this); tlist = null; } } + @Override public final MidiDevice getMidiDevice() { return AbstractMidiDevice.this; } } // class BasicTransmitter /** ! * a class to manage a list of transmitters. */ final class TransmitterList { ! private final ArrayList<Transmitter> transmitters = new ArrayList<>(); private MidiOutDevice.MidiOutReceiver midiOutReceiver; // how many transmitters must be present for optimized // handling private int optimizedReceiverCount = 0;
*** 710,722 **** // this happens when invalid data comes over the wire. Ignore it. return; } } - /** ! * Send this message to all transmitters */ void sendMessage(MidiMessage message, long timeStamp) { if (message instanceof FastShortMessage) { sendMessage(((FastShortMessage) message).getPackedMsg(), timeStamp); return; --- 688,699 ---- // this happens when invalid data comes over the wire. Ignore it. return; } } /** ! * Send this message to all transmitters. */ void sendMessage(MidiMessage message, long timeStamp) { if (message instanceof FastShortMessage) { sendMessage(((FastShortMessage) message).getPackedMsg(), timeStamp); return;
*** 744,753 **** } } } } } - - } // TransmitterList - } --- 721,727 ----
< prev index next >