Note that there are some explanatory texts on larger screens.

plurals
  1. POStreaming voice between Android Phones over WiFi
    primarykey
    data
    text
    <p>I'm trying to stream audio from the mic from 1 Android to another over WiFi. After looking at some examples I made 2 applications with a single activity in each, 1 to capture and send audio and the other to receive.</p> <p>I've used the Audiorecord and Audiotrack classes to capture and play. However, i just hear some crackling sound (which has now stopped after i made some changes though i reverted back)</p> <p>The activity to send voice. </p> <pre><code>public class VoiceSenderActivity extends Activity { private EditText target; private TextView streamingLabel; private Button startButton,stopButton; public byte[] buffer; public static DatagramSocket socket; private int port=50005; //which port?? AudioRecord recorder; //Audio Configuration. private int sampleRate = 8000; //How much will be ideal? private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; private boolean status = true; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); target = (EditText) findViewById (R.id.target_IP); streamingLabel = (TextView) findViewById(R.id.streaming_label); startButton = (Button) findViewById (R.id.start_button); stopButton = (Button) findViewById (R.id.stop_button); streamingLabel.setText("Press Start! to begin"); startButton.setOnClickListener (startListener); stopButton.setOnClickListener (stopListener); } private final OnClickListener stopListener = new OnClickListener() { @Override public void onClick(View arg0) { status = false; recorder.release(); Log.d("VS","Recorder released"); } }; private final OnClickListener startListener = new OnClickListener() { @Override public void onClick(View arg0) { status = true; startStreaming(); } }; public void startStreaming() { Thread streamThread = new Thread(new Runnable() { @Override public void run() { try { int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); DatagramSocket socket = new DatagramSocket(); Log.d("VS", "Socket Created"); byte[] buffer = new byte[minBufSize]; Log.d("VS","Buffer created of size " + minBufSize); DatagramPacket packet; final InetAddress destination = InetAddress.getByName(target.getText().toString()); Log.d("VS", "Address retrieved"); recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize); Log.d("VS", "Recorder initialized"); recorder.startRecording(); while(status == true) { //reading data from MIC into buffer minBufSize = recorder.read(buffer, 0, buffer.length); //putting buffer in the packet packet = new DatagramPacket (buffer,buffer.length,destination,port); socket.send(packet); } } catch(UnknownHostException e) { Log.e("VS", "UnknownHostException"); } catch (IOException e) { Log.e("VS", "IOException"); } } }); streamThread.start(); } } </code></pre> <p>The activity to receive voice</p> <pre><code>public class VoiceReceiverActivity extends Activity { private Button receiveButton,stopButton; public static DatagramSocket socket; private AudioTrack speaker; //Audio Configuration. private int sampleRate = 8000; //How much will be ideal? private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; private boolean status = true; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); receiveButton = (Button) findViewById (R.id.receive_button); stopButton = (Button) findViewById (R.id.stop_button); findViewById(R.id.receive_label); receiveButton.setOnClickListener(receiveListener); stopButton.setOnClickListener(stopListener); } private final OnClickListener stopListener = new OnClickListener() { @Override public void onClick(View v) { status = false; speaker.release(); Log.d("VR","Speaker released"); } }; private final OnClickListener receiveListener = new OnClickListener() { @Override public void onClick(View arg0) { status = true; startReceiving(); } }; public void startReceiving() { Thread receiveThread = new Thread (new Runnable() { @Override public void run() { try { DatagramSocket socket = new DatagramSocket(50005); Log.d("VR", "Socket Created"); byte[] buffer = new byte[256]; //minimum buffer size. need to be careful. might cause problems. try setting manually if any problems faced int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat); speaker = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,channelConfig,audioFormat,minBufSize,AudioTrack.MODE_STREAM); speaker.play(); while(status == true) { try { DatagramPacket packet = new DatagramPacket(buffer,buffer.length); socket.receive(packet); Log.d("VR", "Packet Received"); //reading content from packet buffer=packet.getData(); Log.d("VR", "Packet data read into buffer"); //sending data to the Audiotrack obj i.e. speaker speaker.write(buffer, 0, minBufSize); Log.d("VR", "Writing buffer content to speaker"); } catch(IOException e) { Log.e("VR","IOException"); } } } catch (SocketException e) { Log.e("VR", "SocketException"); } } }); receiveThread.start(); } } </code></pre> <p>I used wireshark to check if the packets are being sent and i can see the packets. The source however, is the MAC address of the sending device and destination too something like a physical address. Not sure if this is relevant though.</p> <p>So what's the problem with?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COThere are at least three problems you have to deal with: delayed (or missing) data, overall data throughput, and the possibility of slightly mismatched sampling frequencies. Practical IP telephony has to have a means of dealing with all three. Mismatched clocks is surprisingly tricky - initially you can introduce a delay to give some buffering allowance, but if the sender is slower you will use up the buffer and the receiver will be starved for data; while if the sender is faster the buffer will eventually overflow with unplayed data.
      singulars
    2. COI did manage to get this working actually. Didn't really have a problem of mismatched frequencies. Delay in data, yes. Had a sort of protocol of my own to match the receiver/sender clocks. At the end it did work but only with some lag (which increased with distance from the wireless router)
      singulars
    3. COHey there, I implemented a test application for the code you have above, making all the necessary changes suggested below butI am still having a problem. I am getting comms between the two phones no problem, but I don't think the mic is recording properly as I am not hearing any sound on the other end. Do you perhaps have a link to a sample solution that I could take a look at?
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload