diff --git a/src/apu.rs b/src/apu.rs index b1eacc4..2afceb9 100644 --- a/src/apu.rs +++ b/src/apu.rs @@ -131,33 +131,35 @@ impl Apu { self.div_prev = Some(bit_5); - if let Some(ref mut prod) = self.prod { - if self.sample_counter >= SM83_CLOCK_SPEED { - self.sample_counter %= SM83_CLOCK_SPEED; + if self.sample_counter >= SM83_CLOCK_SPEED { + self.sample_counter %= SM83_CLOCK_SPEED; - // Sample the APU - let ch1_amplitude = self.ch1.amplitude(); - let ch1_left = self.ctrl.output.ch1_left() as u8 as f32 * ch1_amplitude; - let ch1_right = self.ctrl.output.ch1_right() as u8 as f32 * ch1_amplitude; + if let Some(ref mut prod) = self.prod { + if prod.two_available() { + // Sample the APU + let ch1_amplitude = self.ch1.amplitude(); + let ch1_left = self.ctrl.output.ch1_left() as u8 as f32 * ch1_amplitude; + let ch1_right = self.ctrl.output.ch1_right() as u8 as f32 * ch1_amplitude; - let ch2_amplitude = self.ch2.amplitude(); - let ch2_left = self.ctrl.output.ch2_left() as u8 as f32 * ch2_amplitude; - let ch2_right = self.ctrl.output.ch2_right() as u8 as f32 * ch2_amplitude; + let ch2_amplitude = self.ch2.amplitude(); + let ch2_left = self.ctrl.output.ch2_left() as u8 as f32 * ch2_amplitude; + let ch2_right = self.ctrl.output.ch2_right() as u8 as f32 * ch2_amplitude; - let ch3_amplitude = self.ch3.amplitude(); - let ch3_left = self.ctrl.output.ch3_left() as u8 as f32 * ch3_amplitude; - let ch3_right = self.ctrl.output.ch3_right() as u8 as f32 * ch3_amplitude; + let ch3_amplitude = self.ch3.amplitude(); + let ch3_left = self.ctrl.output.ch3_left() as u8 as f32 * ch3_amplitude; + let ch3_right = self.ctrl.output.ch3_right() as u8 as f32 * ch3_amplitude; - let ch4_amplitude = self.ch4.amplitude(); - let ch4_left = self.ctrl.output.ch4_left() as u8 as f32 * ch4_amplitude; - let ch4_right = self.ctrl.output.ch4_right() as u8 as f32 * ch4_amplitude; + let ch4_amplitude = self.ch4.amplitude(); + let ch4_left = self.ctrl.output.ch4_left() as u8 as f32 * ch4_amplitude; + let ch4_right = self.ctrl.output.ch4_right() as u8 as f32 * ch4_amplitude; - let left = (ch1_left + ch2_left + ch3_left + ch4_left) / 4.0; - let right = (ch1_right + ch2_right + ch3_right + ch4_right) / 4.0; + let left = (ch1_left + ch2_left + ch3_left + ch4_left) / 4.0; + let right = (ch1_right + ch2_right + ch3_right + ch4_right) / 4.0; - prod.push(left) - .and(prod.push(right)) - .expect("Add samples to ring buffer"); + prod.push(left) + .and(prod.push(right)) + .expect("Add samples to ring buffer"); + } } } } diff --git a/src/apu/gen.rs b/src/apu/gen.rs index 2ab21bf..a180565 100644 --- a/src/apu/gen.rs +++ b/src/apu/gen.rs @@ -47,6 +47,11 @@ impl SampleProducer { pub(crate) fn is_full(&self) -> bool { self.inner.is_full() } + + #[inline] + pub(crate) fn two_available(&self) -> bool { + self.inner.slots() > 2 + } } impl std::fmt::Debug for SampleProducer { diff --git a/src/cpu.rs b/src/cpu.rs index 2810f38..ad15da7 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -117,16 +117,9 @@ impl Cpu { } }; - // TODO: With how we currently handle audio - // this --while being correct-- incurs a performance penalty - // as our emu is audio-bound. - let mut elapsed = 0x00; let pending: u32 = cycles.into(); - while elapsed < pending { - if !self.bus.apu().is_full() { - self.bus.clock(); - elapsed += 1; - } + for _ in 0..pending { + self.bus.clock(); } self.handle_interrupts(); diff --git a/src/main.rs b/src/main.rs index 9f7df3d..2fea7cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -112,7 +112,7 @@ fn main() -> Result<()> { if cycle_count >= gb::emu::CYCLES_IN_FRAME { // Draw Frame - cycle_count = Cycle::new(0); + cycle_count %= gb::emu::CYCLES_IN_FRAME; gb::emu::draw(game_boy.ppu(), pixels.get_frame()); window.request_redraw();