我使用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.