Frage

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();
    }
}
}
War es hilfreich?

Lösung

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top