fix(apu): don't spin if ringbuf is full

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-07-28 16:23:31 -05:00
parent 8724da824e
commit e43cac8041
4 changed files with 31 additions and 31 deletions

View File

@ -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");
}
}
}
}

View File

@ -47,6 +47,11 @@ impl<T> SampleProducer<T> {
pub(crate) fn is_full(&self) -> bool {
self.inner.is_full()
}
#[inline]
pub(crate) fn two_available(&self) -> bool {
self.inner.slots() > 2
}
}
impl<T> std::fmt::Debug for SampleProducer<T> {

View File

@ -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();

View File

@ -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();