1. /*
  2. * @(#)Line.java 1.29 04/07/14
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.sound.sampled;
  8. /**
  9. * The <code>Line</code> interface represents a mono or multi-channel
  10. * audio feed. A line is an element of the digital audio
  11. * "pipeline," such as a mixer, an input or output port,
  12. * or a data path into or out of a mixer.
  13. * <p>
  14. * A line can have controls, such as gain, pan, and reverb.
  15. * The controls themselves are instances of classes that extend the
  16. * base <code>{@link Control}</code> class.
  17. * The <code>Line</code> interface provides two accessor methods for
  18. * obtaining the line's controls: <code>{@link #getControls getControls}</code> returns the
  19. * entire set, and <code>{@link #getControl getControl}</code> returns a single control of
  20. * specified type.
  21. * <p>
  22. * Lines exist in various states at different times. When a line opens, it reserves system
  23. * resources for itself, and when it closes, these resources are freed for
  24. * other objects or applications. The <code>{@link #isOpen()}</code> method lets
  25. * you discover whether a line is open or closed.
  26. * An open line need not be processing data, however. Such processing is
  27. * typically initiated by subinterface methods such as
  28. * <code>{@link SourceDataLine#write SourceDataLine.write}</code> and
  29. * <code>{@link TargetDataLine#read TargetDataLine.read}</code>.
  30. *<p>
  31. * You can register an object to receive notifications whenever the line's
  32. * state changes. The object must implement the <code>{@link LineListener}</code>
  33. * interface, which consists of the single method
  34. * <code>{@link LineListener#update update}</code>.
  35. * This method will be invoked when a line opens and closes (and, if it's a
  36. * {@link DataLine}, when it starts and stops).
  37. *<p>
  38. * An object can be registered to listen to multiple lines. The event it
  39. * receives in its <code>update</code> method will specify which line created
  40. * the event, what type of event it was
  41. * (<code>OPEN</code>, <code>CLOSE</code>, <code>START</code>, or <code>STOP</code>),
  42. * and how many sample frames the line had processed at the time the event occurred.
  43. * <p>
  44. * Certain line operations, such as open and close, can generate security
  45. * exceptions if invoked by unprivileged code when the line is a shared audio
  46. * resource.
  47. *
  48. * @author Kara Kytle
  49. * @version 1.29, 04/07/14
  50. *
  51. * @see LineEvent
  52. * @since 1.3
  53. */
  54. public interface Line {
  55. /**
  56. * Obtains the <code>Line.Info</code> object describing this
  57. * line.
  58. * @return description of the line
  59. */
  60. public Line.Info getLineInfo();
  61. /**
  62. * Opens the line, indicating that it should acquire any required
  63. * system resources and become operational.
  64. * If this operation
  65. * succeeds, the line is marked as open, and an <code>OPEN</code> event is dispatched
  66. * to the line's listeners.
  67. * <p>
  68. * Note that some lines, once closed, cannot be reopened. Attempts
  69. * to reopen such a line will always result in an <code>LineUnavailableException</code>.
  70. * <p>
  71. * Some types of lines have configurable properties that may affect
  72. * resource allocation. For example, a <code>DataLine</code> must
  73. * be opened with a particular format and buffer size. Such lines
  74. * should provide a mechanism for configuring these properties, such
  75. * as an additional <code>open</code> method or methods which allow
  76. * an application to specify the desired settings.
  77. * <p>
  78. * This method takes no arguments, and opens the line with the current
  79. * settings. For <code>{@link SourceDataLine}</code> and
  80. * <code>{@link TargetDataLine}</code> objects, this means that the line is
  81. * opened with default settings. For a <code>{@link Clip}</code>, however,
  82. * the buffer size is determined when data is loaded. Since this method does not
  83. * allow the application to specify any data to load, an IllegalArgumentException
  84. * is thrown. Therefore, you should instead use one of the <code>open</code> methods
  85. * provided in the <code>Clip</code> interface to load data into the <code>Clip</code>.
  86. * <p>
  87. * For <code>DataLine</code>'s, if the <code>DataLine.Info</code>
  88. * object which was used to retrieve the line, specifies at least
  89. * one fully qualified audio format, the last one will be used
  90. * as the default format.
  91. *
  92. * @throws IllegalArgumentException if this method is called on a Clip instance.
  93. * @throws LineUnavailableException if the line cannot be
  94. * opened due to resource restrictions.
  95. * @throws SecurityException if the line cannot be
  96. * opened due to security restrictions.
  97. *
  98. * @see #close
  99. * @see #isOpen
  100. * @see LineEvent
  101. * @see DataLine
  102. * @see Clip#open(AudioFormat, byte[], int, int)
  103. * @see Clip#open(AudioInputStream)
  104. */
  105. public void open() throws LineUnavailableException;
  106. /**
  107. * Closes the line, indicating that any system resources
  108. * in use by the line can be released. If this operation
  109. * succeeds, the line is marked closed and a <code>CLOSE</code> event is dispatched
  110. * to the line's listeners.
  111. * @throws SecurityException if the line cannot be
  112. * closed due to security restrictions.
  113. *
  114. * @see #open
  115. * @see #isOpen
  116. * @see LineEvent
  117. */
  118. public void close();
  119. /**
  120. * Indicates whether the line is open, meaning that it has reserved
  121. * system resources and is operational, although it might not currently be
  122. * playing or capturing sound.
  123. * @return <code>true</code> if the line is open, otherwise <code>false</code>
  124. *
  125. * @see #open()
  126. * @see #close()
  127. */
  128. public boolean isOpen();
  129. /**
  130. * Obtains the set of controls associated with this line.
  131. * Some controls may only be available when the line is open.
  132. * If there are no controls, this method returns an array of length 0.
  133. * @return the array of controls
  134. * @see #getControl
  135. */
  136. public Control[] getControls();
  137. /**
  138. * Indicates whether the line supports a control of the specified type.
  139. * Some controls may only be available when the line is open.
  140. * @param control the type of the control for which support is queried
  141. * @return <code>true</code> if at least one control of the specified type is
  142. * supported, otherwise <code>false</code>.
  143. */
  144. public boolean isControlSupported(Control.Type control);
  145. /**
  146. * Obtains a control of the specified type,
  147. * if there is any.
  148. * Some controls may only be available when the line is open.
  149. * @param control the type of the requested control
  150. * @return a control of the specified type
  151. * @throws IllegalArgumentException if a control of the specified type
  152. * is not supported
  153. * @see #getControls
  154. * @see #isControlSupported(Control.Type control)
  155. */
  156. public Control getControl(Control.Type control);
  157. /**
  158. * Adds a listener to this line. Whenever the line's status changes, the
  159. * listener's <code>update()</code> method is called with a <code>LineEvent</code> object
  160. * that describes the change.
  161. * @param listener the object to add as a listener to this line
  162. * @see #removeLineListener
  163. * @see LineListener#update
  164. * @see LineEvent
  165. */
  166. public void addLineListener(LineListener listener);
  167. /**
  168. * Removes the specified listener from this line's list of listeners.
  169. * @param listener listener to remove
  170. * @see #addLineListener
  171. */
  172. public void removeLineListener(LineListener listener);
  173. /**
  174. * A <code>Line.Info</code> object contains information about a line.
  175. * The only information provided by <code>Line.Info</code> itself
  176. * is the Java class of the line.
  177. * A subclass of <code>Line.Info</code> adds other kinds of information
  178. * about the line. This additional information depends on which <code>Line</code>
  179. * subinterface is implemented by the kind of line that the <code>Line.Info</code>
  180. * subclass describes.
  181. * <p>
  182. * A <code>Line.Info</code> can be retrieved using various methods of
  183. * the <code>Line</code>, <code>Mixer</code>, and <code>AudioSystem</code>
  184. * interfaces. Other such methods let you pass a <code>Line.Info</code> as
  185. * an argument, to learn whether lines matching the specified configuration
  186. * are available and to obtain them.
  187. *
  188. * @author Kara Kytle
  189. * @version 1.29, 04/07/14
  190. *
  191. * @see Line#getLineInfo
  192. * @see Mixer#getSourceLineInfo
  193. * @see Mixer#getTargetLineInfo
  194. * @see Mixer#getLine <code>Mixer.getLine(Line.Info)</code>
  195. * @see Mixer#getSourceLineInfo(Line.Info) <code>Mixer.getSourceLineInfo(Line.Info)</code>
  196. * @see Mixer#getSourceLineInfo(Line.Info) <code>Mixer.getTargetLineInfo(Line.Info)</code>
  197. * @see Mixer#isLineSupported <code>Mixer.isLineSupported(Line.Info)</code>
  198. * @see AudioSystem#getLine <code>AudioSystem.getLine(Line.Info)</code>
  199. * @see AudioSystem#getSourceLineInfo <code>AudioSystem.getSourceLineInfo(Line.Info)</code>
  200. * @see AudioSystem#getTargetLineInfo <code>AudioSystem.getTargetLineInfo(Line.Info)</code>
  201. * @see AudioSystem#isLineSupported <code>AudioSystem.isLineSupported(Line.Info)</code>
  202. * @since 1.3
  203. */
  204. public static class Info {
  205. /**
  206. * The class of the line described by the info object.
  207. */
  208. private final Class lineClass;
  209. /**
  210. * Constructs an info object that describes a line of the specified class.
  211. * This constructor is typically used by an application to
  212. * describe a desired line.
  213. * @param lineClass the class of the line that the new Line.Info object describes
  214. */
  215. public Info(Class<?> lineClass) {
  216. if (lineClass == null) {
  217. this.lineClass = Line.class;
  218. } else {
  219. this.lineClass = lineClass;
  220. }
  221. }
  222. /**
  223. * Obtains the class of the line that this Line.Info object describes.
  224. * @return the described line's class
  225. */
  226. public Class<?> getLineClass() {
  227. return lineClass;
  228. }
  229. /**
  230. * Indicates whether the specified info object matches this one.
  231. * To match, the specified object must be identical to or
  232. * a special case of this one. The specified info object
  233. * must be either an instance of the same class as this one,
  234. * or an instance of a sub-type of this one. In addition, the
  235. * attributes of the specified object must be compatible with the
  236. * capabilities of this one. Specifically, the routing configuration
  237. * for the specified info object must be compatible with that of this
  238. * one.
  239. * Subclasses may add other criteria to determine whether the two objects
  240. * match.
  241. *
  242. * @param info the info object which is being compared to this one
  243. * @return <code>true</code> if the specified object matches this one,
  244. * <code>false</code> otherwise
  245. */
  246. public boolean matches(Info info) {
  247. // $$kk: 08.30.99: is this backwards?
  248. // dataLine.matches(targetDataLine) == true: targetDataLine is always dataLine
  249. // targetDataLine.matches(dataLine) == false
  250. // so if i want to make sure i get a targetDataLine, i need:
  251. // targetDataLine.matches(prospective_match) == true
  252. // => prospective_match may be other things as well, but it is at least a targetDataLine
  253. // targetDataLine defines the requirements which prospective_match must meet.
  254. // "if this Class object represents a declared class, this method returns
  255. // true if the specified Object argument is an instance of the represented
  256. // class (or of any of its subclasses)"
  257. // GainControlClass.isInstance(MyGainObj) => true
  258. // GainControlClass.isInstance(MySpecialGainInterfaceObj) => true
  259. // this_class.isInstance(that_object) => that object can by cast to this class
  260. // => that_object's class may be a subtype of this_class
  261. // => that may be more specific (subtype) of this
  262. // "If this Class object represents an interface, this method returns true
  263. // if the class or any superclass of the specified Object argument implements
  264. // this interface"
  265. // GainControlClass.isInstance(MyGainObj) => true
  266. // GainControlClass.isInstance(GenericControlObj) => may be false
  267. // => that may be more specific
  268. if (! (this.getClass().isInstance(info)) ) {
  269. return false;
  270. }
  271. // this.isAssignableFrom(that) => this is same or super to that
  272. // => this is at least as general as that
  273. // => that may be subtype of this
  274. if (! (getLineClass().isAssignableFrom(info.getLineClass())) ) {
  275. return false;
  276. }
  277. return true;
  278. }
  279. /**
  280. * Obtains a textual description of the line info.
  281. * @return a string description
  282. */
  283. public String toString() {
  284. String fullPackagePath = "javax.sound.sampled.";
  285. String initialString = new String(getLineClass().toString());
  286. String finalString;
  287. int index = initialString.indexOf(fullPackagePath);
  288. if (index != -1) {
  289. finalString = initialString.substring(0, index) + initialString.substring( (index + fullPackagePath.length()), initialString.length() );
  290. } else {
  291. finalString = initialString;
  292. }
  293. return finalString;
  294. }
  295. } // class Info
  296. } // interface Line