From 17184e239383b37d2f21665a76aa303d2f8530b1 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 12:12:04 +0100 Subject: [PATCH] fix: issue with global audio memory --- frontends/libretro/src/lib.rs | 43 ++++++++++++++++++++++------------- src/apu.rs | 4 ++++ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/frontends/libretro/src/lib.rs b/frontends/libretro/src/lib.rs index 41bb2110..6a4229d5 100644 --- a/frontends/libretro/src/lib.rs +++ b/frontends/libretro/src/lib.rs @@ -30,6 +30,8 @@ use crate::consts::{REGION_NTSC, RETRO_API_VERSION}; static mut EMULATOR: Option<GameBoy> = None; static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None; static mut FRAME_BUFFER: [u8; FRAME_BUFFER_RGB155_SIZE] = [0x00; FRAME_BUFFER_RGB155_SIZE]; +static mut AUDIO_BUFFER: Option<Vec<i16>> = None; + static mut PENDING_CYCLES: u32 = 0_u32; static mut ENVIRONMENT_CALLBACK: Option<extern "C" fn(u32, *const c_void) -> bool> = None; @@ -187,8 +189,8 @@ pub unsafe extern "C" fn retro_get_system_av_info(info: *mut RetroSystemAvInfo) debugln!("retro_get_system_av_info()"); (*info).geometry.base_width = DISPLAY_WIDTH as u32; (*info).geometry.base_height = DISPLAY_HEIGHT as u32; - (*info).geometry.max_width = DISPLAY_WIDTH as u32; - (*info).geometry.max_height = DISPLAY_HEIGHT as u32; + (*info).geometry.max_width = DISPLAY_WIDTH as u32 * 64; + (*info).geometry.max_height = DISPLAY_HEIGHT as u32 * 64; (*info).geometry.aspect_ratio = DISPLAY_WIDTH as f32 / DISPLAY_HEIGHT as f32; (*info).timing.fps = GameBoy::VISUAL_FREQ as f64; (*info).timing.sample_rate = EMULATOR.as_ref().unwrap().audio_sampling_rate() as f64; @@ -258,20 +260,29 @@ pub extern "C" fn retro_run() { last_frame = emulator.ppu_frame(); } - // 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 - let audio_buffer = emulator - .audio_buffer() - .iter() - .map(|v| *v as i16 * 256) - .collect::<Vec<i16>>(); - - sample_batch_cb( - audio_buffer.as_ptr(), - audio_buffer.len() / channels as usize, - ); - emulator.clear_audio_buffer(); + // 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 + let audio_buffer = emulator + .audio_buffer() + .iter() + .map(|v| *v as i16 * 256) + .collect::<Vec<i16>>(); + + unsafe { + AUDIO_BUFFER = Some(audio_buffer.to_vec()); + let audio_buffer_ref = AUDIO_BUFFER.as_ref().unwrap(); + sample_batch_cb( + audio_buffer_ref.as_ptr(), + audio_buffer_ref.len() / channels as usize, + ); + } + + emulator.clear_audio_buffer(); + } } input_poll_cb(); diff --git a/src/apu.rs b/src/apu.rs index ab739a6d..ff7674e5 100644 --- a/src/apu.rs +++ b/src/apu.rs @@ -749,6 +749,10 @@ impl Apu { self.audio_buffer.clear(); } + pub fn audio_buffer_max(&self) -> usize { + self.audio_buffer_max + } + pub fn clock_freq(&self) -> u32 { self.clock_freq } -- GitLab