< prev index next >

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

Print this page




   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 package com.sun.media.sound;
  26 
  27 import java.io.ByteArrayOutputStream;
  28 import java.io.IOException;
  29 import java.io.InputStream;
  30 import java.util.Arrays;
  31 
  32 import javax.sound.sampled.AudioFormat;
  33 import javax.sound.sampled.AudioInputStream;
  34 import javax.sound.sampled.AudioSystem;
  35 import javax.sound.sampled.Clip;
  36 import javax.sound.sampled.DataLine;
  37 import javax.sound.sampled.LineEvent;
  38 import javax.sound.sampled.LineUnavailableException;
  39 
  40 /**
  41  * Clip implementation for the SoftMixingMixer.
  42  *
  43  * @author Karl Helgason
  44  */
  45 public final class SoftMixingClip extends SoftMixingDataLine implements Clip {
  46 
  47     private AudioFormat format;
  48 
  49     private int framesize;
  50 
  51     private byte[] data;
  52 
  53     private final InputStream datastream = new InputStream() {
  54 

  55         public int read() throws IOException {
  56             byte[] b = new byte[1];
  57             int ret = read(b);
  58             if (ret < 0)
  59                 return ret;
  60             return b[0] & 0xFF;
  61         }
  62 

  63         public int read(byte[] b, int off, int len) throws IOException {
  64 
  65             if (_loopcount != 0) {
  66                 int bloopend = _loopend * framesize;
  67                 int bloopstart = _loopstart * framesize;
  68                 int pos = _frameposition * framesize;
  69 
  70                 if (pos + len >= bloopend)
  71                     if (pos < bloopend) {
  72                         int offend = off + len;
  73                         int o = off;
  74                         while (off != offend) {
  75                             if (pos == bloopend) {
  76                                 if (_loopcount == 0)
  77                                     break;
  78                                 pos = bloopstart;
  79                                 if (_loopcount != LOOP_CONTINUOUSLY)
  80                                     _loopcount--;
  81                             }
  82                             len = offend - off;


 149     private int _loopcount = 0;
 150 
 151     private int _loopstart = 0;
 152 
 153     private int _loopend = -1;
 154 
 155     private float _rightgain;
 156 
 157     private float _leftgain;
 158 
 159     private float _eff1gain;
 160 
 161     private float _eff2gain;
 162 
 163     private AudioFloatInputStream afis;
 164 
 165     SoftMixingClip(SoftMixingMixer mixer, DataLine.Info info) {
 166         super(mixer, info);
 167     }
 168 

 169     protected void processControlLogic() {
 170 
 171         _rightgain = rightgain;
 172         _leftgain = leftgain;
 173         _eff1gain = eff1gain;
 174         _eff2gain = eff2gain;
 175 
 176         if (active_sg) {
 177             _active = active;
 178             active_sg = false;
 179         } else {
 180             active = _active;
 181         }
 182 
 183         if (frameposition_sg) {
 184             _frameposition = frameposition;
 185             frameposition_sg = false;
 186             afis = null;
 187         } else {
 188             frameposition = _frameposition;
 189         }
 190         if (loop_sg) {
 191             _loopcount = loopcount;
 192             _loopstart = loopstart;
 193             _loopend = loopend;
 194         }
 195 
 196         if (afis == null) {
 197             afis = AudioFloatInputStream.getInputStream(new AudioInputStream(
 198                     datastream, format, AudioSystem.NOT_SPECIFIED));
 199 
 200             if (Math.abs(format.getSampleRate() - outputformat.getSampleRate()) > 0.000001)
 201                 afis = new AudioFloatInputStreamResampler(afis, outputformat);
 202         }
 203 
 204     }
 205 

 206     protected void processAudioLogic(SoftAudioBuffer[] buffers) {
 207         if (_active) {
 208             float[] left = buffers[SoftMixingMainMixer.CHANNEL_LEFT].array();
 209             float[] right = buffers[SoftMixingMainMixer.CHANNEL_RIGHT].array();
 210             int bufferlen = buffers[SoftMixingMainMixer.CHANNEL_LEFT].getSize();
 211 
 212             int readlen = bufferlen * in_nrofchannels;
 213             if (readbuffer == null || readbuffer.length < readlen) {
 214                 readbuffer = new float[readlen];
 215             }
 216             int ret = 0;
 217             try {
 218                 ret = afis.read(readbuffer);
 219                 if (ret == -1) {
 220                     _active = false;
 221                     return;
 222                 }
 223                 if (ret != in_nrofchannels)
 224                     Arrays.fill(readbuffer, ret, readlen, 0);
 225             } catch (IOException e) {


 256                     }
 257                 }
 258             }
 259 
 260             if (_eff2gain > 0.0002) {
 261                 float[] eff2 = buffers[SoftMixingMainMixer.CHANNEL_EFFECT2]
 262                         .array();
 263                 for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
 264                     eff2[i] += readbuffer[ix] * _eff2gain;
 265                 }
 266                 if (in_nrofchannels == 2) {
 267                     for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
 268                         eff2[i] += readbuffer[ix] * _eff2gain;
 269                     }
 270                 }
 271             }
 272 
 273         }
 274     }
 275 

 276     public int getFrameLength() {
 277         return bufferSize / format.getFrameSize();
 278     }
 279 

 280     public long getMicrosecondLength() {
 281         return (long) (getFrameLength() * (1000000.0 / (double) getFormat()
 282                 .getSampleRate()));
 283     }
 284 

 285     public void loop(int count) {
 286         LineEvent event = null;
 287 
 288         synchronized (control_mutex) {
 289             if (isOpen()) {
 290                 if (active)
 291                     return;
 292                 active = true;
 293                 active_sg = true;
 294                 loopcount = count;
 295                 event = new LineEvent(this, LineEvent.Type.START,
 296                         getLongFramePosition());
 297             }
 298         }
 299 
 300         if (event != null)
 301             sendEvent(event);
 302 
 303     }
 304 

 305     public void open(AudioInputStream stream) throws LineUnavailableException,
 306             IOException {
 307         if (isOpen()) {
 308             throw new IllegalStateException("Clip is already open with format "
 309                     + getFormat() + " and frame lengh of " + getFrameLength());
 310         }
 311         if (AudioFloatConverter.getConverter(stream.getFormat()) == null)
 312             throw new IllegalArgumentException("Invalid format : "
 313                     + stream.getFormat().toString());
 314 
 315         if (stream.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
 316             byte[] data = new byte[(int) stream.getFrameLength()
 317                     * stream.getFormat().getFrameSize()];
 318             int readsize = 512 * stream.getFormat().getFrameSize();
 319             int len = 0;
 320             while (len != data.length) {
 321                 if (readsize > data.length - len)
 322                     readsize = data.length - len;
 323                 int ret = stream.read(data, len, readsize);
 324                 if (ret == -1)
 325                     break;
 326                 if (ret == 0)
 327                     Thread.yield();
 328                 len += ret;
 329             }
 330             open(stream.getFormat(), data, 0, len);
 331         } else {
 332             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 333             byte[] b = new byte[512 * stream.getFormat().getFrameSize()];
 334             int r = 0;
 335             while ((r = stream.read(b)) != -1) {
 336                 if (r == 0)
 337                     Thread.yield();
 338                 baos.write(b, 0, r);
 339             }
 340             open(stream.getFormat(), baos.toByteArray(), 0, baos.size());
 341         }
 342 
 343     }
 344 

 345     public void open(AudioFormat format, byte[] data, int offset, int bufferSize)
 346             throws LineUnavailableException {
 347         synchronized (control_mutex) {
 348             if (isOpen()) {
 349                 throw new IllegalStateException(
 350                         "Clip is already open with format " + getFormat()
 351                                 + " and frame lengh of " + getFrameLength());
 352             }
 353             if (AudioFloatConverter.getConverter(format) == null)
 354                 throw new IllegalArgumentException("Invalid format : "
 355                         + format.toString());
 356             if (bufferSize % format.getFrameSize() != 0)
 357                 throw new IllegalArgumentException(
 358                         "Buffer size does not represent an integral number of sample frames!");
 359 
 360             if (data != null) {
 361                 this.data = Arrays.copyOf(data, data.length);
 362             }
 363             this.offset = offset;
 364             this.bufferSize = bufferSize;


 368             loopstart = 0;
 369             loopend = -1;
 370             loop_sg = true;
 371 
 372             if (!mixer.isOpen()) {
 373                 mixer.open();
 374                 mixer.implicitOpen = true;
 375             }
 376 
 377             outputformat = mixer.getFormat();
 378             out_nrofchannels = outputformat.getChannels();
 379             in_nrofchannels = format.getChannels();
 380 
 381             open = true;
 382 
 383             mixer.getMainMixer().openLine(this);
 384         }
 385 
 386     }
 387 

 388     public void setFramePosition(int frames) {
 389         synchronized (control_mutex) {
 390             frameposition_sg = true;
 391             frameposition = frames;
 392         }
 393     }
 394 

 395     public void setLoopPoints(int start, int end) {
 396         synchronized (control_mutex) {
 397             if (end != -1) {
 398                 if (end < start)
 399                     throw new IllegalArgumentException("Invalid loop points : "
 400                             + start + " - " + end);
 401                 if (end * framesize > bufferSize)
 402                     throw new IllegalArgumentException("Invalid loop points : "
 403                             + start + " - " + end);
 404             }
 405             if (start * framesize > bufferSize)
 406                 throw new IllegalArgumentException("Invalid loop points : "
 407                         + start + " - " + end);
 408             if (0 < start)
 409                 throw new IllegalArgumentException("Invalid loop points : "
 410                         + start + " - " + end);
 411             loopstart = start;
 412             loopend = end;
 413             loop_sg = true;
 414         }
 415     }
 416 

 417     public void setMicrosecondPosition(long microseconds) {
 418         setFramePosition((int) (microseconds * (((double) getFormat()
 419                 .getSampleRate()) / 1000000.0)));
 420     }
 421 

 422     public int available() {
 423         return 0;
 424     }
 425 

 426     public void drain() {
 427     }
 428 

 429     public void flush() {
 430     }
 431 

 432     public int getBufferSize() {
 433         return bufferSize;
 434     }
 435 

 436     public AudioFormat getFormat() {
 437         return format;
 438     }
 439 

 440     public int getFramePosition() {
 441         synchronized (control_mutex) {
 442             return frameposition;
 443         }
 444     }
 445 

 446     public float getLevel() {
 447         return AudioSystem.NOT_SPECIFIED;
 448     }
 449 

 450     public long getLongFramePosition() {
 451         return getFramePosition();
 452     }
 453 

 454     public long getMicrosecondPosition() {
 455         return (long) (getFramePosition() * (1000000.0 / (double) getFormat()
 456                 .getSampleRate()));
 457     }
 458 

 459     public boolean isActive() {
 460         synchronized (control_mutex) {
 461             return active;
 462         }
 463     }
 464 

 465     public boolean isRunning() {
 466         synchronized (control_mutex) {
 467             return active;
 468         }
 469     }
 470 

 471     public void start() {
 472 
 473         LineEvent event = null;
 474 
 475         synchronized (control_mutex) {
 476             if (isOpen()) {
 477                 if (active)
 478                     return;
 479                 active = true;
 480                 active_sg = true;
 481                 loopcount = 0;
 482                 event = new LineEvent(this, LineEvent.Type.START,
 483                         getLongFramePosition());
 484             }
 485         }
 486 
 487         if (event != null)
 488             sendEvent(event);
 489     }
 490 

 491     public void stop() {
 492         LineEvent event = null;
 493 
 494         synchronized (control_mutex) {
 495             if (isOpen()) {
 496                 if (!active)
 497                     return;
 498                 active = false;
 499                 active_sg = true;
 500                 event = new LineEvent(this, LineEvent.Type.STOP,
 501                         getLongFramePosition());
 502             }
 503         }
 504 
 505         if (event != null)
 506             sendEvent(event);
 507     }
 508 

 509     public void close() {
 510         LineEvent event = null;
 511 
 512         synchronized (control_mutex) {
 513             if (!isOpen())
 514                 return;
 515             stop();
 516 
 517             event = new LineEvent(this, LineEvent.Type.CLOSE,
 518                     getLongFramePosition());
 519 
 520             open = false;
 521             mixer.getMainMixer().closeLine(this);
 522         }
 523 
 524         if (event != null)
 525             sendEvent(event);
 526 
 527     }
 528 

 529     public boolean isOpen() {
 530         return open;
 531     }
 532 

 533     public void open() throws LineUnavailableException {
 534         if (data == null) {
 535             throw new IllegalArgumentException(
 536                     "Illegal call to open() in interface Clip");
 537         }
 538         open(format, data, offset, bufferSize);
 539     }
 540 
 541 }


   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 com.sun.media.sound;
  27 
  28 import java.io.ByteArrayOutputStream;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.util.Arrays;
  32 
  33 import javax.sound.sampled.AudioFormat;
  34 import javax.sound.sampled.AudioInputStream;
  35 import javax.sound.sampled.AudioSystem;
  36 import javax.sound.sampled.Clip;
  37 import javax.sound.sampled.DataLine;
  38 import javax.sound.sampled.LineEvent;
  39 import javax.sound.sampled.LineUnavailableException;
  40 
  41 /**
  42  * Clip implementation for the SoftMixingMixer.
  43  *
  44  * @author Karl Helgason
  45  */
  46 public final class SoftMixingClip extends SoftMixingDataLine implements Clip {
  47 
  48     private AudioFormat format;
  49 
  50     private int framesize;
  51 
  52     private byte[] data;
  53 
  54     private final InputStream datastream = new InputStream() {
  55 
  56         @Override
  57         public int read() throws IOException {
  58             byte[] b = new byte[1];
  59             int ret = read(b);
  60             if (ret < 0)
  61                 return ret;
  62             return b[0] & 0xFF;
  63         }
  64 
  65         @Override
  66         public int read(byte[] b, int off, int len) throws IOException {
  67 
  68             if (_loopcount != 0) {
  69                 int bloopend = _loopend * framesize;
  70                 int bloopstart = _loopstart * framesize;
  71                 int pos = _frameposition * framesize;
  72 
  73                 if (pos + len >= bloopend)
  74                     if (pos < bloopend) {
  75                         int offend = off + len;
  76                         int o = off;
  77                         while (off != offend) {
  78                             if (pos == bloopend) {
  79                                 if (_loopcount == 0)
  80                                     break;
  81                                 pos = bloopstart;
  82                                 if (_loopcount != LOOP_CONTINUOUSLY)
  83                                     _loopcount--;
  84                             }
  85                             len = offend - off;


 152     private int _loopcount = 0;
 153 
 154     private int _loopstart = 0;
 155 
 156     private int _loopend = -1;
 157 
 158     private float _rightgain;
 159 
 160     private float _leftgain;
 161 
 162     private float _eff1gain;
 163 
 164     private float _eff2gain;
 165 
 166     private AudioFloatInputStream afis;
 167 
 168     SoftMixingClip(SoftMixingMixer mixer, DataLine.Info info) {
 169         super(mixer, info);
 170     }
 171 
 172     @Override
 173     protected void processControlLogic() {
 174 
 175         _rightgain = rightgain;
 176         _leftgain = leftgain;
 177         _eff1gain = eff1gain;
 178         _eff2gain = eff2gain;
 179 
 180         if (active_sg) {
 181             _active = active;
 182             active_sg = false;
 183         } else {
 184             active = _active;
 185         }
 186 
 187         if (frameposition_sg) {
 188             _frameposition = frameposition;
 189             frameposition_sg = false;
 190             afis = null;
 191         } else {
 192             frameposition = _frameposition;
 193         }
 194         if (loop_sg) {
 195             _loopcount = loopcount;
 196             _loopstart = loopstart;
 197             _loopend = loopend;
 198         }
 199 
 200         if (afis == null) {
 201             afis = AudioFloatInputStream.getInputStream(new AudioInputStream(
 202                     datastream, format, AudioSystem.NOT_SPECIFIED));
 203 
 204             if (Math.abs(format.getSampleRate() - outputformat.getSampleRate()) > 0.000001)
 205                 afis = new AudioFloatInputStreamResampler(afis, outputformat);
 206         }
 207 
 208     }
 209 
 210     @Override
 211     protected void processAudioLogic(SoftAudioBuffer[] buffers) {
 212         if (_active) {
 213             float[] left = buffers[SoftMixingMainMixer.CHANNEL_LEFT].array();
 214             float[] right = buffers[SoftMixingMainMixer.CHANNEL_RIGHT].array();
 215             int bufferlen = buffers[SoftMixingMainMixer.CHANNEL_LEFT].getSize();
 216 
 217             int readlen = bufferlen * in_nrofchannels;
 218             if (readbuffer == null || readbuffer.length < readlen) {
 219                 readbuffer = new float[readlen];
 220             }
 221             int ret = 0;
 222             try {
 223                 ret = afis.read(readbuffer);
 224                 if (ret == -1) {
 225                     _active = false;
 226                     return;
 227                 }
 228                 if (ret != in_nrofchannels)
 229                     Arrays.fill(readbuffer, ret, readlen, 0);
 230             } catch (IOException e) {


 261                     }
 262                 }
 263             }
 264 
 265             if (_eff2gain > 0.0002) {
 266                 float[] eff2 = buffers[SoftMixingMainMixer.CHANNEL_EFFECT2]
 267                         .array();
 268                 for (int i = 0, ix = 0; i < bufferlen; i++, ix += in_c) {
 269                     eff2[i] += readbuffer[ix] * _eff2gain;
 270                 }
 271                 if (in_nrofchannels == 2) {
 272                     for (int i = 0, ix = 1; i < bufferlen; i++, ix += in_c) {
 273                         eff2[i] += readbuffer[ix] * _eff2gain;
 274                     }
 275                 }
 276             }
 277 
 278         }
 279     }
 280 
 281     @Override
 282     public int getFrameLength() {
 283         return bufferSize / format.getFrameSize();
 284     }
 285 
 286     @Override
 287     public long getMicrosecondLength() {
 288         return (long) (getFrameLength() * (1000000.0 / (double) getFormat()
 289                 .getSampleRate()));
 290     }
 291 
 292     @Override
 293     public void loop(int count) {
 294         LineEvent event = null;
 295 
 296         synchronized (control_mutex) {
 297             if (isOpen()) {
 298                 if (active)
 299                     return;
 300                 active = true;
 301                 active_sg = true;
 302                 loopcount = count;
 303                 event = new LineEvent(this, LineEvent.Type.START,
 304                         getLongFramePosition());
 305             }
 306         }
 307 
 308         if (event != null)
 309             sendEvent(event);
 310 
 311     }
 312 
 313     @Override
 314     public void open(AudioInputStream stream) throws LineUnavailableException,
 315                                                      IOException {
 316         if (isOpen()) {
 317             throw new IllegalStateException("Clip is already open with format "
 318                     + getFormat() + " and frame lengh of " + getFrameLength());
 319         }
 320         if (AudioFloatConverter.getConverter(stream.getFormat()) == null)
 321             throw new IllegalArgumentException("Invalid format : "
 322                     + stream.getFormat().toString());
 323 
 324         if (stream.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
 325             byte[] data = new byte[(int) stream.getFrameLength()
 326                     * stream.getFormat().getFrameSize()];
 327             int readsize = 512 * stream.getFormat().getFrameSize();
 328             int len = 0;
 329             while (len != data.length) {
 330                 if (readsize > data.length - len)
 331                     readsize = data.length - len;
 332                 int ret = stream.read(data, len, readsize);
 333                 if (ret == -1)
 334                     break;
 335                 if (ret == 0)
 336                     Thread.yield();
 337                 len += ret;
 338             }
 339             open(stream.getFormat(), data, 0, len);
 340         } else {
 341             ByteArrayOutputStream baos = new ByteArrayOutputStream();
 342             byte[] b = new byte[512 * stream.getFormat().getFrameSize()];
 343             int r = 0;
 344             while ((r = stream.read(b)) != -1) {
 345                 if (r == 0)
 346                     Thread.yield();
 347                 baos.write(b, 0, r);
 348             }
 349             open(stream.getFormat(), baos.toByteArray(), 0, baos.size());
 350         }
 351 
 352     }
 353 
 354     @Override
 355     public void open(AudioFormat format, byte[] data, int offset, int bufferSize)
 356             throws LineUnavailableException {
 357         synchronized (control_mutex) {
 358             if (isOpen()) {
 359                 throw new IllegalStateException(
 360                         "Clip is already open with format " + getFormat()
 361                                 + " and frame lengh of " + getFrameLength());
 362             }
 363             if (AudioFloatConverter.getConverter(format) == null)
 364                 throw new IllegalArgumentException("Invalid format : "
 365                         + format.toString());
 366             if (bufferSize % format.getFrameSize() != 0)
 367                 throw new IllegalArgumentException(
 368                         "Buffer size does not represent an integral number of sample frames!");
 369 
 370             if (data != null) {
 371                 this.data = Arrays.copyOf(data, data.length);
 372             }
 373             this.offset = offset;
 374             this.bufferSize = bufferSize;


 378             loopstart = 0;
 379             loopend = -1;
 380             loop_sg = true;
 381 
 382             if (!mixer.isOpen()) {
 383                 mixer.open();
 384                 mixer.implicitOpen = true;
 385             }
 386 
 387             outputformat = mixer.getFormat();
 388             out_nrofchannels = outputformat.getChannels();
 389             in_nrofchannels = format.getChannels();
 390 
 391             open = true;
 392 
 393             mixer.getMainMixer().openLine(this);
 394         }
 395 
 396     }
 397 
 398     @Override
 399     public void setFramePosition(int frames) {
 400         synchronized (control_mutex) {
 401             frameposition_sg = true;
 402             frameposition = frames;
 403         }
 404     }
 405 
 406     @Override
 407     public void setLoopPoints(int start, int end) {
 408         synchronized (control_mutex) {
 409             if (end != -1) {
 410                 if (end < start)
 411                     throw new IllegalArgumentException("Invalid loop points : "
 412                             + start + " - " + end);
 413                 if (end * framesize > bufferSize)
 414                     throw new IllegalArgumentException("Invalid loop points : "
 415                             + start + " - " + end);
 416             }
 417             if (start * framesize > bufferSize)
 418                 throw new IllegalArgumentException("Invalid loop points : "
 419                         + start + " - " + end);
 420             if (0 < start)
 421                 throw new IllegalArgumentException("Invalid loop points : "
 422                         + start + " - " + end);
 423             loopstart = start;
 424             loopend = end;
 425             loop_sg = true;
 426         }
 427     }
 428 
 429     @Override
 430     public void setMicrosecondPosition(long microseconds) {
 431         setFramePosition((int) (microseconds * (((double) getFormat()
 432                 .getSampleRate()) / 1000000.0)));
 433     }
 434 
 435     @Override
 436     public int available() {
 437         return 0;
 438     }
 439 
 440     @Override
 441     public void drain() {
 442     }
 443 
 444     @Override
 445     public void flush() {
 446     }
 447 
 448     @Override
 449     public int getBufferSize() {
 450         return bufferSize;
 451     }
 452 
 453     @Override
 454     public AudioFormat getFormat() {
 455         return format;
 456     }
 457 
 458     @Override
 459     public int getFramePosition() {
 460         synchronized (control_mutex) {
 461             return frameposition;
 462         }
 463     }
 464 
 465     @Override
 466     public float getLevel() {
 467         return AudioSystem.NOT_SPECIFIED;
 468     }
 469 
 470     @Override
 471     public long getLongFramePosition() {
 472         return getFramePosition();
 473     }
 474 
 475     @Override
 476     public long getMicrosecondPosition() {
 477         return (long) (getFramePosition() * (1000000.0 / (double) getFormat()
 478                 .getSampleRate()));
 479     }
 480 
 481     @Override
 482     public boolean isActive() {
 483         synchronized (control_mutex) {
 484             return active;
 485         }
 486     }
 487 
 488     @Override
 489     public boolean isRunning() {
 490         synchronized (control_mutex) {
 491             return active;
 492         }
 493     }
 494 
 495     @Override
 496     public void start() {
 497 
 498         LineEvent event = null;
 499 
 500         synchronized (control_mutex) {
 501             if (isOpen()) {
 502                 if (active)
 503                     return;
 504                 active = true;
 505                 active_sg = true;
 506                 loopcount = 0;
 507                 event = new LineEvent(this, LineEvent.Type.START,
 508                         getLongFramePosition());
 509             }
 510         }
 511 
 512         if (event != null)
 513             sendEvent(event);
 514     }
 515 
 516     @Override
 517     public void stop() {
 518         LineEvent event = null;
 519 
 520         synchronized (control_mutex) {
 521             if (isOpen()) {
 522                 if (!active)
 523                     return;
 524                 active = false;
 525                 active_sg = true;
 526                 event = new LineEvent(this, LineEvent.Type.STOP,
 527                         getLongFramePosition());
 528             }
 529         }
 530 
 531         if (event != null)
 532             sendEvent(event);
 533     }
 534 
 535     @Override
 536     public void close() {
 537         LineEvent event = null;
 538 
 539         synchronized (control_mutex) {
 540             if (!isOpen())
 541                 return;
 542             stop();
 543 
 544             event = new LineEvent(this, LineEvent.Type.CLOSE,
 545                     getLongFramePosition());
 546 
 547             open = false;
 548             mixer.getMainMixer().closeLine(this);
 549         }
 550 
 551         if (event != null)
 552             sendEvent(event);
 553 
 554     }
 555 
 556     @Override
 557     public boolean isOpen() {
 558         return open;
 559     }
 560 
 561     @Override
 562     public void open() throws LineUnavailableException {
 563         if (data == null) {
 564             throw new IllegalArgumentException(
 565                     "Illegal call to open() in interface Clip");
 566         }
 567         open(format, data, offset, bufferSize);
 568     }
 569 
 570 }
< prev index next >