播放UDP数据包中接收到的原始PCM音频 [英] Play raw PCM audio received in UDP packets

查看:504
本文介绍了播放UDP数据包中接收到的原始PCM音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我还基于此链接实现了一个程序,但它只会在输出中产生噪音./p>

我一定要使用UDP,并且只能从远程设备获取原始PCM,那么我可以通过它们在PC上播放此原始音频的任何库或API吗?

解决方案

这是获取输出线并在其上播放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);
        }
    }

}

您会看到,它大约处理了十行,其中一半代码是"generate PCM"部分,如果您从其他地方获得PCM,则可以忽略.您需要注意正确的AudioFormat的创建,将带符号和/或字节序的布尔值弄乱,PCM听起来会很乱,甚至可能无法识别.

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?

解决方案

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.

这篇关于播放UDP数据包中接收到的原始PCM音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆