mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Merge pull request #21883 from MarkrPearce96/upstream-pr-audio-thread-safety
libretro: fix audio buffer data race and >1024-frame sample pushes
This commit is contained in:
@@ -73,6 +73,12 @@ static struct {
|
|||||||
int32_t size;
|
int32_t size;
|
||||||
int32_t capacity;
|
int32_t capacity;
|
||||||
} output_audio_buffer = {NULL, 0, 0};
|
} output_audio_buffer = {NULL, 0, 0};
|
||||||
|
// output_audio_buffer is filled by System_AudioPushSamples() on the emu
|
||||||
|
// thread (used with the GL backends, where PSP-side audio pushes arrive
|
||||||
|
// via the GL command queue) and drained + realloc'd on the libretro
|
||||||
|
// thread in retro_run()/init/shutdown — every access must hold this
|
||||||
|
// mutex or a realloc can free the pointer mid-read on the other thread.
|
||||||
|
static std::mutex output_audio_buffer_mutex;
|
||||||
|
|
||||||
// Calculated swap interval is 'stable' if the same
|
// Calculated swap interval is 'stable' if the same
|
||||||
// value is recorded for a number of retro_run()
|
// value is recorded for a number of retro_run()
|
||||||
@@ -123,6 +129,7 @@ namespace Libretro
|
|||||||
static float runSpeed = 0.0f;
|
static float runSpeed = 0.0f;
|
||||||
static s64 runTicksLast = 0;
|
static s64 runTicksLast = 0;
|
||||||
|
|
||||||
|
// Must be called with output_audio_buffer_mutex held.
|
||||||
static void ensure_output_audio_buffer_capacity(int32_t capacity)
|
static void ensure_output_audio_buffer_capacity(int32_t capacity)
|
||||||
{
|
{
|
||||||
if (capacity <= output_audio_buffer.capacity) {
|
if (capacity <= output_audio_buffer.capacity) {
|
||||||
@@ -136,6 +143,7 @@ namespace Libretro
|
|||||||
|
|
||||||
static void init_output_audio_buffer(int32_t capacity)
|
static void init_output_audio_buffer(int32_t capacity)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(output_audio_buffer_mutex);
|
||||||
output_audio_buffer.data = NULL;
|
output_audio_buffer.data = NULL;
|
||||||
output_audio_buffer.size = 0;
|
output_audio_buffer.size = 0;
|
||||||
output_audio_buffer.capacity = 0;
|
output_audio_buffer.capacity = 0;
|
||||||
@@ -144,6 +152,7 @@ namespace Libretro
|
|||||||
|
|
||||||
static void free_output_audio_buffer()
|
static void free_output_audio_buffer()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(output_audio_buffer_mutex);
|
||||||
free(output_audio_buffer.data);
|
free(output_audio_buffer.data);
|
||||||
output_audio_buffer.data = NULL;
|
output_audio_buffer.data = NULL;
|
||||||
output_audio_buffer.size = 0;
|
output_audio_buffer.size = 0;
|
||||||
@@ -152,6 +161,7 @@ namespace Libretro
|
|||||||
|
|
||||||
static void upload_output_audio_buffer()
|
static void upload_output_audio_buffer()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(output_audio_buffer_mutex);
|
||||||
audio_batch_cb(output_audio_buffer.data, output_audio_buffer.size / 2);
|
audio_batch_cb(output_audio_buffer.data, output_audio_buffer.size / 2);
|
||||||
output_audio_buffer.size = 0;
|
output_audio_buffer.size = 0;
|
||||||
}
|
}
|
||||||
@@ -2022,6 +2032,8 @@ inline int16_t Clamp16(int32_t sample) {
|
|||||||
void System_AudioPushSamples(const int32_t *audio, int numSamples, float volume) {
|
void System_AudioPushSamples(const int32_t *audio, int numSamples, float volume) {
|
||||||
// We ignore volume here, because it's handled by libretro presumably.
|
// We ignore volume here, because it's handled by libretro presumably.
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(output_audio_buffer_mutex);
|
||||||
|
|
||||||
// Convert to 16-bit audio for further processing.
|
// Convert to 16-bit audio for further processing.
|
||||||
int16_t buffer[1024 * 2];
|
int16_t buffer[1024 * 2];
|
||||||
int origSamples = numSamples * 2;
|
int origSamples = numSamples * 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user