diff --git a/frontends/sdl/src/audio.rs b/frontends/sdl/src/audio.rs index c5c113c0b64aa6b1b465445e5570743a9cefcefc..5284f5fae7814bf441c0eb248c990b16930a6d1d 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: i32, channels: 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), + channels: Some(channels), + 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 89274d11720ced5bffaf1a25f68d1c44f99573ee..01e3e2cb793fbfc4201826a77a3d3dc701e4845e 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, + self.system.audio_sampling_rate() as i32, + 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 253f83739f00aa6d65b48200de3dd2d014a2b685..f36ccc09396666772a1a992740413250e612452b 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 d072e606d8a053e8c91f239dc5e501d2b355bf46..367ad0ede58c7ace60b2bc7558483e32a3f63310 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 84191d0f22d2fcb27ed1b48a688687f5ea97e22d..130d82b3b799dcff69d79bb61b4d0b8d0685fd50 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 {