From 73cb5666207707c175cdbebab5ae16c4d350ad60 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 24 Aug 2013 12:04:47 +0200 Subject: [PATCH] "Revert" audio buffer behavior on Android. Add audio_block_frames setting (only used by OpenSL atm). --- .../retroarch/browser/MainMenuActivity.java | 38 ++++++++++++------- audio/opensl.c | 10 +++-- general.h | 1 + settings.c | 2 + 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java index 1a9fe970f7..296f9d90be 100644 --- a/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java +++ b/android/phoenix/src/org/retroarch/browser/MainMenuActivity.java @@ -11,6 +11,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.media.AudioManager; @@ -157,7 +158,7 @@ public class MainMenuActivity extends PreferenceActivity { @TargetApi(17) public static int getLowLatencyOptimalSamplingRate() { - AudioManager manager = (AudioManager) MainMenuActivity.getInstance() + AudioManager manager = (AudioManager) getInstance() .getApplicationContext() .getSystemService(Context.AUDIO_SERVICE); return Integer.parseInt(manager @@ -166,15 +167,20 @@ public class MainMenuActivity extends PreferenceActivity { @TargetApi(17) public static int getLowLatencyBufferSize() { - AudioManager manager = (AudioManager) MainMenuActivity.getInstance() + AudioManager manager = (AudioManager) getInstance() .getApplicationContext() .getSystemService(Context.AUDIO_SERVICE); int buffersize = Integer.parseInt(manager .getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); - - Log.i(TAG, "Queried ideal buffer size: " + buffersize); + Log.i(TAG, "Queried ideal buffer size (frames): " + buffersize); return buffersize; } + + @TargetApi(17) + public static boolean hasLowLatencyAudio() { + PackageManager pm = getInstance().getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY); + } public static int getOptimalSamplingRate() { int ret; @@ -261,21 +267,25 @@ public class MainMenuActivity extends PreferenceActivity { prefs.getBoolean("global_config_enable", true)); config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true)); - config.setInt("audio_out_rate", - MainMenuActivity.getOptimalSamplingRate()); - int buffersize = 0; + int optimalRate = getOptimalSamplingRate(); + config.setInt("audio_out_rate", optimalRate); if (android.os.Build.VERSION.SDK_INT >= 17) { - buffersize = getLowLatencyBufferSize(); - if (config.getBoolean("audio_high_latency") == false) { - config.setInt("audio_latency", buffersize / 32); + int buffersize = getLowLatencyBufferSize(); + + boolean lowLatency = hasLowLatencyAudio(); + Log.i(TAG, "Audio is low latency: " + (lowLatency ? "yes" : "no")); + + if (lowLatency && !prefs.getBoolean("audio_high_latency", false)) { + config.setInt("audio_latency", 64); + config.setInt("audio_block_frames", buffersize); } else { - config.setInt("audio_latency", - prefs.getBoolean("audio_high_latency", false) ? 160 : 64); + config.setInt("audio_latency", prefs.getBoolean( + "audio_high_latency", false) ? 160 : 64); + config.setInt("audio_block_frames", 0); } - } - else { + } else { config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64); } diff --git a/audio/opensl.c b/audio/opensl.c index 06362baab9..beffc5456b 100644 --- a/audio/opensl.c +++ b/audio/opensl.c @@ -115,7 +115,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) if (!sl) goto error; - RARCH_LOG("[SLES ] : Requested audio latency: %dms...", latency); + RARCH_LOG("[SLES]: Requested audio latency: %d ms.", latency); GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE)); @@ -124,7 +124,11 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE)); - sl->buf_size = next_pow2(32 * latency); + if (g_settings.audio.block_frames) + sl->buf_size = g_settings.audio.block_frames * 4; + else + sl->buf_size = next_pow2(32 * latency); + sl->buf_count = (latency * 4 * out_rate + 500) / 1000; sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size; @@ -139,7 +143,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) for (unsigned i = 0; i < sl->buf_count; i++) sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size; - RARCH_LOG("[SLES] : Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n", + RARCH_LOG("[SLES]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n", sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count); fmt_pcm.formatType = SL_DATAFORMAT_PCM; diff --git a/general.h b/general.h index 702b8928f8..85a97eeb4c 100644 --- a/general.h +++ b/general.h @@ -201,6 +201,7 @@ struct settings char driver[32]; bool enable; unsigned out_rate; + unsigned block_frames; float in_rate; char device[PATH_MAX]; unsigned latency; diff --git a/settings.c b/settings.c index 4b9dd32237..8a9563e2e5 100644 --- a/settings.c +++ b/settings.c @@ -196,6 +196,7 @@ void config_set_defaults(void) g_settings.audio.enable = audio_enable; g_settings.audio.out_rate = out_rate; + g_settings.audio.block_frames = 0; g_settings.audio.in_rate = out_rate; if (audio_device) strlcpy(g_settings.audio.device, audio_device, sizeof(g_settings.audio.device)); @@ -628,6 +629,7 @@ bool config_load_file(const char *path) // Audio settings. CONFIG_GET_BOOL(audio.enable, "audio_enable"); CONFIG_GET_INT(audio.out_rate, "audio_out_rate"); + CONFIG_GET_INT(audio.block_frames, "audio_block_frames"); CONFIG_GET_STRING(audio.device, "audio_device"); CONFIG_GET_INT(audio.latency, "audio_latency"); CONFIG_GET_BOOL(audio.sync, "audio_sync");