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

10-05 20:46
查看更多