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 | ||