gpt4 book ai didi

java - 使用 Java Sound API 通过 UDP 发送语音

转载 作者:行者123 更新时间:2023-12-03 00:07:34 26 4
gpt4 key购买 nike

我使用 Java Sound API 开发了一个 Java 应用程序。它的作用是捕获来自麦克风的数据并通过 UDP 将其发送到其他计算机以便在那里播放。现在,我遇到了音量、质量和速度问题。我无法找出问题的根源,因此我需要帮助找出程序出了什么问题。

更新
似乎速度问题是由于 Java Sound API 很慢。我尝试了没有 UDP 套接字的程序,并且存在相同类型的延迟,因此 UDP 不会在 LAN 中引入额外的延迟。当程序与耳机一起使用时,回声问题就会消失。声音的质量总体来说还不算太差。唯一剩下的问题是音量。
以下是发件人:

import javax.sound.sampled.*;
import java.io.ByteArrayOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class VoipApp
{
public static void main(String[]args) throws Exception
{
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
float rate = 44100.0f;
int sampleSize = 16;
int channels = 2;
int frameSize = 4;
boolean bigEndian = true;

AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8)
* channels, rate, bigEndian);

TargetDataLine line;
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if(!AudioSystem.isLineSupported(info)){
System.out.println("Not Supported");
System.exit(1);
}

DatagramSocket socket = new DatagramSocket(8081);
//InetAddress IPAddress = InetAddress.getLocalHost();
InetAddress IPAddress = InetAddress.getByName("192.168.0.14");

try
{
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);

//ByteArrayOutputStream out = new ByteArrayOutputStream();
int numBytesRead;
byte[] data = new byte [line.getBufferSize() / 5];
int totalBytesRead = 0;

line.start();
while(true){
numBytesRead = line.read(data,0, data.length);
DatagramPacket sendPacket = new DatagramPacket(data, data.length, IPAddress, 8080);
// totalBytesRead += numBytesRead;
socket.send(sendPacket);
//out.write(data, 0, numBytesRead);
// System.out.println("Debug");
}

}
catch(LineUnavailableException e)
{
e.printStackTrace();
}
}
}
以下是 接收者:
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class VoipAppTwo
{
public static void main(String[]args) throws Exception
{
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
float rate = 44100.0f;
int sampleSize = 16;
int channels = 2;
int frameSize = 4;
boolean bigEndian = true;

AudioFormat format = new AudioFormat(encoding, rate, sampleSize, channels, (sampleSize / 8)
* channels, rate, bigEndian);

SourceDataLine speakers;
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);

speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
speakers.open(format);

DatagramSocket socket = new DatagramSocket(8080);
byte[] data = new byte[speakers.getBufferSize() / 5];
speakers.start();
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(data, data.length);
socket.receive(receivePacket);
speakers.write(data, 0, data.length);
}
}
}

最佳答案

一些想法,但需要注意的是我没有尝试使用 UDP 的直接经验。
在我看来,必须“处理”丢失和乱序的数据包(假设为 UDP),否则预期的不连续性将不断产生破坏性的响亮咔嗒声。但是 IDK 这通常是如何完成的。过滤器?缓冲?将数据包数据封装到窗口(Hann 或 Hamming?)帧中以桥接数据包不连续性?
javax.sound.sampled 非常接近原生声音。 Here is a good article to reference on considerations pertaining to real time, low latency Java-based audio.

关于java - 使用 Java Sound API 通过 UDP 发送语音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62645354/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com