Click here to Skip to main content
15,885,309 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Dear Sirs...

I am trying to create a simple voip application using android. The settings are as follows:

1- Two android machines are being used: A phone, and a tablet.
2- Both machines are connected via "Wi-Fi Direct"
3- The connectivity is working perfectly fine and I can send and receive data without a problem
4- Each few milliseconds I get the contents of the recording buffer, and send it from the client to the server. No compression is being applied here. I just want to send raw audio samples for now.
5- the samples are played on the other device and I can distinguish that the speech is being transmitted however the noise is very high, so I am not sure what the reason is.

I the code of the client and server threads is shown below. I am sure there are things that I am missing here, so any advice is highly appreciated. I don't want to use an SDK, or anything else, I just want to identify what the problem is.

Thank you


public void run() 
{
  try
  {
    // open connection with the server
    InetAddress serverAddr = InetAddress.getByName(this.ServerIPEditText.getText().toString());
    int port=Integer.parseInt(this.ServerPortEditText.getText().toString());
    Socket socket = new Socket(serverAddr, port);
    OutputStream ServerStream=socket.getOutputStream();
			
    // prepare mic recordings
    AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
        RECORDER_SAMPLERATE, RECORDER_CHANNELS,
	RECORDER_AUDIO_ENCODING,  RECORDER_SAMPLERATE * 4);
				
    recorder.startRecording();
			
    short[] buffer=new short[RECORDER_SAMPLERATE*4];
    ByteBuffer byteBuf = ByteBuffer.allocate(2*RECORDER_SAMPLERATE*4);
			
    // keep recording and sending to the server
    while (true)
    {
				
      // first wait for parts of a second, for example 128ms
      Thread.sleep(128);
				
      // read the recorded data
      int count=recorder.read(buffer, 0, buffer.length);
				
      // convert shorts into bytes
      byteBuf.rewind();
      for(int i=0;i<count;i++)
        byteBuf.putShort(buffer[i]);
				
      int length=count*2;
				
			
      // send data
      ServerStream.write(byteBuf.array(),0,length);
				
      ServerStream.flush(); 
    }
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
		
}


Server thread:

public void run() 
{
  try 
  {
    // accept client connection
    Socket client=this.MyServerSocket.accept();
    InputStream ClientStream=client.getInputStream();
			
    // now prepare stuff to be played
    short[] buffer=new short[RECORDER_SAMPLERATE*4];
    ByteBuffer byteBuf = ByteBuffer.allocate(2*RECORDER_SAMPLERATE*4);

			
    // prepare audio player
    int intSize = android.media.AudioTrack.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 
                    RECORDER_SAMPLERATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, 44100*4, AudioTrack.MODE_STREAM); 
    at.play();

    byte[] readBuffer=new byte[1024*4];

	        
    // enter a loop
    while (true)
    {
      // set the length of bytes to be read
      int length=readBuffer.length;
				
      // read the chunk of PCM audio
      int pos=0;
      while (pos!=length)
      {
        pos+=ClientStream.read(readBuffer,pos,length-pos);
      }
				
      //now convert that into short array
      for(int i=0;i<length/2;i++)
      {
        int v=readBuffer[i*2]+readBuffer[i*2+1]-32768;
        buffer[i]=(short) v;
      }
				
				 
      // send this to the out buffer
      at.write(buffer, 0, length/2); 
				
				
    }
			
  } 
  catch (IOException e) 
  {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
		  
}
Posted
Updated 24-Jun-13 2:58am
v2

1 solution

Hi there...

I figured out the solution. First the way I used to convert values back from short to byte is totally wrong. In addition I had an impression that byte value in java is from 0 to 255, however it is from -128 to +127


so I had to modify the client, and just pass the array at the server without any modification and it played perfectly well.

the modification at the client is - converting short into byte array -:

C#
for(int i=0;i<count;i++)
{
    tmp=buffer[i]+32768;
    b1= tmp % 256;
    b2= tmp / 256;
    bbuf[i*2  ]=(byte) (b1-128);
    bbuf[i*2+1]=(byte) (b2-128);
}


as for the server just pass the array directly to the player and it should work perfectly fine.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900