2

I am looking for some links/source codes/tutorials on how to implement a Java client which is able to send audio over to a server (Below). It will be able to send a audio file, which will then be received by the server and played through the computer speakers.

I would also like to ask, would using a UDP or TCP Server be better for this type of situation? Because I would be developing an android app which records sounds then sends it to the server for playback through the computer speakers in real time.

package com.datagram;

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.FloatControl;
import javax.sound.sampled.SourceDataLine;

class Server {

AudioInputStream audioInputStream;
static AudioInputStream ais;
static AudioFormat format;
static boolean status = true;
static int port = 50005;
static int sampleRate = 44100;

public static void main(String args[]) throws Exception {

    DatagramSocket serverSocket = new DatagramSocket(50005);
    byte[] receiveData = new byte[4000];

    format = new AudioFormat(sampleRate, 16, 1, true, false);

    while (status == true) {    

        DatagramPacket receivePacket = new DatagramPacket(receiveData,
                receiveData.length);

        serverSocket.receive(receivePacket);
        System.out.println("It works");

        ByteArrayInputStream baiss = new ByteArrayInputStream(
                receivePacket.getData());

        ais = new AudioInputStream(baiss, format, receivePacket.getLength());

        toSpeaker(receivePacket.getData());


    }
}

public static void toSpeaker(byte soundbytes[]) {
    try {

        DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
        SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);

        sourceDataLine.open(format);

        FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
        volumeControl.setValue(100.0f);

        sourceDataLine.start();
        sourceDataLine.open(format);

        sourceDataLine.start();

        System.out.println("format? :" + sourceDataLine.getFormat());

        sourceDataLine.write(soundbytes, 0, soundbytes.length);
        System.out.println(soundbytes.toString());
        sourceDataLine.drain();
        sourceDataLine.close();
    } catch (Exception e) {
        System.out.println("Not working in speakers...");
        e.printStackTrace();
    }
}
}
Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
user3441098
  • 43
  • 1
  • 8

1 Answers1

3

First of all a small clarification: the thing you wanna do is an audio streaming (just so you know - it will help you with any future google-searches).

Ok, so one answer at a time:

  1. "Is it better to use UDP or TCP server?"

    • The specifics of TCP protocol makes it not really a good choice for streaming (unless you know how to use it correctly, which is not easy but possible). The reason why TCP is not good is the presence of retransmission mechanism. When a packet gets damaged or lost in network, TCP protocol requests for this packets retransmission (it is a simplification of the model but its good enough for the explanation purposes). When transmitting audio data that needs to be played real-time, retransmission doesn't work well. Imagine you're listening to somebody's voice and all of a sudden voice stops, then starts back again (with a delay).

    • Basically UDP is better but you have to be aware of the fact that UDP protocol cannot assure that datagrams (messages of UDP protocol) will come to the receiver in the same order that they came out from the sender. So you have to make sure to discard any datagrams that come in a wrong order or buffer incoming datagrams and reestablish the proper order. Also you have to remember that UDP protocol doesn't provide with any mechanisms that secure the transmission - I mean that you cannot be sure that datagrams will get through network safely (they can get lost and UDP protocol cannot control it).

    • The best idea would be to use none of them. You should try to implement RTP protocol.

  2. "How to create android client that's able to send audio to mentioned server?"

    • As I can see you're using AudioFormat as a thing that processes the audio.

    • What you need to do is find something that can grab audio from android mic in the same format as your AudioFormat in your server app can play.

    • From AudioFormat documentation i can see that you're using specific sample rate (variable sampleRate), you use default encoding which is PCM, 16 bit sample size, signed values and Little Endian bit convention.

    • The thing you should be looking at in Android is AudioRecord, which can grab raw audio frames from mic. There's quite a lot of examples on how to use AudioRecord and most of them use PCM 16 encoding. Most of them will write audio to file, but nothing stops you from pushing it to some sort of network socket. Just google it.

    • Just remember to use AudioRecord with the same sample rate as you use in your server.

    • The last thing that needs clarification is Endianness. Endianness is dependent on cpu architecture. Most of Android devices use Little Endian convention, so you don't have to change anything in your server code. However you should be aware of the fact that some devices might be using Big Endian. More explanation here.

Community
  • 1
  • 1
Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
  • Wow thank you for the detailed answer. I will try to code a RTP server? Or continue developing an app whilst using this one? As I have tried but have failed pretty badly.. Or should I go and learn RTP? As I only have 2 weeks to finish this up... Would love to have some guidance :) – user3441098 May 05 '14 at 06:42
  • I think the first step should be to make the android client because the audiorecord can get pretty annoying. Udp server will work fine (but its not the best solution). When you finish working with your android client (you accomplish a successful audio transmission) and you think you have enough time to redesign your transmission model you can start learning about RTP. – Bartek Lipinski May 05 '14 at 07:40
  • Okay, I will start to code the android client, are you experienced in this? Could I ask for more help from you if I face any obstacles? Thanks alot for the replies, I really appreciate it. – user3441098 May 05 '14 at 07:46
  • I have been recently working with an app that was using audiorecord so I had to try to understand it as well as I could. Am I experienced with it? Who knows...?:D AudioRecord still gets kinda annoying for me sometimes:P. You can ask me if you have some serious blockers. If I have time for it, I will try to answer but I can't promise anything. – Bartek Lipinski May 05 '14 at 12:29
  • BTW if you believe my answer answered your question use the tick (check mark) under the vote arrows to accept it, please:). – Bartek Lipinski May 05 '14 at 13:23
  • Sure! Done! Is there anyway I could communicate with you besides commenting? There's a lot for me to do in the next few weeks before I had to submit the whole project.. So it's kind of stress for me.. I use http://stackoverflow.com/questions/15349987/stream-live-android-audio-to-server But it doesn't work for me? It's "Unfortunately app has crashed" when I copied the code and installed the app to my device after running the server? – user3441098 May 05 '14 at 14:52
  • Hey @blipinsk, do you have any idea about buffersizes? I have tried the above link and it just spams me saying minBuffSize:-3 or some random number, is it that the buffersize is wrong? – user3441098 May 06 '14 at 02:26
  • Me and other stackoverflow members can help you with problems that you think are completely unsolvable by you, but you need to try to figure some things by yourself. If getMinSizeBuffer returns some negative values that means its some sort of error... What kind of error? You have to check [documentation](http://developer.android.com/reference/android/media/AudioRecord.html). Look for info about what this method can return. If you find some more difficulties in using AudioRecord, pls post a new question, you have a bigger chance of an answer (I cant be here all the time, to help you my friend). – Bartek Lipinski May 07 '14 at 10:40