远程设备正在发送UDP数据包中的实时原始PCM音频(不包括标头),我需要在java中实现一个程序来接收这些数据包并在PC上播放它们。 据我所知,原始PCM的属性是16位,单声道,采样率24KHz,所以我试图在这个原始的PCM音频和播放中添加一个wav标题,但问题是我没有文件大小的音频。
我还实施了一个基于this link的程序,但它只在输出中产生噪音。
我一定会使用UDP而我只能从远程设备获取原始PCM,所以我可以在PC上播放这些原始音频的任何库或API吗?
答案 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听起来会非常乱码,甚至可能无法识别。