Merge pull request #260 from Themaister/opensl-upstream

Fixes and tweaks for OpenSL
This commit is contained in:
Squarepusher 2013-07-17 15:10:31 -07:00
commit 81125baca4
4 changed files with 50 additions and 33 deletions

View File

@ -11,4 +11,4 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-16
target=android-17

View File

@ -10,6 +10,7 @@ import android.content.res.AssetManager;
import android.annotation.TargetApi;
import android.app.*;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.net.Uri;
import android.os.*;
import android.preference.PreferenceManager;
@ -351,9 +352,27 @@ public class RetroArch extends Activity implements
return "/mnt/sd/retroarch.cfg";
}
@TargetApi(android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
private int getLowLatencyOptimalSamplingRate() {
AudioManager manager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
return Integer.parseInt(manager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
}
private int getOptimalSamplingRate() {
int ret;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
ret = getLowLatencyOptimalSamplingRate();
else
ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
Log.i(TAG, "Using sampling rate: " + ret + " Hz");
return ret;
}
private void updateConfigFile() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true));
config.setInt("audio_out_rate", getOptimalSamplingRate());
config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true));
config.setBoolean("video_smooth", prefs.getBoolean("video_smooth", true));
config.setBoolean("video_allow_rotate", prefs.getBoolean("video_allow_rotate", true));

View File

@ -34,8 +34,8 @@
#define SLPlayItf_SetPlayState(a, ...) ((*(a))->SetPlayState(a, __VA_ARGS__))
// TODO: Are these sane?
#define BUFFER_SIZE 8192
#define BUFFER_COUNT 4
#define BUFFER_SIZE (2 * 1024)
#define BUFFER_COUNT 16
typedef struct sl
{
@ -61,11 +61,7 @@ typedef struct sl
static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *ctx)
{
sl_t *sl = (sl_t*)ctx;
slock_lock(sl->lock);
sl->buffered_blocks--;
slock_unlock(sl->lock);
__sync_fetch_and_sub(&sl->buffered_blocks, 1);
scond_signal(sl->cond);
}
@ -122,18 +118,21 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL));
GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE));
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine));
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_count = BUFFER_COUNT;
sl->buf_count = (latency * 4 * out_rate + 500) / 1000;
sl->buf_count = (sl->buf_count + BUFFER_SIZE / 2) / BUFFER_SIZE;
sl->buf_count = min(sl->buf_count, BUFFER_COUNT);
RARCH_LOG("[SLES] : Setting audio latency (buffer size: [%d])..\n", sl->buf_count * BUFFER_SIZE);
RARCH_LOG("[SLES] : Setting audio latency (buffer size: [%d]) ...\n", sl->buf_count * BUFFER_SIZE);
fmt_pcm.formatType = SL_DATAFORMAT_PCM;
fmt_pcm.numChannels = 2;
fmt_pcm.samplesPerSec = rate * 1000; // Samplerate is in milli-Hz.
fmt_pcm.bitsPerSample = sizeof(int16_t) * 8;
fmt_pcm.containerSize = sizeof(int16_t) * 8;
fmt_pcm.bitsPerSample = 16;
fmt_pcm.containerSize = 16;
fmt_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
fmt_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; // Android only.
@ -153,7 +152,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
1, &id, &req));
GOTO_IF_FAIL(SLObjectItf_Realize(sl->buffer_queue_object, SL_BOOLEAN_FALSE));
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_BUFFERQUEUE,
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&sl->buffer_queue));
sl->cond = scond_new();
@ -162,9 +161,9 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
(*sl->buffer_queue)->RegisterCallback(sl->buffer_queue, opensl_callback, sl);
// Enqueue a bit to get stuff rolling.
sl->buffered_blocks = BUFFER_COUNT;
sl->buffered_blocks = sl->buf_count;
sl->buffer_index = 0;
for (unsigned i = 0; i < BUFFER_COUNT; i++)
for (unsigned i = 0; i < sl->buf_count; i++)
(*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], BUFFER_SIZE);
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_PLAY, &sl->player));
@ -206,21 +205,18 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
while (size)
{
slock_lock(sl->lock);
if (sl->nonblock)
{
if (sl->buffered_blocks == BUFFER_COUNT)
{
slock_unlock(sl->lock);
if (sl->buffered_blocks == sl->buf_count)
break;
}
}
else
{
while (sl->buffered_blocks == BUFFER_COUNT)
slock_lock(sl->lock);
while (sl->buffered_blocks == sl->buf_count)
scond_wait(sl->cond, sl->lock);
slock_unlock(sl->lock);
}
slock_unlock(sl->lock);
size_t avail_write = min(BUFFER_SIZE - sl->buffer_ptr, size);
if (avail_write)
@ -234,12 +230,16 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
if (sl->buffer_ptr >= BUFFER_SIZE)
{
slock_lock(sl->lock);
(*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], BUFFER_SIZE);
sl->buffer_index = (sl->buffer_index + 1) & (BUFFER_COUNT - 1);
sl->buffered_blocks++;
slock_unlock(sl->lock);
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], BUFFER_SIZE);
sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
__sync_fetch_and_add(&sl->buffered_blocks, 1);
sl->buffer_ptr = 0;
if (res != SL_RESULT_SUCCESS)
{
RARCH_ERR("[OpenSL]: Failed to write! (Error: 0x%x)\n", (unsigned)res);
return -1;
}
}
}
@ -251,16 +251,14 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
static size_t sl_write_avail(void *data)
{
sl_t *sl = (sl_t*)data;
slock_lock(sl->lock);
size_t avail = (BUFFER_COUNT - (int)sl->buffered_blocks - 1) * BUFFER_SIZE + (BUFFER_SIZE - (int)sl->buffer_ptr);
slock_unlock(sl->lock);
size_t avail = (sl->buf_count - (int)sl->buffered_blocks - 1) * BUFFER_SIZE + (BUFFER_SIZE - (int)sl->buffer_ptr);
return avail;
}
static size_t sl_buffer_size(void *data)
{
(void)data;
return BUFFER_SIZE * BUFFER_COUNT;
sl_t *sl = (sl_t*)data;
return BUFFER_SIZE * sl->buf_count;
}
const audio_driver_t audio_opensl = {

View File

@ -313,7 +313,7 @@ static const bool allow_rotate = true;
static const bool audio_enable = true;
// Output samplerate
static const unsigned out_rate = 48000;
static const unsigned out_rate = 48000;
// Audio device (e.g. hw:0,0 or /dev/audio). If NULL, will use defaults.
static const char *audio_device = NULL;