Rafiq
Rafiq

Reputation: 750

voice chat or audio call using socket in java

Scenario 1: Voice Chat between two user/client working well, If and only If, both of them use headphone.

Scenario 2: If any one of them don't use headphone, then voice chat is working but noise is increased gradually.

How it work

Client 1's microphone sound recorded and send to Client 2. But Client 1's speaker sound also recorded and send to Client 2. So, Client 2 hear his own sound and Client 1's sound repeatedly. And noise is increasing and increasing.

Purpose

I need to stop recording of speakers sound. How can I read/ record only microphone's input sound by filtering speaker's sound? Please help.

Here is my code:

public class Server {
ServerSocket MyService;
Socket clientSocket = null;
InputStream input;
TargetDataLine targetDataLine;
OutputStream out;
AudioFormat audioFormat;
SourceDataLine sourceDataLine;
byte tempBuffer[] = new byte[10000];
static Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();

Server() throws LineUnavailableException {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.show();
    try {
        Mixer mixer_ = AudioSystem.getMixer(mixerInfo[0]);
        audioFormat = getAudioFormat();
        DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
        sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
        sourceDataLine.open(audioFormat);
        sourceDataLine.start();
        MyService = new ServerSocket(500);
        clientSocket = MyService.accept();
        captureAudio();
        input = new BufferedInputStream(clientSocket.getInputStream());
        out = new BufferedOutputStream(clientSocket.getOutputStream());
        while (input.read(tempBuffer) != -1) {
            sourceDataLine.write(tempBuffer, 0, 10000);

        }

    } catch (IOException e) {

        e.printStackTrace();
    }

}

private AudioFormat getAudioFormat() {
    float sampleRate = 8000.0F;
    int sampleSizeInBits = 8;
    int channels = 1;
    boolean signed = true;
    boolean bigEndian = false;
    return new AudioFormat(
            sampleRate,
            sampleSizeInBits,
            channels,
            signed,
            bigEndian);
}

public static void main(String s[]) throws LineUnavailableException {
    Server s2 = new Server();
}

private void captureAudio() {
    try {

        audioFormat = getAudioFormat();
        DataLine.Info dataLineInfo = new DataLine.Info(
                TargetDataLine.class, audioFormat);
        Mixer mixer = null;
        System.out.println("Available mixers:");
        for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
            mixer = AudioSystem.getMixer(mixerInfo[3]);
            if (mixer.isLineSupported(dataLineInfo)) {
                System.out.println(mixerInfo[cnt].getName());
                targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);
            }
        }
        targetDataLine.open(audioFormat);
        targetDataLine.start();

        Thread captureThread = new CaptureThread();
        captureThread.start();
    } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
    }
}

class CaptureThread extends Thread {

    byte tempBuffer[] = new byte[10000];

    @Override
    public void run() {
        try {
            while (true) {
                int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length);
                out.write(tempBuffer);
                out.flush();

            }

        } catch (Exception e) {
            System.out.println(e);
            System.exit(0);
        }
    }
}}

And

public class Client {
boolean stopCapture = false;
ByteArrayOutputStream byteArrayOutputStream;
AudioFormat audioFormat;
TargetDataLine targetDataLine;
AudioInputStream audioInputStream;
BufferedOutputStream out = null;
BufferedInputStream in = null;
Socket sock = null;
SourceDataLine sourceDataLine;

public static void main(String[] args) {
    Client tx = new Client();
    tx.captureAudio();
}

private void captureAudio() {
    try {
        sock = new Socket("192.168.1.3", 500);
        out = new BufferedOutputStream(sock.getOutputStream());
        in = new BufferedInputStream(sock.getInputStream());

        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
        System.out.println("Available mixers:");
        for (int cnt = 0; cnt < mixerInfo.length; cnt++) {
            System.out.println(mixerInfo[cnt].getName());
        }
        audioFormat = getAudioFormat();

        DataLine.Info dataLineInfo = new DataLine.Info(
                TargetDataLine.class, audioFormat);

        Mixer mixer = AudioSystem.getMixer(mixerInfo[2]);

        targetDataLine = (TargetDataLine) mixer.getLine(dataLineInfo);

        targetDataLine.open(audioFormat);
        targetDataLine.start();

        Thread captureThread = new CaptureThread();
        captureThread.start();

        DataLine.Info dataLineInfo1 = new DataLine.Info(
                SourceDataLine.class, audioFormat);
        sourceDataLine = (SourceDataLine) AudioSystem
                .getLine(dataLineInfo1);
        sourceDataLine.open(audioFormat);
        sourceDataLine.start();

        Thread playThread = new PlayThread();
        playThread.start();

    } catch (Exception e) {
        System.out.println(e);
        System.exit(0);
    }
}

class CaptureThread extends Thread {

    byte tempBuffer[] = new byte[10000];

    @Override
    public void run() {
        byteArrayOutputStream = new ByteArrayOutputStream();
        stopCapture = false;
        try {
            while (!stopCapture) {

                int cnt = targetDataLine.read(tempBuffer, 0,
                        tempBuffer.length);

                out.write(tempBuffer);

                if (cnt > 0) {

                    byteArrayOutputStream.write(tempBuffer, 0, cnt);

                }
            }
            byteArrayOutputStream.close();
        } catch (Exception e) {
            System.out.println(e);
            System.exit(0);
        }
    }
}

private AudioFormat getAudioFormat() {
    float sampleRate = 8000.0F;

    int sampleSizeInBits = 8;

    int channels = 1;

    boolean signed = true;

    boolean bigEndian = false;

    return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
            bigEndian);
}

class PlayThread extends Thread {

    byte tempBuffer[] = new byte[10000];

    @Override
    public void run() {
        try {
            while (in.read(tempBuffer) != -1) {
                sourceDataLine.write(tempBuffer, 0, 10000);

            }
            sourceDataLine.drain();
            sourceDataLine.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  }

}

Upvotes: 4

Views: 16343

Answers (2)

Malcolm Crompton
Malcolm Crompton

Reputation: 1

You could add a noise gate. So if the users volume doesn't reach a certain value, the volume is set to 0

Upvotes: 0

Sebas
Sebas

Reputation: 104

Typical "echo cancellation" issue when dealing with hands-free audio.

Try searching for a library who takes care of that because if you want to do it from scratch it is not trivial, matlab, adaptive filters, etc etc.

Sebas

Upvotes: 2

Related Questions