gt:                 outputLine = (SourceDataLine) AudioSystem.getLine(info);
context: package org.kontalk.util;
  
  import java.io.BufferedInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  import javax.sound.sampled.AudioFormat;
  import javax.sound.sampled.AudioSystem;
  import javax.sound.sampled.DataLine;
  import javax.sound.sampled.FloatControl;
  import javax.sound.sampled.LineUnavailableException;
  import javax.sound.sampled.SourceDataLine;
  
  import com.jcraft.jogg.Packet;
  import com.jcraft.jogg.Page;
  import com.jcraft.jogg.StreamState;
  import com.jcraft.jogg.SyncState;
  import com.jcraft.jorbis.Block;
  import com.jcraft.jorbis.Comment;
  import com.jcraft.jorbis.DspState;
  import com.jcraft.jorbis.Info;
  
  /**
   * Simple Clip like player for OGG's. Code is mostly taken from the example
   * provided with JOrbis.
   *
   * Source: http://www.cokeandcode.com/main/code/
   *
   * @author kevin
   */
  public class OggClip {
  
      private final int BUFSIZE = 4096 * 2;
      private int convsize = BUFSIZE * 2;
      private byte[] convbuffer = new byte[convsize];
      private SyncState oy;
      private StreamState os;
      private Page og;
      private Packet op;
      private Info vi;
      private Comment vc;
      private DspState vd;
      private Block vb;
      private SourceDataLine outputLine;
      private int rate;
      private int channels;
      private BufferedInputStream bitStream = null;
      private byte[] buffer = null;
      private int bytes = 0;
      private Thread player = null;
  
      private float balance;
      private float gain = -1;
      private boolean paused;
      private float oldGain;
  
      /**
       * Create a new clip based on a reference into the class path
       *
       * @param ref The reference into the class path which the ogg can be read
       * from
       * @throws IOException Indicated a failure to find the resource
       */
      public OggClip(String ref) throws IOException {
          try {
              init(Thread.currentThread().getContextClassLoader().getResourceAsStream(ref));
          } catch (IOException e) {
              throw new IOException("Couldn't find: " + ref);
          }
      }
  
      /**
       * Create a new clip based on a reference into the class path
       *
       * @param in The stream from which the ogg can be read from
       * @throws IOException Indicated a failure to read from the stream
       */
      public OggClip(InputStream in) throws IOException {
          init(in);
      }
  
      /**
       * Set the default gain value (default volume)
       */
      public void setDefaultGain() {
          setGain(-1);
      }
  
      /**
       * Attempt to set the global gain (volume ish) for the play back. If the
       * control is not supported this method has no effect. 1.0 will set maximum
       * gain, 0.0 minimum gain
       *
       * @param gain The gain value
       */
      public void setGain(float gain) {
          if (gain != -1) {
              if ((gain < 0) || (gain > 1)) {
                  throw new IllegalArgumentException("Volume must be between 0.0 and 1.0");
              }
          }
  
          this.gain = gain;
  
          if (outputLine == null) {
              return;
          }
  
          try {
              FloatControl control = (FloatControl) outputLine.getControl(FloatControl.Type.MASTER_GAIN);
              if (gain == -1) {
                  control.setValue(0);
              } else {
                  float max = control.getMaximum();
                  float min = control.getMinimum(); // negative values all seem to be zero?
                  float range = max - min;
  
                  control.setValue(min + (range * gain));
              }
          } catch (IllegalArgumentException e) {
              // gain not supported
              e.printStackTrace();
          }
      }
  
      /**
       * Attempt to set the balance between the two speakers. -1.0 is full left
       * speak, 1.0 if full right speaker. Anywhere in between moves between the
       * two speakers. If the control is not supported this method has no effect
       *
       * @param balance The balance value
       */
      public void setBalance(float balance) {
          this.balance = balance;
  
          if (outputLine == null) {
              return;
          }
  
          try {
              FloatControl control = (FloatControl) outputLine.getControl(FloatControl.Type.BALANCE);
              control.setValue(balance);
          } catch (IllegalArgumentException e) {
              // balance not supported
          }
      }
  
      /**
       * Check the state of the play back
       *
       * @return True if the playback has been stopped
       */
      private boolean checkState() {
          while (paused && (player != null)) {
              synchronized (player) {
                  if (player != null) {
                      try {
                          player.wait();
                      } catch (InterruptedException e) {
                          // ignored
                      }
                  }
              }
          }
  
          return stopped();
      }
  
      /**
       * Pause the play back
       */
      public void pause() {
          paused = true;
          oldGain = gain;
          setGain(0);
      }
  
      /**
       * Check if the stream is paused
       *
       * @return True if the stream is paused
       */
      public boolean isPaused() {
          return paused;
      }
  
      /**
       * Resume the play back
       */
      public void resume() {
          if (!paused) {
              play();
              return;
          }
  
          paused = false;
  
          synchronized (player) {
              if (player != null) {
                  player.notify();
              }
          }
          setGain(oldGain);
      }
  
      /**
       * Check if the clip has been stopped
       *
       * @return True if the clip has been stopped
       */
      public boolean stopped() {
          return ((player == null) || (!player.isAlive()));
      }
  
      /**
       * Initialise the ogg clip
       *
       * @param in The stream we're going to read from
       * @throws IOException Indicates a failure to read from the stream
       */
      private void init(InputStream in) throws IOException {
          if (in == null) {
              throw new IOException("Couldn't find input source");
          }
          bitStream = new BufferedInputStream(in);
          bitStream.mark(Integer.MAX_VALUE);
      }
  
      /**
       * Play the clip once
       */
      public void play() {
          stop();
  
          try {
              bitStream.reset();
          } catch (IOException e) {
              // ignore if no mark
          }
  
          player = new Thread() {
              public void run() {
                  try {
                      playStream(Thread.currentThread());
                  } catch (InternalException e) {
                      e.printStackTrace();
                  }
  
                  try {
                      bitStream.reset();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          ;
          };
  		player.setDaemon(true);
          player.start();
      }
  
      /**
       * Loop the clip - maybe for background music
       */
      public void loop() {
          stop();
  
          try {
              bitStream.reset();
          } catch (IOException e) {
              // ignore if no mark
          }
  
          player = new Thread() {
              @Override
              public void run() {
                  while (player == Thread.currentThread()) {
                      try {
                          playStream(Thread.currentThread());
                      } catch (InternalException e) {
                          e.printStackTrace();
                          player = null;
                      }
  
                      try {
                          bitStream.reset();
                      } catch (IOException e) {
                      }
                  }
              }
          ;
          };
  		player.setDaemon(true);
          player.start();
      }
  
      /**
       * Stop the clip playing
       */
      public void stop() {
          if (stopped()) {
              return;
          }
  
          player = null;
          outputLine.drain();
      }
  
      /**
       * Close the stream being played from
       */
      public void close() {
          try {
              if (bitStream != null) {
                  bitStream.close();
              }
          } catch (IOException e) {
          }
      }
  
      /*
       * Taken from the JOrbis Player
       */
      private void initJavaSound(int channels, int rate) {
          try {
              AudioFormat audioFormat = new AudioFormat(rate, 16,
                      channels, true, // PCM_Signed
                      false // littleEndian
              );
              DataLine.Info info = new DataLine.Info(SourceDataLine.class,
                      audioFormat, AudioSystem.NOT_SPECIFIED);
              if (!AudioSystem.isLineSupported(info)) {
                  throw new Exception("Line " + info + " not supported.");
              }
  
              try {
  