From f99d3dbd5ccd80bcd071cf49e689f6b6724df499 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 6 Jun 2024 15:38:41 +0200 Subject: Android: Ask system for optimal audio buffer size and sample rate This can reduce audio latency according to https://developer.android.com/ndk/guides/audio/opensl/opensl-prog-notes#perform. Previously we were using the hardcoded values of 48000 Hz and 256 frames per buffer. The sample rate we use with this change is 48000 Hz on all devices I'm aware of, but the buffer size does vary across devices. Terminology note: The old code used the term "sample" to refer to what Android refers to as a "frame". "Frame" is a clearer term to use for this, so I've changed OpenSLESStream's terminology. One frame consists of one sample per channel. --- .../org/dolphinemu/dolphinemu/utils/AudioUtils.kt | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AudioUtils.kt (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AudioUtils.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AudioUtils.kt new file mode 100644 index 0000000000..68e3573fa5 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AudioUtils.kt @@ -0,0 +1,28 @@ +package org.dolphinemu.dolphinemu.utils + +import android.content.Context +import android.media.AudioManager +import androidx.annotation.Keep +import org.dolphinemu.dolphinemu.DolphinApplication + +object AudioUtils { + @JvmStatic @Keep + fun getSampleRate(): Int = + getAudioServiceProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE, 48000) + + @JvmStatic @Keep + fun getFramesPerBuffer(): Int = + getAudioServiceProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER, 256) + + private fun getAudioServiceProperty(property: String, fallback: Int): Int { + return try { + val context = DolphinApplication.getAppContext() + val am = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager + Integer.parseUnsignedInt(am.getProperty(property)) + } catch (e: NullPointerException) { + fallback + } catch (e: NumberFormatException) { + fallback + } + } +} -- cgit v1.2.3