3

我正在尝试编写一个 VOIP 会议 Java Applet。一切正常,音质良好,直到第三个用户进入房间。我正在尝试合并几个音频流,但是当它完成时,声音真的很不稳定。每个流都进入不同的线程。登录小程序的用户越多,质量损失就越大。

音频格式:采样率:8000,位:16

这是单个音频流的来源:

while (true) {
                DatagramPacket receive = new DatagramPacket(mBuffer, mBuffer.length);
                datagramSocket.receive(receive);
                System.out.println("Received from: " + receive.getAddress() + ":" + receive.getPort());
                short[] shortBuffer = convert(mBuffer); // Convert the buffer to a 2byte short

                double volume = calcVolume(calcDistance(Client.getUser().getXPosition(), Client.getUser().getYPosition(), mUser.getXPosition(), mUser.getYPosition())); // Used to calculate sound for proximity effect
                for (int i = 0; i < shortBuffer.length; i++) {
                    shortBuffer[i] *= volume;
                }
                mBuffer = convert(shortBuffer);

                position = 0; // Set the short position in the buffer to 0
                //resetPosition();
            }

这是音频流汇集并合并的地方:

    class PlayThread extends Thread {
    private short[] previousBuffer; // Used to prevent from duplicated data
    private short[] buffer = new short[1];

    @Override
    public void run() {
        while (true) {

            previousBuffer = Arrays.copyOf(buffer, buffer.length);

            for (int i = 0; i < buffer.length; i++) {
                int sum = 0;
                int total = 0;

                synchronized (mReceiveThreads) {
                    for (ReceiveThread receiveThread : mReceiveThreads) {
                        short[] sBuffer = convert(receiveThread.mBuffer);

                        buffer = smoothArray(sBuffer, 1.6); // Smooth the current buffer
                        if (receiveThread.position < sBuffer.length) {
                            sum += sBuffer[receiveThread.position];
                            receiveThread.position++;
                            total++;
                        }

                    }
                }

                if (total > 0) {
                    buffer[i] = (short) (sum / total);
                }

            }

            if(!Arrays.equals(buffer, previousBuffer)) {

                //lowerVolume();
                if(ClientPanel.getAudioselected()) {
                    sourceDataLine.write(convert(buffer), 0, buffer.length * 2);
                }
            }
            //System.out.println("Took " + (System.nanoTime() - start) + "ns.");
        }
    }

正如你所看到的,我遍历了我所有的接收线程并从所有线程中得到 1 个短。我得到平均声音并将输出写入源数据线。

任何想法如何防止声音变得如此波涛汹涌?

4

0 回答 0