Compare commits

...

3 Commits

Author SHA1 Message Date
Rekai Nyangadzayi Musuka 2af673d7c5 chore: remove various warnings
continuous-integration/drone/push Build is passing Details
2021-07-28 16:25:29 -05:00
Rekai Nyangadzayi Musuka e43cac8041 fix(apu): don't spin if ringbuf is full 2021-07-28 16:23:31 -05:00
Rekai Nyangadzayi Musuka 8724da824e chore: inline some methods 2021-07-28 14:53:52 -05:00
5 changed files with 31 additions and 46 deletions

View File

@ -131,33 +131,35 @@ impl Apu {
self.div_prev = Some(bit_5); self.div_prev = Some(bit_5);
if let Some(ref mut prod) = self.prod { if self.sample_counter >= SM83_CLOCK_SPEED {
if self.sample_counter >= SM83_CLOCK_SPEED { self.sample_counter %= SM83_CLOCK_SPEED;
self.sample_counter %= SM83_CLOCK_SPEED;
// Sample the APU if let Some(ref mut prod) = self.prod {
let ch1_amplitude = self.ch1.amplitude(); if prod.two_available() {
let ch1_left = self.ctrl.output.ch1_left() as u8 as f32 * ch1_amplitude; // Sample the APU
let ch1_right = self.ctrl.output.ch1_right() as u8 as f32 * ch1_amplitude; 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_amplitude = self.ch2.amplitude();
let ch2_left = self.ctrl.output.ch2_left() as u8 as f32 * 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_right = self.ctrl.output.ch2_right() as u8 as f32 * ch2_amplitude;
let ch3_amplitude = self.ch3.amplitude(); let ch3_amplitude = self.ch3.amplitude();
let ch3_left = self.ctrl.output.ch3_left() as u8 as f32 * 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_right = self.ctrl.output.ch3_right() as u8 as f32 * ch3_amplitude;
let ch4_amplitude = self.ch4.amplitude(); let ch4_amplitude = self.ch4.amplitude();
let ch4_left = self.ctrl.output.ch4_left() as u8 as f32 * 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_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 left = (ch1_left + ch2_left + ch3_left + ch4_left) / 4.0;
let right = (ch1_right + ch2_right + ch3_right + ch4_right) / 4.0; let right = (ch1_right + ch2_right + ch3_right + ch4_right) / 4.0;
prod.push(left) prod.push(left)
.and(prod.push(right)) .and(prod.push(right))
.expect("Add samples to ring buffer"); .expect("Add samples to ring buffer");
}
} }
} }
} }
@ -166,13 +168,6 @@ impl Apu {
self.prod = Some(prod); self.prod = Some(prod);
} }
pub(crate) fn is_full(&self) -> bool {
match self.prod.as_ref() {
Some(prod) => prod.is_full(),
None => false,
}
}
/// 0xFF26 | NR52 - Sound On/Off /// 0xFF26 | NR52 - Sound On/Off
pub(crate) fn set_status(&mut self, byte: u8) { pub(crate) fn set_status(&mut self, byte: u8) {
self.ctrl.enabled = (byte >> 7) & 0x01 == 0x01; self.ctrl.enabled = (byte >> 7) & 0x01 == 0x01;

View File

@ -3,7 +3,7 @@ use rtrb::{Consumer, Producer, PushError, RingBuffer};
pub(crate) const SAMPLE_RATE: u32 = 48000; // Hz pub(crate) const SAMPLE_RATE: u32 = 48000; // Hz
const CHANNEL_COUNT: usize = 2; const CHANNEL_COUNT: usize = 2;
const AUDIO_BUFFER_LEN: usize = 4096; const BUFFER_CAPACITY: usize = 4096 * CHANNEL_COUNT; // # of samples * the # of channels
pub struct AudioSPSC<T> { pub struct AudioSPSC<T> {
inner: RingBuffer<T>, inner: RingBuffer<T>,
@ -12,7 +12,7 @@ pub struct AudioSPSC<T> {
impl<T> Default for AudioSPSC<T> { impl<T> Default for AudioSPSC<T> {
fn default() -> Self { fn default() -> Self {
Self { Self {
inner: RingBuffer::new(AUDIO_BUFFER_LEN * CHANNEL_COUNT), inner: RingBuffer::new(BUFFER_CAPACITY),
} }
} }
} }
@ -43,8 +43,9 @@ impl<T> SampleProducer<T> {
self.inner.push(value) self.inner.push(value)
} }
pub(crate) fn is_full(&self) -> bool { #[inline]
self.inner.is_full() pub(crate) fn two_available(&self) -> bool {
self.inner.slots() > 2
} }
} }

View File

@ -66,10 +66,6 @@ impl Bus {
self.cartridge.as_ref()?.title() self.cartridge.as_ref()?.title()
} }
pub(crate) fn apu(&self) -> &Apu {
&self.apu
}
pub(crate) fn clock(&mut self) { pub(crate) fn clock(&mut self) {
self.ppu.clock(); self.ppu.clock();
self.timer.clock(); self.timer.clock();

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(); let pending: u32 = cycles.into();
while elapsed < pending { for _ in 0..pending {
if !self.bus.apu().is_full() { self.bus.clock();
self.bus.clock();
elapsed += 1;
}
} }
self.handle_interrupts(); self.handle_interrupts();

View File

@ -112,7 +112,7 @@ fn main() -> Result<()> {
if cycle_count >= gb::emu::CYCLES_IN_FRAME { if cycle_count >= gb::emu::CYCLES_IN_FRAME {
// Draw Frame // Draw Frame
cycle_count = Cycle::new(0); cycle_count %= gb::emu::CYCLES_IN_FRAME;
gb::emu::draw(game_boy.ppu(), pixels.get_frame()); gb::emu::draw(game_boy.ppu(), pixels.get_frame());
window.request_redraw(); window.request_redraw();