Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play raw PCM audio received in UDP packets

The remote device is sending live raw PCM audio(no header included) in UDP packets and I need to implement a program in java to receive these packets and play them on the PC live. As I know that raw PCM's attributes are 16bit, mono, sampling rate 24KHz, so I tried to add a wav header to this raw PCM audio and play but the problem is I don't have File size of the audio.

I also implemented a program based on this link but it only gives noise in output.

I am bound to use UDP and I can get only raw PCM from remote device, so is their any library or API by which I can play this raw audio on PC?

like image 761
Abhishek Sharma Avatar asked Sep 30 '15 18:09

Abhishek Sharma


Video Answer


1 Answers

Here is a simple example for obtaining an output line and playing PCM on it. When run it plays about a second long annoying beep.

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

public class RawAudioPlay {

    public static void main(String[] args) {
        try {
            // select audio format parameters
            AudioFormat af = new AudioFormat(24000, 16, 1, true, false);
            DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
            SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);

            // generate some PCM data (a sine wave for simplicity)
            byte[] buffer = new byte[64];
            double step = Math.PI / buffer.length;
            double angle = Math.PI * 2;
            int i = buffer.length;
            while (i > 0) {
                double sine = Math.sin(angle);
                int sample = (int) Math.round(sine * 32767);
                buffer[--i] = (byte) (sample >> 8);
                buffer[--i] = (byte) sample;
                angle -= step;
            }

            // prepare audio output
            line.open(af, 4096);
            line.start();
            // output wave form repeatedly
            for (int n=0; n<500; ++n) {
                line.write(buffer, 0, buffer.length);
            }
            // shut down audio
            line.drain();
            line.stop();
            line.close();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

}

You see, its roughly ten lines for handling the line, half of the code is the section "generate PCM" which you can ignore if you get PCM from somehwere else. You need to pay attention to the creation of the correct AudioFormat, screw up the booleans for signed and/or endian and the PCM will sound very garbled, possibly not even recognizable.

like image 176
Durandal Avatar answered Oct 16 '22 09:10

Durandal