mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
(Switch audren) One lock for the renderer and the buffer state; blocking by default
write_avail() runs on the frontend's thread and brings the wave buffer states up to date with audrvUpdate(); the writer, on the audio thread, adds and starts. Every call into the renderer, and the reads and writes of the wave buffer states and the buffer being filled, are under the one lock, so the voice's buffer list is never rewritten under an add - which lost buffers from the voice with their audio, left them counted free, and took the backpressure with them. The driver is blocking until the frontend says otherwise; it sets non-blocking at init only when audio sync is off. Fixes #19508.
This commit is contained in:
1 parent
db9d54a031
commit
6d0da53215
1 file changed
+22
-11
@@ -52,6 +52,10 @@ typedef struct
|
||||
size_t current_size;
|
||||
size_t buffer_size;
|
||||
size_t samples;
|
||||
/* Held for every call into the renderer and for the wave buffer
|
||||
* states and the buffer being filled: write_avail() reads them on
|
||||
* the frontend's thread while the writer, on the audio thread, adds
|
||||
* and starts. */
|
||||
Mutex update_lock;
|
||||
bool nonblock;
|
||||
} libnx_audren_t;
|
||||
@@ -81,7 +85,9 @@ static void *libnx_audren_audio_init(
|
||||
real_latency = MAX(5, latency);
|
||||
RARCH_LOG("[Audren] real_latency is %u.\n", real_latency);
|
||||
|
||||
aud->nonblock = !block_frames;
|
||||
/* Blocking until the frontend says otherwise: it sets non-blocking
|
||||
* at init only when audio sync is off. */
|
||||
aud->nonblock = false;
|
||||
/* The latency setting is split across the BUFFER_COUNT wave buffers
|
||||
* the renderer plays in turn, so that the buffers together hold the
|
||||
* setting and rate control - which sees the total, below - holds it
|
||||
@@ -181,11 +187,11 @@ fail:
|
||||
static size_t libnx_audren_audio_room(libnx_audren_t *aud)
|
||||
{
|
||||
size_t free_bufs = 0;
|
||||
size_t room;
|
||||
unsigned i;
|
||||
|
||||
mutexLock(&aud->update_lock);
|
||||
audrvUpdate(&aud->drv);
|
||||
mutexUnlock(&aud->update_lock);
|
||||
|
||||
for (i = 0; i < BUFFER_COUNT; i++)
|
||||
if ( aud->wavebufs[i].state == AudioDriverWaveBufState_Free
|
||||
@@ -198,10 +204,13 @@ static size_t libnx_audren_audio_room(libnx_audren_t *aud)
|
||||
{
|
||||
if (free_bufs)
|
||||
free_bufs--;
|
||||
return free_bufs * aud->buffer_size
|
||||
room = free_bufs * aud->buffer_size
|
||||
+ (aud->buffer_size - aud->current_size);
|
||||
}
|
||||
return free_bufs * aud->buffer_size;
|
||||
else
|
||||
room = free_bufs * aud->buffer_size;
|
||||
mutexUnlock(&aud->update_lock);
|
||||
return room;
|
||||
}
|
||||
|
||||
static size_t libnx_audren_audio_buffer_size(void *data)
|
||||
@@ -237,11 +246,15 @@ static size_t libnx_audren_audio_append(
|
||||
void *dstbuf = NULL;
|
||||
ssize_t free_idx = -1;
|
||||
|
||||
mutexLock(&aud->update_lock);
|
||||
if (!aud->current_wavebuf)
|
||||
{
|
||||
free_idx = libnx_audren_audio_get_free_wavebuf_idx(aud);
|
||||
if (free_idx == -1)
|
||||
{
|
||||
mutexUnlock(&aud->update_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
aud->current_wavebuf = &aud->wavebufs[free_idx];
|
||||
aud->current_pool_ptr = aud->mempool + (free_idx * aud->buffer_size);
|
||||
@@ -260,18 +273,12 @@ static size_t libnx_audren_audio_append(
|
||||
if (aud->current_size == aud->buffer_size)
|
||||
{
|
||||
audrvVoiceAddWaveBuf(&aud->drv, 0, aud->current_wavebuf);
|
||||
|
||||
mutexLock(&aud->update_lock);
|
||||
audrvUpdate(&aud->drv);
|
||||
mutexUnlock(&aud->update_lock);
|
||||
|
||||
if (!audrvVoiceIsPlaying(&aud->drv, 0))
|
||||
{
|
||||
audrvVoiceStart(&aud->drv, 0);
|
||||
}
|
||||
|
||||
aud->current_wavebuf = NULL;
|
||||
}
|
||||
mutexUnlock(&aud->update_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -321,7 +328,9 @@ static bool libnx_audren_audio_stop(void *data)
|
||||
if (!aud)
|
||||
return false;
|
||||
|
||||
mutexLock(&aud->update_lock);
|
||||
audrvVoiceStop(&aud->drv, 0);
|
||||
mutexUnlock(&aud->update_lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -334,7 +343,9 @@ static bool libnx_audren_audio_start(void *data, bool is_shutdown)
|
||||
if (!aud)
|
||||
return false;
|
||||
|
||||
mutexLock(&aud->update_lock);
|
||||
audrvVoiceStart(&aud->drv, 0);
|
||||
mutexUnlock(&aud->update_lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user