From 1aae3b6e244f8f8848278680ae1c40edd4755e93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Thu, 3 Aug 2023 23:00:59 +0000
Subject: [PATCH] Fix Linux issue with libretro audio

---
 frontends/libretro/src/lib.rs | 13 +++----------
 frontends/sdl/src/main.rs     | 17 +----------------
 2 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/frontends/libretro/src/lib.rs b/frontends/libretro/src/lib.rs
index 3d4fc311..15ef7333 100644
--- a/frontends/libretro/src/lib.rs
+++ b/frontends/libretro/src/lib.rs
@@ -219,7 +219,7 @@ pub extern "C" fn retro_set_controller_port_device() {
 pub extern "C" fn retro_run() {
     let emulator = unsafe { EMULATOR.as_mut().unwrap() };
     let video_refresh_cb = unsafe { VIDEO_REFRESH_CALLBACK.as_ref().unwrap() };
-    let sample_cb = unsafe { AUDIO_SAMPLE_CALLBACK.as_ref().unwrap() };
+    let sample_batch_cb = unsafe { AUDIO_SAMPLE_BATCH_CALLBACK.as_ref().unwrap() };
     let input_poll_cb = unsafe { INPUT_POLL_CALLBACK.as_ref().unwrap() };
     let input_state_cb = unsafe { INPUT_STATE_CALLBACK.as_ref().unwrap() };
     let key_states = unsafe { KEY_STATES.as_mut().unwrap() };
@@ -265,20 +265,13 @@ pub extern "C" fn retro_run() {
 
         // in case there's new audio data available in the emulator
         // we must handle it by sending it to the audio callback
-        if !emulator.audio_buffer().is_empty() {
-            // obtains the audio buffer reference and queues it
-            // in a batch manner using the audio callback at the
-            // the end of the operation clears the buffer
+        if emulator.audio_buffer().len() >= 64 {
             let audio_buffer = emulator
                 .audio_buffer()
                 .iter()
                 .map(|v| *v as i16 * 256)
                 .collect::<Vec<i16>>();
-
-            for chunk in audio_buffer.chunks_exact(2) {
-                sample_cb(chunk[0], chunk[1]);
-            }
-
+            sample_batch_cb(audio_buffer.as_ptr(), audio_buffer.len() / 2_usize);
             emulator.clear_audio_buffer();
         }
     }
diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs
index 5e562880..9218a762 100644
--- a/frontends/sdl/src/main.rs
+++ b/frontends/sdl/src/main.rs
@@ -474,7 +474,7 @@ impl Emulator {
 
                     // in case there's new significant new audio data available in
                     // the emulator we must handle it, sending it to the audio callback
-                    if self.system.audio_buffer().len() > self.max_audio_buffer as usize {
+                    if self.system.audio_buffer().len() >= self.max_audio_buffer as usize {
                         if let Some(audio) = self.audio.as_mut() {
                             let audio_buffer = self
                                 .system
@@ -488,21 +488,6 @@ impl Emulator {
                     }
                 }
 
-                // in case there's pending audio data available in the emulator
-                // we must handle it, sending it to the audio callback
-                if self.system.audio_buffer().is_empty() {
-                    if let Some(audio) = self.audio.as_mut() {
-                        let audio_buffer = self
-                            .system
-                            .audio_buffer()
-                            .iter()
-                            .map(|v| *v as f32 / VOLUME)
-                            .collect::<Vec<f32>>();
-                        audio.device.queue_audio(&audio_buffer).unwrap();
-                    }
-                    self.system.clear_audio_buffer();
-                }
-
                 // in case there's at least one new frame that was drawn during
                 // during the current tick, then we need to flush it to the canvas,
                 // this separation between texture creation and canvas flush prevents
-- 
GitLab