title: Capture 8kHz, 16-bit Linear Samples with 4 frames of 20ms audio in each RTP Packet
body: <p>I need to write simple Java Client program to capture live audio streaming. </p>
  
  <p><strong>Requirement</strong></p>
  
  <ul>
  <li>RTP Audio Packets.</li>
  <li>8kHz, 16-bit Linear Samples (Linear PCM).</li>
  <li>4 frames of 20ms audio will be sent in each RTP Packet.</li>
  </ul>
  
  <p>After some search I found sample code on internet to capture the audio but it play beep sound. </p>
  
  <p><strong>Code</strong></p>
  
  <pre><code>import java.io.ByteArrayInputStream;
  import java.net.DatagramPacket;
  import java.net.DatagramSocket;
  import javax.sound.sampled.AudioFormat;
  import javax.sound.sampled.AudioInputStream;
  import javax.sound.sampled.AudioSystem;
  import javax.sound.sampled.DataLine;
  import javax.sound.sampled.SourceDataLine;
  
  public class Server {
  
      AudioInputStream audioInputStream;
      static AudioInputStream ais;
      static AudioFormat format;
      static boolean status = true;
      static int port = 31007;
      static int sampleRate = 44100;
  
      static DataLine.Info dataLineInfo;
      static SourceDataLine sourceDataLine;
  
      public static void main(String args[]) throws Exception 
      {
          System.out.println("Server started at port:"+port);
  
          @SuppressWarnings("resource")
          DatagramSocket serverSocket = new DatagramSocket(port);
  
          /**
           * Formula for lag = (byte_size/sample_rate)*2
           * Byte size 9728 will produce ~ 0.45 seconds of lag. Voice slightly broken.
           * Byte size 1400 will produce ~ 0.06 seconds of lag. Voice extremely broken.
           * Byte size 4000 will produce ~ 0.18 seconds of lag. Voice slightly more broken then 9728.
           */
  
          byte[] receiveData = new byte[4096];
  
          format = new AudioFormat(sampleRate, 16, 2, true, false);
          dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
          sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
          sourceDataLine.open(format);
          sourceDataLine.start();
  
          //FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
          //volumeControl.setValue(1.00f);
  
          DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
  
          ByteArrayInputStream baiss = new ByteArrayInputStream(receivePacket.getData());
  
          while (status == true) 
          {
              System.out.println("Reciving Packets");
              serverSocket.receive(receivePacket);
              ais = new AudioInputStream(baiss, format, receivePacket.getLength());
              toSpeaker(receivePacket.getData());
          }
          sourceDataLine.drain();
          sourceDataLine.close();
      }
  
      public static void toSpeaker(byte soundbytes[]) {
          try 
          {
              System.out.println("At the speaker");
              sourceDataLine.write(soundbytes, 0, soundbytes.length);
          } catch (Exception e) {
              System.out.println("Not working in speakers...");
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>I think I can not able to find the proper format to capture packets send in given format ? </p>
  
  <p>Can any one help me to find find the proper <em>AudioFormat</em> to capture this audio streaming or any link pointing to same will be helpful for me... Thanks... :)</p>
  
  <p><strong><em>Answer</em></strong></p>
  
  <pre><code>float sampleRate = 8000;
  int sampleSizeInBits = 16;
  int channels = 1;
  boolean signed = true;
  boolean bigEndian = true;
  AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
  </code></pre>
  
  <p><strong>UDP + RTP Packet Format</strong></p>
  
  <p><a href="https://i.stack.imgur.com/sT6sx.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sT6sx.gif" alt="enter image description here"></a></p>
  
  <p>While buffering minus 12 bytes from data as it contains RTP header information.</p>
  
  <pre><code>receivePacket = new DatagramPacket(receiveData, receiveData.length);
  byte[] packet = new byte[receivePacket.getLength() - 12];
  serverSocket.receive(receivePacket);
  packet = Arrays.copyOfRange(receivePacket.getData(), 12, receivePacket.getLength());
  </code></pre>
  
  <p>hope this will help you in future or feel free to correct if its wrong Thanks..</p>