/* |
|
* Copyright (c) 1999, 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.sampled; |
|
/** |
|
* The <code>Line</code> interface represents a mono or multi-channel |
|
* audio feed. A line is an element of the digital audio |
|
* "pipeline," such as a mixer, an input or output port, |
|
* or a data path into or out of a mixer. |
|
* <p> |
|
* A line can have controls, such as gain, pan, and reverb. |
|
* The controls themselves are instances of classes that extend the |
|
* base <code>{@link Control}</code> class. |
|
* The <code>Line</code> interface provides two accessor methods for |
|
* obtaining the line's controls: <code>{@link #getControls getControls}</code> returns the |
|
* entire set, and <code>{@link #getControl getControl}</code> returns a single control of |
|
* specified type. |
|
* <p> |
|
* Lines exist in various states at different times. When a line opens, it reserves system |
|
* resources for itself, and when it closes, these resources are freed for |
|
* other objects or applications. The <code>{@link #isOpen()}</code> method lets |
|
* you discover whether a line is open or closed. |
|
* An open line need not be processing data, however. Such processing is |
|
* typically initiated by subinterface methods such as |
|
* <code>{@link SourceDataLine#write SourceDataLine.write}</code> and |
|
* <code>{@link TargetDataLine#read TargetDataLine.read}</code>. |
|
*<p> |
|
* You can register an object to receive notifications whenever the line's |
|
* state changes. The object must implement the <code>{@link LineListener}</code> |
|
* interface, which consists of the single method |
|
* <code>{@link LineListener#update update}</code>. |
|
* This method will be invoked when a line opens and closes (and, if it's a |
|
* {@link DataLine}, when it starts and stops). |
|
*<p> |
|
* An object can be registered to listen to multiple lines. The event it |
|
* receives in its <code>update</code> method will specify which line created |
|
* the event, what type of event it was |
|
* (<code>OPEN</code>, <code>CLOSE</code>, <code>START</code>, or <code>STOP</code>), |
|
* and how many sample frames the line had processed at the time the event occurred. |
|
* <p> |
|
* Certain line operations, such as open and close, can generate security |
|
* exceptions if invoked by unprivileged code when the line is a shared audio |
|
* resource. |
|
* |
|
* @author Kara Kytle |
|
* |
|
* @see LineEvent |
|
* @since 1.3 |
|
*/ |
|
public interface Line extends AutoCloseable { |
|
/** |
|
* Obtains the <code>Line.Info</code> object describing this |
|
* line. |
|
* @return description of the line |
|
*/ |
|
public Line.Info getLineInfo(); |
|
/** |
|
* Opens the line, indicating that it should acquire any required |
|
* system resources and become operational. |
|
* If this operation |
|
* succeeds, the line is marked as open, and an <code>OPEN</code> event is dispatched |
|
* to the line's listeners. |
|
* <p> |
|
* Note that some lines, once closed, cannot be reopened. Attempts |
|
* to reopen such a line will always result in an <code>LineUnavailableException</code>. |
|
* <p> |
|
* Some types of lines have configurable properties that may affect |
|
* resource allocation. For example, a <code>DataLine</code> must |
|
* be opened with a particular format and buffer size. Such lines |
|
* should provide a mechanism for configuring these properties, such |
|
* as an additional <code>open</code> method or methods which allow |
|
* an application to specify the desired settings. |
|
* <p> |
|
* This method takes no arguments, and opens the line with the current |
|
* settings. For <code>{@link SourceDataLine}</code> and |
|
* <code>{@link TargetDataLine}</code> objects, this means that the line is |
|
* opened with default settings. For a <code>{@link Clip}</code>, however, |
|
* the buffer size is determined when data is loaded. Since this method does not |
|
* allow the application to specify any data to load, an IllegalArgumentException |
|
* is thrown. Therefore, you should instead use one of the <code>open</code> methods |
|
* provided in the <code>Clip</code> interface to load data into the <code>Clip</code>. |
|
* <p> |
|
* For <code>DataLine</code>'s, if the <code>DataLine.Info</code> |
|
* object which was used to retrieve the line, specifies at least |
|
* one fully qualified audio format, the last one will be used |
|
* as the default format. |
|
* |
|
* @throws IllegalArgumentException if this method is called on a Clip instance. |
|
* @throws LineUnavailableException if the line cannot be |
|
* opened due to resource restrictions. |
|
* @throws SecurityException if the line cannot be |
|
* opened due to security restrictions. |
|
* |
|
* @see #close |
|
* @see #isOpen |
|
* @see LineEvent |
|
* @see DataLine |
|
* @see Clip#open(AudioFormat, byte[], int, int) |
|
* @see Clip#open(AudioInputStream) |
|
*/ |
|
public void open() throws LineUnavailableException; |
|
/** |
|
* Closes the line, indicating that any system resources |
|
* in use by the line can be released. If this operation |
|
* succeeds, the line is marked closed and a <code>CLOSE</code> event is dispatched |
|
* to the line's listeners. |
|
* @throws SecurityException if the line cannot be |
|
* closed due to security restrictions. |
|
* |
|
* @see #open |
|
* @see #isOpen |
|
* @see LineEvent |
|
*/ |
|
public void close(); |
|
/** |
|
* Indicates whether the line is open, meaning that it has reserved |
|
* system resources and is operational, although it might not currently be |
|
* playing or capturing sound. |
|
* @return <code>true</code> if the line is open, otherwise <code>false</code> |
|
* |
|
* @see #open() |
|
* @see #close() |
|
*/ |
|
public boolean isOpen(); |
|
/** |
|
* Obtains the set of controls associated with this line. |
|
* Some controls may only be available when the line is open. |
|
* If there are no controls, this method returns an array of length 0. |
|
* @return the array of controls |
|
* @see #getControl |
|
*/ |
|
public Control[] getControls(); |
|
/** |
|
* Indicates whether the line supports a control of the specified type. |
|
* Some controls may only be available when the line is open. |
|
* @param control the type of the control for which support is queried |
|
* @return <code>true</code> if at least one control of the specified type is |
|
* supported, otherwise <code>false</code>. |
|
*/ |
|
public boolean isControlSupported(Control.Type control); |
|
/** |
|
* Obtains a control of the specified type, |
|
* if there is any. |
|
* Some controls may only be available when the line is open. |
|
* @param control the type of the requested control |
|
* @return a control of the specified type |
|
* @throws IllegalArgumentException if a control of the specified type |
|
* is not supported |
|
* @see #getControls |
|
* @see #isControlSupported(Control.Type control) |
|
*/ |
|
public Control getControl(Control.Type control); |
|
/** |
|
* Adds a listener to this line. Whenever the line's status changes, the |
|
* listener's <code>update()</code> method is called with a <code>LineEvent</code> object |
|
* that describes the change. |
|
* @param listener the object to add as a listener to this line |
|
* @see #removeLineListener |
|
* @see LineListener#update |
|
* @see LineEvent |
|
*/ |
|
public void addLineListener(LineListener listener); |
|
/** |
|
* Removes the specified listener from this line's list of listeners. |
|
* @param listener listener to remove |
|
* @see #addLineListener |
|
*/ |
|
public void removeLineListener(LineListener listener); |
|
/** |
|
* A <code>Line.Info</code> object contains information about a line. |
|
* The only information provided by <code>Line.Info</code> itself |
|
* is the Java class of the line. |
|
* A subclass of <code>Line.Info</code> adds other kinds of information |
|
* about the line. This additional information depends on which <code>Line</code> |
|
* subinterface is implemented by the kind of line that the <code>Line.Info</code> |
|
* subclass describes. |
|
* <p> |
|
* A <code>Line.Info</code> can be retrieved using various methods of |
|
* the <code>Line</code>, <code>Mixer</code>, and <code>AudioSystem</code> |
|
* interfaces. Other such methods let you pass a <code>Line.Info</code> as |
|
* an argument, to learn whether lines matching the specified configuration |
|
* are available and to obtain them. |
|
* |
|
* @author Kara Kytle |
|
* |
|
* @see Line#getLineInfo |
|
* @see Mixer#getSourceLineInfo |
|
* @see Mixer#getTargetLineInfo |
|
* @see Mixer#getLine <code>Mixer.getLine(Line.Info)</code> |
|
* @see Mixer#getSourceLineInfo(Line.Info) <code>Mixer.getSourceLineInfo(Line.Info)</code> |
|
* @see Mixer#getSourceLineInfo(Line.Info) <code>Mixer.getTargetLineInfo(Line.Info)</code> |
|
* @see Mixer#isLineSupported <code>Mixer.isLineSupported(Line.Info)</code> |
|
* @see AudioSystem#getLine <code>AudioSystem.getLine(Line.Info)</code> |
|
* @see AudioSystem#getSourceLineInfo <code>AudioSystem.getSourceLineInfo(Line.Info)</code> |
|
* @see AudioSystem#getTargetLineInfo <code>AudioSystem.getTargetLineInfo(Line.Info)</code> |
|
* @see AudioSystem#isLineSupported <code>AudioSystem.isLineSupported(Line.Info)</code> |
|
* @since 1.3 |
|
*/ |
|
public static class Info { |
|
/** |
|
* The class of the line described by the info object. |
|
*/ |
|
private final Class lineClass; |
|
/** |
|
* Constructs an info object that describes a line of the specified class. |
|
* This constructor is typically used by an application to |
|
* describe a desired line. |
|
* @param lineClass the class of the line that the new Line.Info object describes |
|
*/ |
|
public Info(Class<?> lineClass) { |
|
if (lineClass == null) { |
|
this.lineClass = Line.class; |
|
} else { |
|
this.lineClass = lineClass; |
|
} |
|
} |
|
/** |
|
* Obtains the class of the line that this Line.Info object describes. |
|
* @return the described line's class |
|
*/ |
|
public Class<?> getLineClass() { |
|
return lineClass; |
|
} |
|
/** |
|
* Indicates whether the specified info object matches this one. |
|
* To match, the specified object must be identical to or |
|
* a special case of this one. The specified info object |
|
* must be either an instance of the same class as this one, |
|
* or an instance of a sub-type of this one. In addition, the |
|
* attributes of the specified object must be compatible with the |
|
* capabilities of this one. Specifically, the routing configuration |
|
* for the specified info object must be compatible with that of this |
|
* one. |
|
* Subclasses may add other criteria to determine whether the two objects |
|
* match. |
|
* |
|
* @param info the info object which is being compared to this one |
|
* @return <code>true</code> if the specified object matches this one, |
|
* <code>false</code> otherwise |
|
*/ |
|
public boolean matches(Info info) { |
|
// $$kk: 08.30.99: is this backwards? |
|
// dataLine.matches(targetDataLine) == true: targetDataLine is always dataLine |
|
// targetDataLine.matches(dataLine) == false |
|
// so if i want to make sure i get a targetDataLine, i need: |
|
// targetDataLine.matches(prospective_match) == true |
|
// => prospective_match may be other things as well, but it is at least a targetDataLine |
|
// targetDataLine defines the requirements which prospective_match must meet. |
|
// "if this Class object represents a declared class, this method returns |
|
// true if the specified Object argument is an instance of the represented |
|
// class (or of any of its subclasses)" |
|
// GainControlClass.isInstance(MyGainObj) => true |
|
// GainControlClass.isInstance(MySpecialGainInterfaceObj) => true |
|
// this_class.isInstance(that_object) => that object can by cast to this class |
|
// => that_object's class may be a subtype of this_class |
|
// => that may be more specific (subtype) of this |
|
// "If this Class object represents an interface, this method returns true |
|
// if the class or any superclass of the specified Object argument implements |
|
// this interface" |
|
// GainControlClass.isInstance(MyGainObj) => true |
|
// GainControlClass.isInstance(GenericControlObj) => may be false |
|
// => that may be more specific |
|
if (! (this.getClass().isInstance(info)) ) { |
|
return false; |
|
} |
|
// this.isAssignableFrom(that) => this is same or super to that |
|
// => this is at least as general as that |
|
// => that may be subtype of this |
|
if (! (getLineClass().isAssignableFrom(info.getLineClass())) ) { |
|
return false; |
|
} |
|
return true; |
|
} |
|
/** |
|
* Obtains a textual description of the line info. |
|
* @return a string description |
|
*/ |
|
public String toString() { |
|
String fullPackagePath = "javax.sound.sampled."; |
|
String initialString = new String(getLineClass().toString()); |
|
String finalString; |
|
int index = initialString.indexOf(fullPackagePath); |
|
if (index != -1) { |
|
finalString = initialString.substring(0, index) + initialString.substring( (index + fullPackagePath.length()), initialString.length() ); |
|
} else { |
|
finalString = initialString; |
|
} |
|
return finalString; |
|
} |
|
} // class Info |
|
} // interface Line |