Compare commits
No commits in common. "2af673d7c5eb59a3b8f1804243ce63d8327f5369" and "903cfacad3676071f917ff0aaa2baf1f436146d5" have entirely different histories.
2af673d7c5
...
903cfacad3
11
src/apu.rs
11
src/apu.rs
|
@ -131,11 +131,10 @@ 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;
|
||||||
|
|
||||||
if let Some(ref mut prod) = self.prod {
|
|
||||||
if prod.two_available() {
|
|
||||||
// Sample the APU
|
// Sample the APU
|
||||||
let ch1_amplitude = self.ch1.amplitude();
|
let ch1_amplitude = self.ch1.amplitude();
|
||||||
let ch1_left = self.ctrl.output.ch1_left() as u8 as f32 * ch1_amplitude;
|
let ch1_left = self.ctrl.output.ch1_left() as u8 as f32 * ch1_amplitude;
|
||||||
|
@ -162,12 +161,18 @@ impl Apu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_producer(&mut self, prod: SampleProducer<f32>) {
|
pub fn set_producer(&mut self, prod: SampleProducer<f32>) {
|
||||||
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;
|
||||||
|
|
|
@ -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 BUFFER_CAPACITY: usize = 4096 * CHANNEL_COUNT; // # of samples * the # of channels
|
const AUDIO_BUFFER_LEN: usize = 4096;
|
||||||
|
|
||||||
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(BUFFER_CAPACITY),
|
inner: RingBuffer::new(AUDIO_BUFFER_LEN * CHANNEL_COUNT),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,8 @@ impl<T> SampleProducer<T> {
|
||||||
self.inner.push(value)
|
self.inner.push(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub(crate) fn is_full(&self) -> bool {
|
||||||
pub(crate) fn two_available(&self) -> bool {
|
self.inner.is_full()
|
||||||
self.inner.slots() > 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,10 @@ 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();
|
||||||
|
|
|
@ -117,9 +117,16 @@ 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();
|
||||||
for _ in 0..pending {
|
while elapsed < pending {
|
||||||
|
if !self.bus.apu().is_full() {
|
||||||
self.bus.clock();
|
self.bus.clock();
|
||||||
|
elapsed += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.handle_interrupts();
|
self.handle_interrupts();
|
||||||
|
|
|
@ -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 %= gb::emu::CYCLES_IN_FRAME;
|
cycle_count = Cycle::new(0);
|
||||||
|
|
||||||
gb::emu::draw(game_boy.ppu(), pixels.get_frame());
|
gb::emu::draw(game_boy.ppu(), pixels.get_frame());
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
|
|
Loading…
Reference in New Issue