在Java中,通过TCP套接字从C#应用程序接收音频数据流,并在接收时播放流媒体

在Java中,通过TCP套接字从C#应用程序接收音频数据流,并在接收时播放流媒体,java,c#,audio,tcp,Java,C#,Audio,Tcp,我有一些C#应用程序中音频的原始PCM数据。我需要把它放到Java应用程序中并作为音频播放 作为第一步,我希望Java应用程序在音频流输入时立即播放音频(而不是保存临时文件并播放,而是在接收时播放) 我在用C#正确格式化PCM音频数据并将其发送到Java应用程序时遇到问题。我目前正在使用一个简单的TCP套接字系统来实现这一点,将C#app(Unity制造)称为“客户端”,将Java应用称为“服务器” 在Unity C#客户端上,我使用NatMic获取麦克风的原始PCM数据。当数据进入时,此函数每

我有一些C#应用程序中音频的原始PCM数据。我需要把它放到Java应用程序中并作为音频播放

作为第一步,我希望Java应用程序在音频流输入时立即播放音频(而不是保存临时文件并播放,而是在接收时播放)

我在用C#正确格式化PCM音频数据并将其发送到Java应用程序时遇到问题。我目前正在使用一个简单的TCP套接字系统来实现这一点,将C#app(Unity制造)称为“客户端”,将Java应用称为“服务器”

在Unity C#客户端上,我使用NatMic获取麦克风的原始PCM数据。当数据进入时,此函数每秒调用多次:

void IAudioProcessor.OnSampleBuffer(float[] sampleBuffer, int sampleRate, int channelCount, long timestamp)
我有一个浮点数组和两个整数来描述音频数据

如何将这些数据打包成字节发送到Java

我有一个TCP设置,可以将字节发送到Java,当我测试在客户端和服务器之间来回发送简单的字符串消息时,它似乎工作得很好

但是,当我试图打包音频并发送过来时,它永远不会起作用。我总是遇到这样的错误:

javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
以下是Java端的一个片段,介绍了我如何尝试在Java端播放音频作为测试(当客户端连接时,我运行了一次):


我应该如何打包float[]、int和int以发送到Java服务器,以便它将其识别为音频流?

首先,您需要将数据输出为
源数据线,而不是
剪辑。
剪辑在接收到整个声音文件之前无法播放

通常的计划是以您想要的任何方式读取输入行,并在调用sdl.write()方法的循环中将其转换为正确的格式

对于传入的数据,应该采用以下方法

while(playerRunning)
{
    readBuffer = getInputPCM();
    audioBytes = convertToFollowAudioFormat(readBuffer);
    sourceDataLine.write(audioBytes, 0, sdlBufferSize);
}
如果传入数据是浮动的,范围从-1到1,并且以基本的“CD质量”Java格式(44100 fps,16位,立体声,little endian)输出,则转换可能如下所示:

for (int i = 0, n = buffer.length; i < n; i++)
{
    buffer[i] *= 32767;
    audioBytes[i*2] = (byte) buffer[i];
    audioBytes[i*2 + 1] = (byte)((int)buffer[i] >> 8 );
}
return audioBytes;
至于您的
getInputPCM
方法,我假设您能够在流中只显示PCM数据,不需要进一步解析。如果您想在发货前将PCM转换为C#格式的字节,这也是完全有效的

在Java教程的教程中,有更多关于各种输出格式的文章


对于以上内容,我主要是从我的github项目中复制/编辑代码,这是一种增强的
Clip

Clip listener期望什么?所以这真的是一个c#问题:如何将整数打包成字节:找出!!嗨,菲尔,我真的很感谢你抽出时间陪我度过这段时间。根据你提供的信息,我已经能够让它播放一些声音!但声音只是一些白噪音。当从客户端接收到数据时,我像这样向sdl写入:
byte[]audioBytes=convertAudioBytes(字节)
sourceDataLine.write(audioBytes,0,audioBytes.length)
客户机中的PCM被规范化为-1到1,因此在将其写入sdl之前,我基于您的转换器运行了一个新函数。我在C#端犯了一个错误(原来我已经在那里转换了字节,所以当我在Java端通过转换器运行它们时,它产生了白噪声woops)。我现在可以听到音频了!有一些小的中断(听起来有点像静电),但它是真正的音频传输,应该为我的目的工作。再次感谢您花时间仔细阅读。而“静态”是由于为传入的字节数组使用了错误的大小(太小,无法包含所有缓冲区数据)而导致的,所以它也消失了。听起来好极了,太棒了!祝贺
for (int i = 0, n = buffer.length; i < n; i++)
{
    buffer[i] *= 32767;
    audioBytes[i*2] = (byte) buffer[i];
    audioBytes[i*2 + 1] = (byte)((int)buffer[i] >> 8 );
}
return audioBytes;
AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
                44100, 16, 2, 4, 44100, false);
Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
SourceDataLine sdl = (SourceDataLine)AudioSystem.getLine(info);