title: Java - recording from mixer
body: <p>I have a problem connected with my previous question. I want to record audio from mixer (speakers), I'm using javax.sound. I have to set up audioFormat and I don't know what to type there :/ Using class ListMixer (which I found here -> <a href="http://forums.oracle.com/forums/thread.jspa?threadID=2198477&amp;tstart=2" rel="noreferrer">http://forums.oracle.com/forums/thread.jspa?threadID=2198477&amp;tstart=2</a>), I write something like this: <a href="http://forums.oracle.com/forums/thread.jspa?threadID=2198477&amp;tstart=2" rel="noreferrer">http://forums.oracle.com/forums/thread.jspa?threadID=2198477&amp;tstart=2</a> but I don't have any info about sample rate (unknown sample rate). Program is throwing this exception:</p>
  
  <blockquote>
    <p>java.lang.IllegalArgumentException: Line unsupported: interface TargetDataLine supporting format PCM_UNSIGNED 44100.0 Hz, 8 bit, mono, 4 bytes/frame,</p>
  </blockquote>
  
  <p>Code:</p>
  
  <pre><code>package sound;
  
  import javax.swing.*;
  import java.awt.*;
  import java.awt.event.*;
  import java.io.*;
  import javax.sound.sampled.*;
  
  public class AudioCapture02 extends JFrame{
  
    boolean stopCapture = false;
    ByteArrayOutputStream byteArrayOutputStream;
    AudioFormat audioFormat;
    TargetDataLine targetDataLine;
    AudioInputStream audioInputStream;
    SourceDataLine sourceDataLine;
  
    public AudioCapture02(){//constructor
      final JButton captureBtn =
                            new JButton("Capture");
      final JButton stopBtn = new JButton("Stop");
      final JButton playBtn =
                           new JButton("Playback");
  
      captureBtn.setEnabled(true);
      stopBtn.setEnabled(false);
      playBtn.setEnabled(false);
  
      //Register anonymous listeners
      captureBtn.addActionListener(
        new ActionListener(){
          public void actionPerformed(
                                   ActionEvent e){
            captureBtn.setEnabled(false);
            stopBtn.setEnabled(true);
            playBtn.setEnabled(false);
            //Capture input data from the
            // microphone until the Stop button is
            // clicked.
            captureAudio();
          }//end actionPerformed
        }//end ActionListener
      );//end addActionListener()
      getContentPane().add(captureBtn);
  
      stopBtn.addActionListener(
        new ActionListener(){
          public void actionPerformed(
                                   ActionEvent e){
            captureBtn.setEnabled(true);
            stopBtn.setEnabled(false);
            playBtn.setEnabled(true);
            //Terminate the capturing of input data
            // from the microphone.
            stopCapture = true;
          }//end actionPerformed
        }//end ActionListener
      );//end addActionListener()
      getContentPane().add(stopBtn);
  
      playBtn.addActionListener(
        new ActionListener(){
          public void actionPerformed(
                                   ActionEvent e){
            //Play back all of the data that was
            // saved during capture.
            playAudio();
          }//end actionPerformed
        }//end ActionListener
      );//end addActionListener()
      getContentPane().add(playBtn);
  
      getContentPane().setLayout(new FlowLayout());
      setTitle("Capture/Playback Demo");
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setSize(250,70);
      setVisible(true);
    }//end constructor
  
    //This method captures audio input from a
    // microphone and saves it in a
    // ByteArrayOutputStream object.
    private void captureAudio(){
      try{
        //Get and display a list of
        // available mixers.
        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
        System.out.println("Available mixers:");
        for(int cnt = 0; cnt &lt; mixerInfo.length;
                                            cnt++){
          System.out.println(mixerInfo[cnt].
                                        getName());
        }//end for loop
  
        //Get everything set up for capture
        audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED, 44100.0F, 8, 1, 4, 44100.0F,
                          false);
  
  
        DataLine.Info dataLineInfo =
                              new DataLine.Info(
                              TargetDataLine.class,
                              audioFormat);
        ListMixers lm = new ListMixers();
        lm.listAll(new PrintWriter(System.out));
  
        System.out.println(" AKTUALNY =&gt; "+mixerInfo[0].getName());
        Mixer mixer = AudioSystem.getMixer(mixerInfo[0]);
  
        //Get a TargetDataLine on the selected
        // mixer.
        targetDataLine = (TargetDataLine)
                       mixer.getLine(dataLineInfo);
        //Prepare the line for use.
        targetDataLine.open(audioFormat);
        targetDataLine.start();
  
        //Create a thread to capture the microphone
        // data and start it running.  It will run
        // until the Stop button is clicked.
        Thread captureThread = new CaptureThread();
        captureThread.start();
      } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
      }//end catch
    }//end captureAudio method
  
    //This method plays back the audio data that
    // has been saved in the ByteArrayOutputStream
    private void playAudio() {
      try{
        //Get everything set up for playback.
        //Get the previously-saved data into a byte
        // array object.
        byte audioData[] = byteArrayOutputStream.
                                     toByteArray();
        //Get an input stream on the byte array
        // containing the data
        InputStream byteArrayInputStream =
               new ByteArrayInputStream(audioData);
        AudioFormat audioFormat = getAudioFormat();
        audioInputStream = new AudioInputStream(
                      byteArrayInputStream,
                      audioFormat,
                      audioData.length/audioFormat.
                                   getFrameSize());
        DataLine.Info dataLineInfo =
                              new DataLine.Info(
                              SourceDataLine.class,
                              audioFormat);
        sourceDataLine = (SourceDataLine)
                 AudioSystem.getLine(dataLineInfo);
        sourceDataLine.open(audioFormat);
        sourceDataLine.start();
  
        //Create a thread to play back the data and
        // start it  running.  It will run until
        // all the data has been played back.
        Thread playThread = new PlayThread();
        playThread.start();
      } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
      }//end catch
    }//end playAudio
  
    //This method creates and returns an
    // AudioFormat object for a given set of format
    // parameters.  If these parameters don't work
    // well for you, try some of the other
    // allowable parameter values, which are shown
    // in comments following the declartions.
    private AudioFormat getAudioFormat(){
      float sampleRate = 8000.0F;
      //8000,11025,16000,22050,44100
      int sampleSizeInBits = 16;
      //8,16
      int channels = 1;
      //1,2
      boolean signed = true;
      //true,false
      boolean bigEndian = false;
      //true,false
      return new AudioFormat(
                        sampleRate,
                        sampleSizeInBits,
                        channels,
                        signed,
                        bigEndian);
    }//end getAudioFormat
  //=============================================//
  
  //Inner class to capture data from microphone
  class CaptureThread extends Thread{
    //An arbitrary-size temporary holding buffer
    byte tempBuffer[] = new byte[10000];
    public void run(){
      byteArrayOutputStream =
                       new ByteArrayOutputStream();
      stopCapture = false;
      try{//Loop until stopCapture is set by
          // another thread that services the Stop
          // button.
        while(!stopCapture){
          //Read data from the internal buffer of
          // the data line.
          int cnt = targetDataLine.read(tempBuffer,
                                0,
                                tempBuffer.length);
          if(cnt &gt; 0){
            //Save data in output stream object.
            byteArrayOutputStream.write(tempBuffer,
                                        0,
                                        cnt);
          }//end if
        }//end while
        byteArrayOutputStream.close();
      }catch (Exception e) {
        System.out.println(e);
        System.exit(0);
      }//end catch
    }//end run
  }//end inner class CaptureThread
  //===================================//
  //Inner class to play back the data
  // that was saved.
  class PlayThread extends Thread{
    byte tempBuffer[] = new byte[10000];
  
    public void run(){
      try{
        int cnt;
        //Keep looping until the input read method
        // returns -1 for empty stream.
        while((cnt = audioInputStream.read(
                        tempBuffer, 0,
                        tempBuffer.length)) != -1){
          if(cnt &gt; 0){
            //Write data to the internal buffer of
            // the data line where it will be
            // delivered to the speaker.
            sourceDataLine.write(tempBuffer,0,cnt);
          }//end if
        }//end while
        //Block and wait for internal buffer of the
        // data line to empty.
        sourceDataLine.drain();
        sourceDataLine.close();
      }catch (Exception e) {
        System.out.println(e);
        System.exit(0);
      }//end catch
    }//end run
  }//end inner class PlayThread
  //=============================================//
  class ListMixers {
      PrintWriter out;
  
       void listAll(final PrintWriter out) {
          this.out = out;
          Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
          for (int i = 0; i &lt; aInfos.length; i++) {
              try {
                  Mixer mixer = AudioSystem.getMixer(aInfos[i]);
                  out.println(""+i+": "+aInfos[i].getName()+", "
                          +aInfos[i].getVendor()+", "
                          +aInfos[i].getVersion()+", "
                          +aInfos[i].getDescription());
  
                  printLines(mixer, mixer.getSourceLineInfo());
                  printLines(mixer, mixer.getTargetLineInfo());
              } catch (Exception e) {
                  out.println("Exception: "+e);
              }
              out.println();
          }
          if (aInfos.length == 0) {
              out.println("[No mixers available]");
          }
      }
  
      void printLines(Mixer mixer, Line.Info[] infos) {
          for (int i = 0; i &lt; infos.length; i++) {
              try {
                  if (infos[i] instanceof Port.Info) {
                      Port.Info info = (Port.Info) infos[i];
  
                      out.println("  Port " + info);
                  }
                  if (infos[i] instanceof DataLine.Info) {
                      DataLine.Info info = (DataLine.Info) infos[i];
  
                      out.println("  Line " + info + " (max. " +
                                  mixer.getMaxLines(info) + " simultaneously): ");
                      printFormats(info);
                  }
                  Line line = mixer.getLine(infos[i]);
  
                  if (!(line instanceof Clip)) {
                      try {
                          line.open();
                      }
                      catch (LineUnavailableException e) {
                          out.println("LineUnavailableException when trying to open this line");
                      }
                  }
                  try {
                      printControls(line.getControls());
                  }
                  finally {
                      if (!(line instanceof Clip)) {
                          line.close();
                      }
                  }
              }
              catch (Exception e) {
                  out.println("Exception: " + e);
              }
              out.println();
          }
      }
  
      void printFormats(DataLine.Info info) {
          AudioFormat[] formats = info.getFormats();
          for (int i = 0; i &lt; formats.length; i++) {
              out.println("  "+i+": "+formats[i]
                      +" ("+formats[i].getChannels()+" channels, "
                      +"frameSize="+formats[i].getFrameSize()+", "
                      +(formats[i].isBigEndian()?"big endian":"little endian")
                      +")");
          }
          if (formats.length == 0) {
              out.println("  [no formats]");
          }
          out.println();
      }
  
      void printControls(Control[] controls) {
          for (int i = 0; i&lt;controls.length; i++) {
              printControl("    ", "Controls["+i+"]: ", controls[i]);
          }
          if (controls.length == 0) {
              out.println("    [no controls]");
          }
          out.println();
      }
  
      void printControl(String indent, String id, Control control) {
          if (control instanceof BooleanControl) {
              BooleanControl ctrl = (BooleanControl) control;
              out.println(indent+id+"BooleanControl: "+ctrl);
          } else if (control instanceof CompoundControl) {
              CompoundControl ctrl = (CompoundControl) control;
              Control[] ctrls = ctrl.getMemberControls();
              out.println(indent+id+"CompoundControl: "+control);
              for (int i=0; i&lt;ctrls.length; i++) {
                  printControl(indent+"  ", "MemberControls["+i+"]: ", ctrls[i]);
              }
          } else if (control instanceof EnumControl) {
              EnumControl ctrl = (EnumControl) control;
              Object[] values = ctrl.getValues();
              Object value = ctrl.getValue();
              out.println(indent+id+"EnumControl: "+control);
              for (int i=0; i&lt;values.length; i++) {
                  if (values[i] instanceof Control) {
                      printControl(indent+"  ", "Values["+i+"]: "+((values[i]==value)?"*":""), (Control) values[i]);
                  } else {
                      out.println(indent+"  Values["+i+"]: "+((values[i]==value)?"*":"")+values[i]);
                  }
              }
          } else if (control instanceof FloatControl) {
              FloatControl ctrl = (FloatControl) control;
              out.println(indent+id+"FloatControl: "+ctrl);
          } else {
              out.println(indent+id+"Control: "+control);
          }
      }
  }
  }//end outer class AudioCapture02.java
  </code></pre>