播放以UDP数据包收到的原始PCM音频

时间:2015-09-30 18:53:24

标签: java sockets audio udp pcm

远程设备正在发送UDP数据包中的实时原始PCM音频(不包括标头),我需要在java中实现一个程序来接收这些数据包并在PC上播放它们。 据我所知,原始PCM的属性是16位,单声道,采样率24KHz,所以我试图在这个原始的PCM音频和播放中添加一个wav标题,但问题是我没有文件大小的音频。

我还实施了一个基于this link的程序,但它只在输出中产生噪音。

我一定会使用UDP而我只能从远程设备获取原始PCM,所以我可以在PC上播放这些原始音频的任何库或API吗?

1 个答案:

答案 0 :(得分:6)

这是一个获取输出线并在其上播放PCM的简单示例。当它运行时,它会播放大约一秒长的恼人的哔哔声。

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);
        }
    }

}

你看,它大约有10行用于处理该行,代码的一半是“生成PCM”部分,如果你从其他地方获得PCM,你可以忽略它。你需要注意创建正确的AudioFormat,搞砸了有符号和/或endian的布尔值,PCM听起来会非常乱码,甚至可能无法识别。