diff --git a/frontends/sdl/src/audio.rs b/frontends/sdl/src/audio.rs index 94e897f245a65bd9f2ab95ba469388fd60d81e24..c5c113c0b64aa6b1b465445e5570743a9cefcefc 100644 --- a/frontends/sdl/src/audio.rs +++ b/frontends/sdl/src/audio.rs @@ -14,7 +14,7 @@ impl Audio { let desired_spec = AudioSpecDesired { freq: Some(44100), - channels: Some(1), + channels: Some(2), samples: Some(4096), }; diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts index ff789a00434129d6c274a196cb6d75d70e5843dc..dcde0e67798a246778a73e203c21ef4afb77f7a8 100644 --- a/frontends/web/ts/gb.ts +++ b/frontends/web/ts/gb.ts @@ -518,16 +518,14 @@ export class GameboyEmulator extends EmulatorBase implements Emulator { } get audioBuffer(): Float32Array[] { - const audioBuffer = []; const internalBuffer = this.gameBoy?.audio_buffer_eager(true) ?? []; - for (let channel = 0; channel < 2; channel++) { - const stream = new Float32Array(internalBuffer.length); - for (let index = 0; index < internalBuffer.length; index++) { - stream[index] = internalBuffer[index] / 100.0; - } - audioBuffer.push(stream); + const leftStream = new Float32Array(internalBuffer.length / 2); + const rightStream = new Float32Array(internalBuffer.length / 2); + for (let index = 0; index < internalBuffer.length; index += 2) { + leftStream[index / 2] = internalBuffer[index] / 100.0; + rightStream[index / 2] = internalBuffer[index + 1] / 100.0; } - return audioBuffer; + return [leftStream, rightStream]; } get romInfo(): RomInfo { diff --git a/src/apu.rs b/src/apu.rs index ddbc0c32d81181921d7ad920449a6dc509c5aa8c..8fb3fd7bac5978ae00ab692e312cfee0472ef56a 100644 --- a/src/apu.rs +++ b/src/apu.rs @@ -59,6 +59,9 @@ pub struct Apu { ch3_length_stop: bool, ch3_enabled: bool, + right_enabled: bool, + left_enabled: bool, + wave_ram: [u8; 16], sampling_rate: u16, @@ -70,7 +73,7 @@ pub struct Apu { } impl Apu { - pub fn new(sampling_rate: u16) -> Self { + pub fn new(sampling_rate: u16, buffer_size: f32) -> Self { Self { ch1_timer: 0, ch1_sequence: 0, @@ -114,6 +117,9 @@ impl Apu { ch3_length_stop: false, ch3_enabled: false, + left_enabled: true, + right_enabled: true, + wave_ram: [0u8; 16], sampling_rate, @@ -123,8 +129,10 @@ impl Apu { sequencer: 0, sequencer_step: 0, output_timer: 0, - audio_buffer: VecDeque::with_capacity(sampling_rate as usize), - audio_buffer_max: sampling_rate as usize, + audio_buffer: VecDeque::with_capacity( + (sampling_rate as f32 * buffer_size as f32 * 2.0) as usize, + ), + audio_buffer_max: (sampling_rate as f32 * buffer_size as f32 * 2.0) as usize, } } @@ -171,6 +179,9 @@ impl Apu { self.ch3_length_stop = false; self.ch3_enabled = false; + self.left_enabled = true; + self.right_enabled = true; + self.sequencer = 0; self.sequencer_step = 0; self.output_timer = 0; @@ -342,8 +353,14 @@ impl Apu { // volume item is added to the queue if self.audio_buffer.len() >= self.audio_buffer_max { self.audio_buffer.pop_front(); + self.audio_buffer.pop_front(); + } + if self.left_enabled { + self.audio_buffer.push_back(self.output()); + } + if self.right_enabled { + self.audio_buffer.push_back(self.output()); } - self.audio_buffer.push_back(self.output()); // @TODO the CPU clock is hardcoded here, we must handle situations // where there's some kind of overclock @@ -542,6 +559,6 @@ impl Apu { impl Default for Apu { fn default() -> Self { - Self::new(44100) + Self::new(44100, 1.0) } }