Audio Latency - Java программа для программы Android - PullRequest
0 голосов
/ 05 июля 2018

У меня есть две нити Java, одна на моем компьютере, а другая на телефоне Android. Я хочу транслировать аудио, полученное со звуковой линии на моем компьютере, на телефон Android через UDP-пакеты (одноранговое соединение).

Все работает нормально, за исключением случаев, когда задержка звука и основная проблема, которую я имею, это задержка. Я пробовал разные частоты дискретизации и разный размер буфера, но у меня все еще есть задержка (1-2 секунды) между двумя устройствами.

Это мой код.

Java Audio Sender

(new Thread(() -> {

            while (true) {
                   System.out.println(">>"+status);
                while (status) {

                    try {

                        int size = tdl.read(buffer, 0, buffer.length);
                        if(size>0){
                        DatagramPacket sendPacket
                                = new DatagramPacket(buffer, size, hostAddress, port);
                        socket.send(sendPacket);
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(AudioSender.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (java.lang.NullPointerException ne) {

                    }
                }
            }

        })).start();

 public static void setUpAudioDriverInput() throws LineUnavailableException {
    if (tdl != null) {
        tdl.close();
    }

    int channels = 1;
    int sampleSize = 16;
    boolean bigEndian = false;

    format = new AudioFormat(rate, sampleSize, channels, true, bigEndian);

    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

    Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();

    Mixer mixer = AudioSystem.getMixer(mixerInfoFinal.get(lineIndex));

    tdl = (TargetDataLine) mixer.getLine(info);
    tdl.open(format);
    tdl.start();

}

Java Android Audio Receiver

  public void getStreaming(){


       getThread = new Thread(new Runnable() {
        @Override
        public void run() {

            try {

                System.out.println("Thread Streamer is Starting..  status2"+ status2);

                int rate = Integer.parseInt(((Spinner) findViewById(R.id.rateSpinner)).getSelectedItem().toString());
                int bufferSize = Integer.parseInt(((Spinner) findViewById(R.id.bufferSizeSpinner)).getSelectedItem().toString());

                String payload = ((EditText) findViewById(R.id.nameEditText)).getText().toString();
                payload += "#" + rate;
                payload += "#" + bufferSize;
                payload += "#";

                System.out.println(">>>"+payload);

                InetAddress address = InetAddress.getByName(((EditText) findViewById(R.id.ipAddressEditText)).getText().toString());
                DatagramPacket dp = new DatagramPacket(payload.getBytes(),payload.length(),address,8088);
                socket.send(dp);

               byte[] buffer = new byte[bufferSize];

                AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate, channelConfigOUT, audioFormat, buffer.length, AudioTrack.MODE_STREAM);
                audioTrack.play();


                DatagramPacket receivedPacket = new DatagramPacket(buffer,buffer.length);

                System.out.println("BufferSize "+ bufferSize);




                boolean skip=false;

                while(status2 && !Thread.currentThread().isInterrupted()){
                    try {
                        socket.receive(receivedPacket);
                    }catch(SocketTimeoutException ste){
                        skip=true;
                        Thread.currentThread().interrupt();
                        stopStreaming();

                    }
                    if(!skip) {
                        buffer = receivedPacket.getData();
                        audioTrack.write(buffer, 0, buffer.length);
                        System.out.println("aaa" + Thread.currentThread().getName());

                    }
                }

            } catch (SocketException e) {
                e.printStackTrace();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }



        }
    });

    getThread.start();

}

Спасибо.

UPDATE Я обнаружил, что это была сеть, где я пытался, что это супер пересылка пакетов. С другой сетью задержка действительно уменьшилась до менее чем половины секунды. Вчера я мог посмотреть фильм с ним, и время ожидания на пределе. Я дам вам знать, если я улучшу систему.

1 Ответ

0 голосов
/ 05 июля 2018

Вы не должны использовать размер чтения TargetDataLine для создания DatagramPacket. Слишком много пакетов создано.

Лучше всего прочитать несколько килобайт данных (т.е. несколько чтений TDL), а затем отправить их в один "большой" DatagramPacket.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...