From c81ead8a08caf65fe2a27384693a9f3bfadece11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Mon, 24 Jul 2023 16:41:15 +0100 Subject: [PATCH] chore: dynamic sampling rate --- frontends/sdl/src/audio.rs | 8 ++++---- frontends/sdl/src/main.rs | 7 ++++++- frontends/web/ts/gb.ts | 4 ++-- src/apu.rs | 30 ++++++++++++++++++++---------- src/gb.rs | 32 ++++++++++++++++++++------------ 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/frontends/sdl/src/audio.rs b/frontends/sdl/src/audio.rs index c5c113c0..8b628d04 100644 --- a/frontends/sdl/src/audio.rs +++ b/frontends/sdl/src/audio.rs @@ -9,13 +9,13 @@ pub struct Audio { } impl Audio { - pub fn new(sdl: &Sdl) -> Self { + pub fn new(sdl: &Sdl, freq: Option<i32>, channels: Option<u8>, samples: Option<u16>) -> Self { let audio_subsystem = sdl.audio().unwrap(); let desired_spec = AudioSpecDesired { - freq: Some(44100), - channels: Some(2), - samples: Some(4096), + freq: Some(freq.unwrap_or(44100)), + channels: Some(channels.unwrap_or(2)), + samples: Some(samples.unwrap_or(4096)), }; // creates the queue that is going to be used to update the diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs index 89274d11..72afac1c 100644 --- a/frontends/sdl/src/main.rs +++ b/frontends/sdl/src/main.rs @@ -205,7 +205,12 @@ impl Emulator { } pub fn start_audio(&mut self, sdl: &Sdl) { - self.audio = Some(Audio::new(sdl)); + self.audio = Some(Audio::new( + sdl, + Some(self.system.audio_sampling_rate() as i32), + Some(self.system.audio_channels()), + None, + )); } pub fn load_rom(&mut self, path: Option<&str>) { diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts index 253f8373..f36ccc09 100644 --- a/frontends/web/ts/gb.ts +++ b/frontends/web/ts/gb.ts @@ -606,8 +606,8 @@ export class GameboyEmulator extends EmulatorBase implements Emulator { get audioSpecs(): AudioSpecs { return { - samplingRate: 44100, - channels: 2 + samplingRate: this.gameBoy?.audio_sampling_rate() ?? 44100, + channels: this.gameBoy?.audio_channels() ?? 2 }; } diff --git a/src/apu.rs b/src/apu.rs index d072e606..367ad0ed 100644 --- a/src/apu.rs +++ b/src/apu.rs @@ -2,6 +2,8 @@ use std::collections::VecDeque; use crate::{gb::GameBoy, warnln}; +const CHANNELS: u8 = 2; + const DUTY_TABLE: [[u8; 8]; 4] = [ [0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 1], @@ -194,9 +196,9 @@ impl Apu { sequencer_step: 0, output_timer: 0, audio_buffer: VecDeque::with_capacity( - (sampling_rate as f32 * buffer_size) as usize * 2, + (sampling_rate as f32 * buffer_size) as usize * CHANNELS as usize, ), - audio_buffer_max: (sampling_rate as f32 * buffer_size) as usize * 2, + audio_buffer_max: (sampling_rate as f32 * buffer_size) as usize * CHANNELS as usize, clock_freq, } } @@ -690,38 +692,46 @@ impl Apu { } } - pub fn ch1_enabled(&mut self) -> bool { + pub fn ch1_out_enabled(&self) -> bool { self.ch1_out_enabled } - pub fn set_ch1_enabled(&mut self, enabled: bool) { + pub fn set_ch1_out_enabled(&mut self, enabled: bool) { self.ch1_out_enabled = enabled; } - pub fn ch2_enabled(&mut self) -> bool { + pub fn ch2_out_enabled(&self) -> bool { self.ch2_out_enabled } - pub fn set_ch2_enabled(&mut self, enabled: bool) { + pub fn set_ch2_out_enabled(&mut self, enabled: bool) { self.ch2_out_enabled = enabled; } - pub fn ch3_enabled(&mut self) -> bool { + pub fn ch3_out_enabled(&self) -> bool { self.ch3_out_enabled } - pub fn set_ch3_enabled(&mut self, enabled: bool) { + pub fn set_ch3_out_enabled(&mut self, enabled: bool) { self.ch3_out_enabled = enabled; } - pub fn ch4_enabled(&mut self) -> bool { + pub fn ch4_out_enabled(&self) -> bool { self.ch4_out_enabled } - pub fn set_ch4_enabled(&mut self, enabled: bool) { + pub fn set_ch4_out_enabled(&mut self, enabled: bool) { self.ch4_out_enabled = enabled; } + pub fn sampling_rate(&self) -> u16 { + self.sampling_rate + } + + pub fn channels(&self) -> u8 { + CHANNELS + } + pub fn audio_buffer(&self) -> &VecDeque<u8> { &self.audio_buffer } diff --git a/src/gb.rs b/src/gb.rs index 84191d0f..130d82b3 100644 --- a/src/gb.rs +++ b/src/gb.rs @@ -601,36 +601,44 @@ impl GameBoy { self.apu_i().ch4_output() } - pub fn audio_ch1_enabled(&mut self) -> bool { - self.apu().ch2_enabled() + pub fn audio_ch1_enabled(&self) -> bool { + self.apu_i().ch2_out_enabled() } pub fn set_audio_ch1_enabled(&mut self, enabled: bool) { - self.apu().set_ch1_enabled(enabled) + self.apu().set_ch1_out_enabled(enabled) } - pub fn audio_ch2_enabled(&mut self) -> bool { - self.apu().ch2_enabled() + pub fn audio_ch2_enabled(&self) -> bool { + self.apu_i().ch2_out_enabled() } pub fn set_audio_ch2_enabled(&mut self, enabled: bool) { - self.apu().set_ch2_enabled(enabled) + self.apu().set_ch2_out_enabled(enabled) } - pub fn audio_ch3_enabled(&mut self) -> bool { - self.apu().ch3_enabled() + pub fn audio_ch3_enabled(&self) -> bool { + self.apu_i().ch3_out_enabled() } pub fn set_audio_ch3_enabled(&mut self, enabled: bool) { - self.apu().set_ch3_enabled(enabled) + self.apu().set_ch3_out_enabled(enabled) } - pub fn audio_ch4_enabled(&mut self) -> bool { - self.apu().ch4_enabled() + pub fn audio_ch4_enabled(&self) -> bool { + self.apu_i().ch4_out_enabled() } pub fn set_audio_ch4_enabled(&mut self, enabled: bool) { - self.apu().set_ch4_enabled(enabled) + self.apu().set_ch4_out_enabled(enabled) + } + + pub fn audio_sampling_rate(&self) -> u16 { + self.apu_i().sampling_rate() + } + + pub fn audio_channels(&self) -> u8 { + self.apu_i().channels() } pub fn cartridge_eager(&mut self) -> Cartridge { -- GitLab