mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-24 11:52:52 +00:00
Add high latency audio support for Android.
Should fix ghetto hardware again.
This commit is contained in:
parent
3122dbf4e6
commit
16ca310f93
@ -98,6 +98,12 @@
|
||||
android:summary="Enable dynamic rate control (recommended)."
|
||||
android:title="Dynamic Rate Control"
|
||||
android:dependency="audio_enable" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="audio_high_latency"
|
||||
android:summary="Use (very) high latency audio. Necessary for older Android devices with poor audio drivers."
|
||||
android:title="High latency audio"
|
||||
android:dependency="audio_enable" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen android:title="Input Options" >
|
||||
|
@ -219,6 +219,7 @@ public class CoreSelection extends Activity implements
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||
config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true));
|
||||
config.setInt("audio_out_rate", getOptimalSamplingRate());
|
||||
config.setInt("audio_latency", prefs.getBoolean("audio_high_latency", false) ? 160 : 64);
|
||||
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));
|
||||
|
@ -33,13 +33,10 @@
|
||||
|
||||
#define SLPlayItf_SetPlayState(a, ...) ((*(a))->SetPlayState(a, __VA_ARGS__))
|
||||
|
||||
// TODO: Are these sane?
|
||||
#define BUFFER_SIZE (2 * 1024)
|
||||
#define BUFFER_COUNT 16
|
||||
|
||||
typedef struct sl
|
||||
{
|
||||
uint8_t buffer[BUFFER_COUNT][BUFFER_SIZE];
|
||||
uint8_t **buffer;
|
||||
uint8_t *buffer_chunk;
|
||||
unsigned buffer_index;
|
||||
unsigned buffer_ptr;
|
||||
volatile unsigned buffered_blocks;
|
||||
@ -55,6 +52,7 @@ typedef struct sl
|
||||
slock_t *lock;
|
||||
scond_t *cond;
|
||||
bool nonblock;
|
||||
unsigned buf_size;
|
||||
unsigned buf_count;
|
||||
} sl_t;
|
||||
|
||||
@ -93,6 +91,8 @@ static void sl_free(void *data)
|
||||
if (sl->cond)
|
||||
scond_free(sl->cond);
|
||||
|
||||
free(sl->buffer);
|
||||
free(sl->buffer_chunk);
|
||||
free(sl);
|
||||
}
|
||||
|
||||
@ -122,11 +122,23 @@ 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);
|
||||
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);
|
||||
sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size;
|
||||
|
||||
RARCH_LOG("[SLES] : Setting audio latency (buffer size: [%d]) ...\n", sl->buf_count * BUFFER_SIZE);
|
||||
sl->buffer = (uint8_t**)calloc(sizeof(uint8_t*), sl->buf_count);
|
||||
if (!sl->buffer)
|
||||
goto error;
|
||||
|
||||
sl->buffer_chunk = (uint8_t*)calloc(sl->buf_count, sl->buf_size);
|
||||
if (!sl->buffer_chunk)
|
||||
goto error;
|
||||
|
||||
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",
|
||||
sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count);
|
||||
|
||||
fmt_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
fmt_pcm.numChannels = 2;
|
||||
@ -164,7 +176,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
|
||||
sl->buffered_blocks = sl->buf_count;
|
||||
sl->buffer_index = 0;
|
||||
for (unsigned i = 0; i < sl->buf_count; i++)
|
||||
(*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], BUFFER_SIZE);
|
||||
(*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], sl->buf_size);
|
||||
|
||||
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_PLAY, &sl->player));
|
||||
GOTO_IF_FAIL(SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING));
|
||||
@ -218,7 +230,7 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
|
||||
slock_unlock(sl->lock);
|
||||
}
|
||||
|
||||
size_t avail_write = min(BUFFER_SIZE - sl->buffer_ptr, size);
|
||||
size_t avail_write = min(sl->buf_size - sl->buffer_ptr, size);
|
||||
if (avail_write)
|
||||
{
|
||||
memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write);
|
||||
@ -228,9 +240,9 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
|
||||
written += avail_write;
|
||||
}
|
||||
|
||||
if (sl->buffer_ptr >= BUFFER_SIZE)
|
||||
if (sl->buffer_ptr >= sl->buf_size)
|
||||
{
|
||||
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], BUFFER_SIZE);
|
||||
SLresult res = (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[sl->buffer_index], sl->buf_size);
|
||||
sl->buffer_index = (sl->buffer_index + 1) % sl->buf_count;
|
||||
__sync_fetch_and_add(&sl->buffered_blocks, 1);
|
||||
sl->buffer_ptr = 0;
|
||||
@ -243,22 +255,20 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
//RARCH_LOG("Blocks: %u\n", sl->buffered_blocks);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static size_t sl_write_avail(void *data)
|
||||
{
|
||||
sl_t *sl = (sl_t*)data;
|
||||
size_t avail = (sl->buf_count - (int)sl->buffered_blocks - 1) * BUFFER_SIZE + (BUFFER_SIZE - (int)sl->buffer_ptr);
|
||||
size_t avail = (sl->buf_count - (int)sl->buffered_blocks - 1) * sl->buf_size + (sl->buf_size - (int)sl->buffer_ptr);
|
||||
return avail;
|
||||
}
|
||||
|
||||
static size_t sl_buffer_size(void *data)
|
||||
{
|
||||
sl_t *sl = (sl_t*)data;
|
||||
return BUFFER_SIZE * sl->buf_count;
|
||||
return sl->buf_size * sl->buf_count;
|
||||
}
|
||||
|
||||
static bool sl_use_float(void *data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user