播放在 UDP 数据包中收到的原始 PCM 音频
远程设备正在 UDP 数据包中发送实时原始 PCM 音频(不包含标头),我需要在 java 中实现一个程序来接收这些数据包并在 PC 上实时播放它们.我知道原始 PCM 的属性是 16 位、单声道、采样率 24KHz,所以我尝试在这个原始 PCM 音频中添加一个 wav 标头并播放,但问题是我没有音频的文件大小.
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.
我还基于 this link 实现了一个程序,但它只会在输出中产生噪音.
I also implemented a program based on this link but it only gives noise in output.
我必须使用 UDP,我只能从远程设备获取原始 PCM,那么他们是否有任何库或 API 可以在 PC 上播放此原始音频?
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?
推荐答案
这里有一个简单的例子,用于获取输出线并在其上播放 PCM.运行时,它会播放大约一秒钟长的烦人的哔哔声.
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);
}
}
}
您看,它大约有十行用于处理该行,其中一半的代码是生成 PCM"部分,如果您从其他地方获取 PCM,您可以忽略它.您需要注意创建正确的音频格式,将带符号和/或字节序的布尔值搞砸,PCM 听起来会很乱,甚至可能无法识别.
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.
相关文章