From ae34f5cf6db64e4541eb9e3369009f022663b7b0 Mon Sep 17 00:00:00 2001 From: xucz Date: Tue, 15 Nov 2022 10:55:48 +0800 Subject: [PATCH 1/2] [Android]optimize pushExternalAudioFrame timestamp. --- .../advanced/customaudio/CustomAudioSource.java | 5 ++++- .../agora/api/example/utils/AudioFileReader.java | 15 ++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/customaudio/CustomAudioSource.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/customaudio/CustomAudioSource.java index c5073f813..7fa984682 100755 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/customaudio/CustomAudioSource.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/customaudio/CustomAudioSource.java @@ -54,6 +54,7 @@ public class CustomAudioSource extends BaseFragment implements View.OnClickListe public static RtcEngineEx engine; private Switch mic, pcm; private ChannelMediaOptions option = new ChannelMediaOptions(); + private volatile int pushTimes = 0; private AudioSeatManager audioSeatManager; private AudioFileReader audioPushingHelper; @@ -153,7 +154,8 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { audioPushingHelper = new AudioFileReader(requireContext(), (buffer, timestamp) -> { if(joined && engine != null){ - engine.pushExternalAudioFrame(buffer, timestamp); + Log.i(TAG, "pushExternalAudioFrame times:" + pushTimes++); + engine.pushExternalAudioFrame(buffer, 0); } }); } catch (Exception e) { @@ -330,6 +332,7 @@ public void run() { join.setEnabled(true); join.setText(getString(R.string.leave)); if(audioPushingHelper != null){ + pushTimes = 0; audioPushingHelper.start(); } audioSeatManager.upLocalSeat(uid); diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java index 57e6bf042..d42f449a1 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java @@ -13,7 +13,7 @@ public class AudioFileReader { public static final Integer BITS_PER_SAMPLE = 16; private static final Integer SAMPLES = 441; private static final Integer BUFFER_SIZE = SAMPLES * BITS_PER_SAMPLE / 8 * SAMPLE_NUM_OF_CHANNEL; - private static final Integer PUSH_INTERVAL = SAMPLES * 1000 / SAMPLE_RATE; + private static final long PUSH_INTERVAL = SAMPLES * 1000 / SAMPLE_RATE; private final Context context; private final OnAudioReadListener audioReadListener; @@ -62,16 +62,21 @@ public void run() { } Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO); pushing = true; + + long start_time = System.currentTimeMillis();; + int sent_audio_frames = 0; while (pushing) { - long before = System.currentTimeMillis(); if(audioReadListener != null){ audioReadListener.onAudioRead(readBuffer(), System.currentTimeMillis()); } + ++ sent_audio_frames; + long next_frame_start_time = sent_audio_frames * PUSH_INTERVAL + start_time; long now = System.currentTimeMillis(); - long consuming = now - before; - if(consuming < PUSH_INTERVAL){ + + if(next_frame_start_time > now){ + long sleep_duration = next_frame_start_time - now; try { - Thread.sleep(PUSH_INTERVAL - consuming); + Thread.sleep(sleep_duration); } catch (InterruptedException e) { e.printStackTrace(); } From f1e734a6c77e6061c36caf58aa2969a0e667bb59 Mon Sep 17 00:00:00 2001 From: xucz Date: Thu, 24 Nov 2022 14:44:28 +0800 Subject: [PATCH 2/2] [Android]optimized audio buffer code. --- .../api/example/utils/AudioFileReader.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java index d42f449a1..387463604 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/utils/AudioFileReader.java @@ -8,12 +8,17 @@ public class AudioFileReader { private static final String AUDIO_FILE = "output.raw"; - public static final Integer SAMPLE_RATE = 44100; - public static final Integer SAMPLE_NUM_OF_CHANNEL = 2; - public static final Integer BITS_PER_SAMPLE = 16; - private static final Integer SAMPLES = 441; - private static final Integer BUFFER_SIZE = SAMPLES * BITS_PER_SAMPLE / 8 * SAMPLE_NUM_OF_CHANNEL; - private static final long PUSH_INTERVAL = SAMPLES * 1000 / SAMPLE_RATE; + public static final int SAMPLE_RATE = 44100; + public static final int SAMPLE_NUM_OF_CHANNEL = 2; + public static final int BITS_PER_SAMPLE = 16; + + public static final float BYTE_PER_SAMPLE = 1.0f * BITS_PER_SAMPLE / 8 * SAMPLE_NUM_OF_CHANNEL; + public static final float DURATION_PER_SAMPLE = 1000.0f / SAMPLE_RATE; // ms + public static final float SAMPLE_COUNT_PER_MS = SAMPLE_RATE * 1.0f / 1000; // ms + + private static final int BUFFER_SAMPLE_COUNT = (int) (SAMPLE_COUNT_PER_MS * 10); // 10ms sample count + private static final int BUFFER_BYTE_SIZE = (int) (BUFFER_SAMPLE_COUNT * BYTE_PER_SAMPLE); // byte + private static final long BUFFER_DURATION = (long) (BUFFER_SAMPLE_COUNT * DURATION_PER_SAMPLE); // ms private final Context context; private final OnAudioReadListener audioReadListener; @@ -70,7 +75,7 @@ public void run() { audioReadListener.onAudioRead(readBuffer(), System.currentTimeMillis()); } ++ sent_audio_frames; - long next_frame_start_time = sent_audio_frames * PUSH_INTERVAL + start_time; + long next_frame_start_time = sent_audio_frames * BUFFER_DURATION + start_time; long now = System.currentTimeMillis(); if(next_frame_start_time > now){ @@ -95,7 +100,7 @@ public void run() { } private byte[] readBuffer() { - int byteSize = BUFFER_SIZE; + int byteSize = BUFFER_BYTE_SIZE; byte[] buffer = new byte[byteSize]; try { if (inputStream.read(buffer) < 0) {