Showing the changes to java/pkg/javax/sound/sampled/DataLine.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,496 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package javax.sound.sampled; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * <code>DataLine</code> adds media-related functionality to its | |
| 30 | + * superinterface, <code>{@link Line}</code>. This functionality includes | |
| 31 | + * transport-control methods that start, stop, drain, and flush | |
| 32 | + * the audio data that passes through the line. A data line can also | |
| 33 | + * report the current position, volume, and audio format of the media. | |
| 34 | + * Data lines are used for output of audio by means of the | |
| 35 | + * subinterfaces <code>{@link SourceDataLine}</code> or | |
| 36 | + * <code>{@link Clip}</code>, which allow an application program to write data. Similarly, | |
| 37 | + * audio input is handled by the subinterface <code>{@link TargetDataLine}</code>, | |
| 38 | + * which allows data to be read. | |
| 39 | + * <p> | |
| 40 | + * A data line has an internal buffer in which | |
| 41 | + * the incoming or outgoing audio data is queued. The | |
| 42 | + * <code>{@link #drain()}</code> method blocks until this internal buffer | |
| 43 | + * becomes empty, usually because all queued data has been processed. The | |
| 44 | + * <code>{@link #flush()}</code> method discards any available queued data | |
| 45 | + * from the internal buffer. | |
| 46 | + * <p> | |
| 47 | + * A data line produces <code>{@link LineEvent.Type#START START}</code> and | |
| 48 | + * <code>{@link LineEvent.Type#STOP STOP}</code> events whenever | |
| 49 | + * it begins or ceases active presentation or capture of data. These events | |
| 50 | + * can be generated in response to specific requests, or as a result of | |
| 51 | + * less direct state changes. For example, if <code>{@link #start()}</code> is called | |
| 52 | + * on an inactive data line, and data is available for capture or playback, a | |
| 53 | + * <code>START</code> event will be generated shortly, when data playback | |
| 54 | + * or capture actually begins. Or, if the flow of data to an active data | |
| 55 | + * line is constricted so that a gap occurs in the presentation of data, | |
| 56 | + * a <code>STOP</code> event is generated. | |
| 57 | + * <p> | |
| 58 | + * Mixers often support synchronized control of multiple data lines. | |
| 59 | + * Synchronization can be established through the Mixer interface's | |
| 60 | + * <code>{@link Mixer#synchronize synchronize}</code> method. | |
| 61 | + * See the description of the <code>{@link Mixer Mixer}</code> interface | |
| 62 | + * for a more complete description. | |
| 63 | + * | |
| 64 | + * @author Kara Kytle | |
| 65 | + * @see LineEvent | |
| 66 | + * @since 1.3 | |
| 67 | + */ | |
| 68 | +public interface DataLine extends Line { | |
| 69 | + | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Drains queued data from the line by continuing data I/O until the | |
| 73 | + * data line's internal buffer has been emptied. | |
| 74 | + * This method blocks until the draining is complete. Because this is a | |
| 75 | + * blocking method, it should be used with care. If <code>drain()</code> | |
| 76 | + * is invoked on a stopped line that has data in its queue, the method will | |
| 77 | + * block until the line is running and the data queue becomes empty. If | |
| 78 | + * <code>drain()</code> is invoked by one thread, and another continues to | |
| 79 | + * fill the data queue, the operation will not complete. | |
| 80 | + * This method always returns when the data line is closed. | |
| 81 | + * | |
| 82 | + * @see #flush() | |
| 83 | + */ | |
| 84 | + public void drain(); | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Flushes queued data from the line. The flushed data is discarded. | |
| 88 | + * In some cases, not all queued data can be discarded. For example, a | |
| 89 | + * mixer can flush data from the buffer for a specific input line, but any | |
| 90 | + * unplayed data already in the output buffer (the result of the mix) will | |
| 91 | + * still be played. You can invoke this method after pausing a line (the | |
| 92 | + * normal case) if you want to skip the "stale" data when you restart | |
| 93 | + * playback or capture. (It is legal to flush a line that is not stopped, | |
| 94 | + * but doing so on an active line is likely to cause a discontinuity in the | |
| 95 | + * data, resulting in a perceptible click.) | |
| 96 | + * | |
| 97 | + * @see #stop() | |
| 98 | + * @see #drain() | |
| 99 | + */ | |
| 100 | + public void flush(); | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Allows a line to engage in data I/O. If invoked on a line | |
| 104 | + * that is already running, this method does nothing. Unless the data in | |
| 105 | + * the buffer has been flushed, the line resumes I/O starting | |
| 106 | + * with the first frame that was unprocessed at the time the line was | |
| 107 | + * stopped. When audio capture or playback starts, a | |
| 108 | + * <code>{@link LineEvent.Type#START START}</code> event is generated. | |
| 109 | + * | |
| 110 | + * @see #stop() | |
| 111 | + * @see #isRunning() | |
| 112 | + * @see LineEvent | |
| 113 | + */ | |
| 114 | + public void start(); | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * Stops the line. A stopped line should cease I/O activity. | |
| 118 | + * If the line is open and running, however, it should retain the resources required | |
| 119 | + * to resume activity. A stopped line should retain any audio data in its buffer | |
| 120 | + * instead of discarding it, so that upon resumption the I/O can continue where it left off, | |
| 121 | + * if possible. (This doesn't guarantee that there will never be discontinuities beyond the | |
| 122 | + * current buffer, of course; if the stopped condition continues | |
| 123 | + * for too long, input or output samples might be dropped.) If desired, the retained data can be | |
| 124 | + * discarded by invoking the <code>flush</code> method. | |
| 125 | + * When audio capture or playback stops, a <code>{@link LineEvent.Type#STOP STOP}</code> event is generated. | |
| 126 | + * | |
| 127 | + * @see #start() | |
| 128 | + * @see #isRunning() | |
| 129 | + * @see #flush() | |
| 130 | + * @see LineEvent | |
| 131 | + */ | |
| 132 | + public void stop(); | |
| 133 | + | |
| 134 | + /** | |
| 135 | + * Indicates whether the line is running. The default is <code>false</code>. | |
| 136 | + * An open line begins running when the first data is presented in response to an | |
| 137 | + * invocation of the <code>start</code> method, and continues | |
| 138 | + * until presentation ceases in response to a call to <code>stop</code> or | |
| 139 | + * because playback completes. | |
| 140 | + * @return <code>true</code> if the line is running, otherwise <code>false</code> | |
| 141 | + * @see #start() | |
| 142 | + * @see #stop() | |
| 143 | + */ | |
| 144 | + public boolean isRunning(); | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Indicates whether the line is engaging in active I/O (such as playback | |
| 148 | + * or capture). When an inactive line becomes active, it sends a | |
| 149 | + * <code>{@link LineEvent.Type#START START}</code> event to its listeners. Similarly, when | |
| 150 | + * an active line becomes inactive, it sends a | |
| 151 | + * <code>{@link LineEvent.Type#STOP STOP}</code> event. | |
| 152 | + * @return <code>true</code> if the line is actively capturing or rendering | |
| 153 | + * sound, otherwise <code>false</code> | |
| 154 | + * @see #isOpen | |
| 155 | + * @see #addLineListener | |
| 156 | + * @see #removeLineListener | |
| 157 | + * @see LineEvent | |
| 158 | + * @see LineListener | |
| 159 | + */ | |
| 160 | + public boolean isActive(); | |
| 161 | + | |
| 162 | + /** | |
| 163 | + * Obtains the current format (encoding, sample rate, number of channels, | |
| 164 | + * etc.) of the data line's audio data. | |
| 165 | + * | |
| 166 | + * <p>If the line is not open and has never been opened, it returns | |
| 167 | + * the default format. The default format is an implementation | |
| 168 | + * specific audio format, or, if the <code>DataLine.Info</code> | |
| 169 | + * object, which was used to retrieve this <code>DataLine</code>, | |
| 170 | + * specifies at least one fully qualified audio format, the | |
| 171 | + * last one will be used as the default format. Opening the | |
| 172 | + * line with a specific audio format (e.g. | |
| 173 | + * {@link SourceDataLine#open(AudioFormat)}) will override the | |
| 174 | + * default format. | |
| 175 | + * | |
| 176 | + * @return current audio data format | |
| 177 | + * @see AudioFormat | |
| 178 | + */ | |
| 179 | + public AudioFormat getFormat(); | |
| 180 | + | |
| 181 | + /** | |
| 182 | + * Obtains the maximum number of bytes of data that will fit in the data line's | |
| 183 | + * internal buffer. For a source data line, this is the size of the buffer to | |
| 184 | + * which data can be written. For a target data line, it is the size of | |
| 185 | + * the buffer from which data can be read. Note that | |
| 186 | + * the units used are bytes, but will always correspond to an integral | |
| 187 | + * number of sample frames of audio data. | |
| 188 | + * | |
| 189 | + * @return the size of the buffer in bytes | |
| 190 | + */ | |
| 191 | + public int getBufferSize(); | |
| 192 | + | |
| 193 | + /** | |
| 194 | + * Obtains the number of bytes of data currently available to the | |
| 195 | + * application for processing in the data line's internal buffer. For a | |
| 196 | + * source data line, this is the amount of data that can be written to the | |
| 197 | + * buffer without blocking. For a target data line, this is the amount of data | |
| 198 | + * available to be read by the application. For a clip, this value is always | |
| 199 | + * 0 because the audio data is loaded into the buffer when the clip is opened, | |
| 200 | + * and persists without modification until the clip is closed. | |
| 201 | + * <p> | |
| 202 | + * Note that the units used are bytes, but will always | |
| 203 | + * correspond to an integral number of sample frames of audio data. | |
| 204 | + * <p> | |
| 205 | + * An application is guaranteed that a read or | |
| 206 | + * write operation of up to the number of bytes returned from | |
| 207 | + * <code>available()</code> will not block; however, there is no guarantee | |
| 208 | + * that attempts to read or write more data will block. | |
| 209 | + * | |
| 210 | + * @return the amount of data available, in bytes | |
| 211 | + */ | |
| 212 | + public int available(); | |
| 213 | + | |
| 214 | + /** | |
| 215 | + * Obtains the current position in the audio data, in sample frames. | |
| 216 | + * The frame position measures the number of sample | |
| 217 | + * frames captured by, or rendered from, the line since it was opened. | |
| 218 | + * This return value will wrap around after 2^31 frames. It is recommended | |
| 219 | + * to use <code>getLongFramePosition</code> instead. | |
| 220 | + * | |
| 221 | + * @return the number of frames already processed since the line was opened | |
| 222 | + * @see #getLongFramePosition() | |
| 223 | + */ | |
| 224 | + public int getFramePosition(); | |
| 225 | + | |
| 226 | + | |
| 227 | + /** | |
| 228 | + * Obtains the current position in the audio data, in sample frames. | |
| 229 | + * The frame position measures the number of sample | |
| 230 | + * frames captured by, or rendered from, the line since it was opened. | |
| 231 | + * | |
| 232 | + * @return the number of frames already processed since the line was opened | |
| 233 | + * @since 1.5 | |
| 234 | + */ | |
| 235 | + public long getLongFramePosition(); | |
| 236 | + | |
| 237 | + | |
| 238 | + /** | |
| 239 | + * Obtains the current position in the audio data, in microseconds. | |
| 240 | + * The microsecond position measures the time corresponding to the number | |
| 241 | + * of sample frames captured by, or rendered from, the line since it was opened. | |
| 242 | + * The level of precision is not guaranteed. For example, an implementation | |
| 243 | + * might calculate the microsecond position from the current frame position | |
| 244 | + * and the audio sample frame rate. The precision in microseconds would | |
| 245 | + * then be limited to the number of microseconds per sample frame. | |
| 246 | + * | |
| 247 | + * @return the number of microseconds of data processed since the line was opened | |
| 248 | + */ | |
| 249 | + public long getMicrosecondPosition(); | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * Obtains the current volume level for the line. This level is a measure | |
| 253 | + * of the signal's current amplitude, and should not be confused with the | |
| 254 | + * current setting of a gain control. The range is from 0.0 (silence) to | |
| 255 | + * 1.0 (maximum possible amplitude for the sound waveform). The units | |
| 256 | + * measure linear amplitude, not decibels. | |
| 257 | + * | |
| 258 | + * @return the current amplitude of the signal in this line, or | |
| 259 | + * <code>{@link AudioSystem#NOT_SPECIFIED}</code> | |
| 260 | + */ | |
| 261 | + public float getLevel(); | |
| 262 | + | |
| 263 | + /** | |
| 264 | + * Besides the class information inherited from its superclass, | |
| 265 | + * <code>DataLine.Info</code> provides additional information specific to data lines. | |
| 266 | + * This information includes: | |
| 267 | + * <ul> | |
| 268 | + * <li> the audio formats supported by the data line | |
| 269 | + * <li> the minimum and maximum sizes of its internal buffer | |
| 270 | + * </ul> | |
| 271 | + * Because a <code>Line.Info</code> knows the class of the line its describes, a | |
| 272 | + * <code>DataLine.Info</code> object can describe <code>DataLine</code> | |
| 273 | + * subinterfaces such as <code>{@link SourceDataLine}</code>, | |
| 274 | + * <code>{@link TargetDataLine}</code>, and <code>{@link Clip}</code>. | |
| 275 | + * You can query a mixer for lines of any of these types, passing an appropriate | |
| 276 | + * instance of <code>DataLine.Info</code> as the argument to a method such as | |
| 277 | + * <code>{@link Mixer#getLine Mixer.getLine(Line.Info)}</code>. | |
| 278 | + * | |
| 279 | + * @see Line.Info | |
| 280 | + * @author Kara Kytle | |
| 281 | + * @since 1.3 | |
| 282 | + */ | |
| 283 | + public static class Info extends Line.Info { | |
| 284 | + | |
| 285 | + private AudioFormat[] formats; | |
| 286 | + private int minBufferSize; | |
| 287 | + private int maxBufferSize; | |
| 288 | + | |
| 289 | + /** | |
| 290 | + * Constructs a data line's info object from the specified information, | |
| 291 | + * which includes a set of supported audio formats and a range for the buffer size. | |
| 292 | + * This constructor is typically used by mixer implementations | |
| 293 | + * when returning information about a supported line. | |
| 294 | + * | |
| 295 | + * @param lineClass the class of the data line described by the info object | |
| 296 | + * @param formats set of formats supported | |
| 297 | + * @param minBufferSize minimum buffer size supported by the data line, in bytes | |
| 298 | + * @param maxBufferSize maximum buffer size supported by the data line, in bytes | |
| 299 | + */ | |
| 300 | + public Info(Class<?> lineClass, AudioFormat[] formats, int minBufferSize, int maxBufferSize) { | |
| 301 | + | |
| 302 | + super(lineClass); | |
| 303 | + | |
| 304 | + if (formats == null) { | |
| 305 | + this.formats = new AudioFormat[0]; | |
| 306 | + } else { | |
| 307 | + this.formats = formats; | |
| 308 | + } | |
| 309 | + | |
| 310 | + this.minBufferSize = minBufferSize; | |
| 311 | + this.maxBufferSize = maxBufferSize; | |
| 312 | + } | |
| 313 | + | |
| 314 | + | |
| 315 | + /** | |
| 316 | + * Constructs a data line's info object from the specified information, | |
| 317 | + * which includes a single audio format and a desired buffer size. | |
| 318 | + * This constructor is typically used by an application to | |
| 319 | + * describe a desired line. | |
| 320 | + * | |
| 321 | + * @param lineClass the class of the data line described by the info object | |
| 322 | + * @param format desired format | |
| 323 | + * @param bufferSize desired buffer size in bytes | |
| 324 | + */ | |
| 325 | + public Info(Class<?> lineClass, AudioFormat format, int bufferSize) { | |
| 326 | + | |
| 327 | + super(lineClass); | |
| 328 | + | |
| 329 | + if (format == null) { | |
| 330 | + this.formats = new AudioFormat[0]; | |
| 331 | + } else { | |
| 332 | + AudioFormat[] formats = { format }; | |
| 333 | + this.formats = formats; | |
| 334 | + } | |
| 335 | + | |
| 336 | + this.minBufferSize = bufferSize; | |
| 337 | + this.maxBufferSize = bufferSize; | |
| 338 | + } | |
| 339 | + | |
| 340 | + | |
| 341 | + /** | |
| 342 | + * Constructs a data line's info object from the specified information, | |
| 343 | + * which includes a single audio format. | |
| 344 | + * This constructor is typically used by an application to | |
| 345 | + * describe a desired line. | |
| 346 | + * | |
| 347 | + * @param lineClass the class of the data line described by the info object | |
| 348 | + * @param format desired format | |
| 349 | + */ | |
| 350 | + public Info(Class<?> lineClass, AudioFormat format) { | |
| 351 | + this(lineClass, format, AudioSystem.NOT_SPECIFIED); | |
| 352 | + } | |
| 353 | + | |
| 354 | + | |
| 355 | + /** | |
| 356 | + * Obtains a set of audio formats supported by the data line. | |
| 357 | + * Note that <code>isFormatSupported(AudioFormat)</code> might return | |
| 358 | + * <code>true</code> for certain additional formats that are missing from | |
| 359 | + * the set returned by <code>getFormats()</code>. The reverse is not | |
| 360 | + * the case: <code>isFormatSupported(AudioFormat)</code> is guaranteed to return | |
| 361 | + * <code>true</code> for all formats returned by <code>getFormats()</code>. | |
| 362 | + * | |
| 363 | + * Some fields in the AudioFormat instances can be set to | |
| 364 | + * {@link javax.sound.sampled.AudioSystem#NOT_SPECIFIED NOT_SPECIFIED} | |
| 365 | + * if that field does not apply to the format, | |
| 366 | + * or if the format supports a wide range of values for that field. | |
| 367 | + * For example, a multi-channel device supporting up to | |
| 368 | + * 64 channels, could set the channel field in the | |
| 369 | + * <code>AudioFormat</code> instances returned by this | |
| 370 | + * method to <code>NOT_SPECIFIED</code>. | |
| 371 | + * | |
| 372 | + * @return a set of supported audio formats. | |
| 373 | + * @see #isFormatSupported(AudioFormat) | |
| 374 | + */ | |
| 375 | + public AudioFormat[] getFormats() { | |
| 376 | + | |
| 377 | + AudioFormat[] returnedArray = new AudioFormat[formats.length]; | |
| 378 | + System.arraycopy(formats, 0, returnedArray, 0, formats.length); | |
| 379 | + return returnedArray; | |
| 380 | + } | |
| 381 | + | |
| 382 | + /** | |
| 383 | + * Indicates whether this data line supports a particular audio format. | |
| 384 | + * The default implementation of this method simply returns <code>true</code> if | |
| 385 | + * the specified format matches any of the supported formats. | |
| 386 | + * | |
| 387 | + * @param format the audio format for which support is queried. | |
| 388 | + * @return <code>true</code> if the format is supported, otherwise <code>false</code> | |
| 389 | + * @see #getFormats | |
| 390 | + * @see AudioFormat#matches | |
| 391 | + */ | |
| 392 | + public boolean isFormatSupported(AudioFormat format) { | |
| 393 | + | |
| 394 | + for (int i = 0; i < formats.length; i++) { | |
| 395 | + if (format.matches(formats[i])) { | |
| 396 | + return true; | |
| 397 | + } | |
| 398 | + } | |
| 399 | + | |
| 400 | + return false; | |
| 401 | + } | |
| 402 | + | |
| 403 | + /** | |
| 404 | + * Obtains the minimum buffer size supported by the data line. | |
| 405 | + * @return minimum buffer size in bytes, or <code>AudioSystem.NOT_SPECIFIED</code> | |
| 406 | + */ | |
| 407 | + public int getMinBufferSize() { | |
| 408 | + return minBufferSize; | |
| 409 | + } | |
| 410 | + | |
| 411 | + | |
| 412 | + /** | |
| 413 | + * Obtains the maximum buffer size supported by the data line. | |
| 414 | + * @return maximum buffer size in bytes, or <code>AudioSystem.NOT_SPECIFIED</code> | |
| 415 | + */ | |
| 416 | + public int getMaxBufferSize() { | |
| 417 | + return maxBufferSize; | |
| 418 | + } | |
| 419 | + | |
| 420 | + | |
| 421 | + /** | |
| 422 | + * Determines whether the specified info object matches this one. | |
| 423 | + * To match, the superclass match requirements must be met. In | |
| 424 | + * addition, this object's minimum buffer size must be at least as | |
| 425 | + * large as that of the object specified, its maximum buffer size must | |
| 426 | + * be at most as large as that of the object specified, and all of its | |
| 427 | + * formats must match formats supported by the object specified. | |
| 428 | + * @return <code>true</code> if this object matches the one specified, | |
| 429 | + * otherwise <code>false</code>. | |
| 430 | + */ | |
| 431 | + public boolean matches(Line.Info info) { | |
| 432 | + | |
| 433 | + if (! (super.matches(info)) ) { | |
| 434 | + return false; | |
| 435 | + } | |
| 436 | + | |
| 437 | + Info dataLineInfo = (Info)info; | |
| 438 | + | |
| 439 | + // treat anything < 0 as NOT_SPECIFIED | |
| 440 | + // demo code in old Java Sound Demo used a wrong buffer calculation | |
| 441 | + // that would lead to arbitrary negative values | |
| 442 | + if ((getMaxBufferSize() >= 0) && (dataLineInfo.getMaxBufferSize() >= 0)) { | |
| 443 | + if (getMaxBufferSize() > dataLineInfo.getMaxBufferSize()) { | |
| 444 | + return false; | |
| 445 | + } | |
| 446 | + } | |
| 447 | + | |
| 448 | + if ((getMinBufferSize() >= 0) && (dataLineInfo.getMinBufferSize() >= 0)) { | |
| 449 | + if (getMinBufferSize() < dataLineInfo.getMinBufferSize()) { | |
| 450 | + return false; | |
| 451 | + } | |
| 452 | + } | |
| 453 | + | |
| 454 | + AudioFormat[] localFormats = getFormats(); | |
| 455 | + | |
| 456 | + if (localFormats != null) { | |
| 457 | + | |
| 458 | + for (int i = 0; i < localFormats.length; i++) { | |
| 459 | + if (! (localFormats[i] == null) ) { | |
| 460 | + if (! (dataLineInfo.isFormatSupported(localFormats[i])) ) { | |
| 461 | + return false; | |
| 462 | + } | |
| 463 | + } | |
| 464 | + } | |
| 465 | + } | |
| 466 | + | |
| 467 | + return true; | |
| 468 | + } | |
| 469 | + | |
| 470 | + /** | |
| 471 | + * Obtains a textual description of the data line info. | |
| 472 | + * @return a string description | |
| 473 | + */ | |
| 474 | + public String toString() { | |
| 475 | + | |
| 476 | + StringBuffer buf = new StringBuffer(); | |
| 477 | + | |
| 478 | + if ( (formats.length == 1) && (formats[0] != null) ) { | |
| 479 | + buf.append(" supporting format " + formats[0]); | |
| 480 | + } else if (getFormats().length > 1) { | |
| 481 | + buf.append(" supporting " + getFormats().length + " audio formats"); | |
| 482 | + } | |
| 483 | + | |
| 484 | + if ( (minBufferSize != AudioSystem.NOT_SPECIFIED) && (maxBufferSize != AudioSystem.NOT_SPECIFIED) ) { | |
| 485 | + buf.append(", and buffers of " + minBufferSize + " to " + maxBufferSize + " bytes"); | |
| 486 | + } else if ( (minBufferSize != AudioSystem.NOT_SPECIFIED) && (minBufferSize > 0) ) { | |
| 487 | + buf.append(", and buffers of at least " + minBufferSize + " bytes"); | |
| 488 | + } else if (maxBufferSize != AudioSystem.NOT_SPECIFIED) { | |
| 489 | + buf.append(", and buffers of up to " + minBufferSize + " bytes"); | |
| 490 | + } | |
| 491 | + | |
| 492 | + return new String(super.toString() + buf); | |
| 493 | + } | |
| 494 | + } // class Info | |
| 495 | + | |
| 496 | +} // interface DataLine | |