diff --git a/src/apu.rs b/src/apu.rs index 9c76f76..6bafde4 100644 --- a/src/apu.rs +++ b/src/apu.rs @@ -5,7 +5,7 @@ use types::ch1::{Sweep, SweepDirection}; use types::ch3::Volume as Ch3Volume; use types::ch4::{CounterWidth, Frequency as Ch4Frequency, PolynomialCounter}; use types::common::{EnvelopeDirection, FrequencyHigh, SoundDuty, VolumeEnvelope}; -use types::fs::{FrameSequencer, FrameSequencerState}; +use types::fs::{FrameSequencer, State as FrameSequencerState}; use types::{ChannelControl, SoundOutput}; pub mod gen; @@ -98,16 +98,16 @@ impl Apu { self.sample_counter += SAMPLE_INCREMENT; // Frame Sequencer (512Hz) - if self.falling_edge(12, div) { + if self.is_falling_edge(12, div) { use FrameSequencerState::*; match self.sequencer.state() { - Length => self.handle_length(), + Length => self.clock_length(), LengthAndSweep => { - self.handle_length(); - self.handle_sweep(); + self.clock_length(); + self.clock_sweep(); } - Envelope => self.handle_envelope(), + Envelope => self.clock_envelope(), Nothing => {} } @@ -116,16 +116,16 @@ impl Apu { self.div_prev = Some(div); - self.ch1.clock(); - self.ch2.clock(); - self.ch3.clock(); - self.ch4.clock(); + self.ch1.tick(); + self.ch2.tick(); + self.ch3.tick(); + self.ch4.tick(); if self.sample_counter >= SM83_CLOCK_SPEED { self.sample_counter %= SM83_CLOCK_SPEED; if let Some(ref mut prod) = self.prod { - if prod.available_block() { + if prod.available_blocking() { // Sample the APU let ch1_amplitude = self.ch1.amplitude(); let ch1_left = self.ctrl.output.ch1_left() as u8 as f32 * ch1_amplitude; @@ -157,10 +157,6 @@ impl Apu { } } - pub fn set_producer(&mut self, prod: SampleProducer) { - self.prod = Some(prod); - } - /// 0xFF26 | NR52 - Sound On/Off pub(crate) fn set_status(&mut self, byte: u8) { self.ctrl.enabled = (byte >> 7) & 0x01 == 0x01; @@ -183,6 +179,10 @@ impl Apu { } } + pub fn attach_producer(&mut self, prod: SampleProducer) { + self.prod = Some(prod); + } + fn reset(&mut self) { self.ch1.sweep = Default::default(); self.ch1.duty = Default::default(); @@ -216,7 +216,7 @@ impl Apu { self.ch4.enabled = Default::default(); } - fn clock_length(freq_hi: &FrequencyHigh, length_timer: &mut u16, enabled: &mut bool) { + fn process_length(freq_hi: &FrequencyHigh, length_timer: &mut u16, enabled: &mut bool) { if freq_hi.length_disable() && *length_timer > 0 { *length_timer -= 1; @@ -228,7 +228,7 @@ impl Apu { } } - fn clock_length_ch4(freq: &Ch4Frequency, length_timer: &mut u16, enabled: &mut bool) { + fn ch4_process_length(freq: &Ch4Frequency, length_timer: &mut u16, enabled: &mut bool) { if freq.length_disable() && *length_timer > 0 { *length_timer -= 1; @@ -240,33 +240,33 @@ impl Apu { } } - fn handle_length(&mut self) { - Self::clock_length( + fn clock_length(&mut self) { + Self::process_length( &self.ch1.freq_hi, &mut self.ch1.length_timer, &mut self.ch1.enabled, ); - Self::clock_length( + Self::process_length( &self.ch2.freq_hi, &mut self.ch2.length_timer, &mut self.ch2.enabled, ); - Self::clock_length( + Self::process_length( &self.ch3.freq_hi, &mut self.ch3.length_timer, &mut self.ch3.enabled, ); - Self::clock_length_ch4( + Self::ch4_process_length( &self.ch4.freq, &mut self.ch4.length_timer, &mut self.ch4.enabled, ); } - fn handle_sweep(&mut self) { + fn clock_sweep(&mut self) { if self.ch1.sweep_timer != 0 { self.ch1.sweep_timer -= 1; } @@ -288,7 +288,7 @@ impl Apu { } } - fn clock_envelope(envelope: &VolumeEnvelope, period_timer: &mut u8, current_volume: &mut u8) { + fn process_envelope(envelope: &VolumeEnvelope, period_timer: &mut u8, current_volume: &mut u8) { use EnvelopeDirection::*; if envelope.period() != 0 { @@ -308,29 +308,29 @@ impl Apu { } } - fn handle_envelope(&mut self) { + fn clock_envelope(&mut self) { // Channels 1, 2 and 4 have Volume Envelopes - Self::clock_envelope( + Self::process_envelope( &self.ch1.envelope, &mut self.ch1.period_timer, &mut self.ch1.current_volume, ); - Self::clock_envelope( + Self::process_envelope( &self.ch2.envelope, &mut self.ch2.period_timer, &mut self.ch2.current_volume, ); - Self::clock_envelope( + Self::process_envelope( &self.ch4.envelope, &mut self.ch4.period_timer, &mut self.ch4.current_volume, ); } - fn falling_edge(&self, bit: u8, div: u16) -> bool { + fn is_falling_edge(&self, bit: u8, div: u16) -> bool { match self.div_prev { Some(p) => (p >> bit & 0x01) == 0x01 && (div >> bit & 0x01) == 0x00, None => false, @@ -416,26 +416,6 @@ pub(crate) struct Channel1 { } impl Channel1 { - fn amplitude(&self) -> f32 { - if self.is_dac_enabled() && self.enabled { - let input = self.duty.wave_pattern().amplitude(self.duty_pos) * self.current_volume; - (input as f32 / 7.5) - 1.0 - } else { - 0.0 - } - } - - fn clock(&mut self) { - if self.freq_timer != 0 { - self.freq_timer -= 1; - } - - if self.freq_timer == 0 { - self.freq_timer = (2048 - self.frequency()) * 4; - self.duty_pos = (self.duty_pos + 1) % 8; - } - } - /// 0xFF10 | NR10 - Channel 1 Sweep Register pub(crate) fn sweep(&self) -> u8 { u8::from(self.sweep) | 0x80 @@ -516,6 +496,26 @@ impl Channel1 { } } + fn tick(&mut self) { + if self.freq_timer != 0 { + self.freq_timer -= 1; + } + + if self.freq_timer == 0 { + self.freq_timer = (2048 - self.frequency()) * 4; + self.duty_pos = (self.duty_pos + 1) % 8; + } + } + + fn amplitude(&self) -> f32 { + if self.is_dac_enabled() && self.enabled { + let input = self.duty.wave_pattern().amplitude(self.duty_pos) * self.current_volume; + (input as f32 / 7.5) - 1.0 + } else { + 0.0 + } + } + fn calc_sweep_freq(&mut self) -> u16 { use SweepDirection::*; @@ -574,26 +574,6 @@ pub(crate) struct Channel2 { } impl Channel2 { - fn amplitude(&self) -> f32 { - if self.is_dac_enabled() && self.enabled { - let input = self.duty.wave_pattern().amplitude(self.duty_pos) * self.current_volume; - (input as f32 / 7.5) - 1.0 - } else { - 0.0 - } - } - - fn clock(&mut self) { - if self.freq_timer != 0 { - self.freq_timer -= 1; - } - - if self.freq_timer == 0 { - self.freq_timer = (2048 - self.frequency()) * 4; - self.duty_pos = (self.duty_pos + 1) % 8; - } - } - /// 0xFF16 | NR21 - Channel 2 Sound length / Wave Pattern Duty pub(crate) fn duty(&self) -> u8 { u8::from(self.duty) | 0x3F @@ -649,6 +629,26 @@ impl Channel2 { } } + fn amplitude(&self) -> f32 { + if self.is_dac_enabled() && self.enabled { + let input = self.duty.wave_pattern().amplitude(self.duty_pos) * self.current_volume; + (input as f32 / 7.5) - 1.0 + } else { + 0.0 + } + } + + fn tick(&mut self) { + if self.freq_timer != 0 { + self.freq_timer -= 1; + } + + if self.freq_timer == 0 { + self.freq_timer = (2048 - self.frequency()) * 4; + self.duty_pos = (self.duty_pos + 1) % 8; + } + } + fn frequency(&self) -> u16 { (self.freq_hi.freq_bits() as u16) << 8 | self.freq_lo as u16 } @@ -767,16 +767,7 @@ impl Channel3 { } } - fn amplitude(&self) -> f32 { - if self.dac_enabled && self.enabled { - let input = self.read_sample(self.offset) >> self.volume.shift_count(); - (input as f32 / 7.5) - 1.0 - } else { - 0.0 - } - } - - fn clock(&mut self) { + fn tick(&mut self) { if self.freq_timer != 0 { self.freq_timer -= 1; } @@ -787,6 +778,15 @@ impl Channel3 { } } + fn amplitude(&self) -> f32 { + if self.dac_enabled && self.enabled { + let input = self.read_sample(self.offset) >> self.volume.shift_count(); + (input as f32 / 7.5) - 1.0 + } else { + 0.0 + } + } + fn read_sample(&self, index: u8) -> u8 { let i = (index / 2) as usize; @@ -889,16 +889,7 @@ impl Channel4 { } } - fn amplitude(&self) -> f32 { - if self.is_dac_enabled() && self.enabled { - let input = (!self.lf_shift & 0x01) as u8 * self.current_volume; - (input as f32 / 7.5) - 1.0 - } else { - 0.0 - } - } - - fn clock(&mut self) { + fn tick(&mut self) { if self.freq_timer != 0 { self.freq_timer -= 1; } @@ -916,6 +907,15 @@ impl Channel4 { } } + fn amplitude(&self) -> f32 { + if self.is_dac_enabled() && self.enabled { + let input = (!self.lf_shift & 0x01) as u8 * self.current_volume; + (input as f32 / 7.5) - 1.0 + } else { + 0.0 + } + } + fn is_dac_enabled(&self) -> bool { self.envelope.0 & 0xF8 != 0x00 } diff --git a/src/apu/gen.rs b/src/apu/gen.rs index ebc82fe..cd38bf1 100644 --- a/src/apu/gen.rs +++ b/src/apu/gen.rs @@ -48,7 +48,7 @@ impl SampleProducer { self.inner.slots() > 2 } - pub(crate) fn available_block(&self) -> bool { + pub(crate) fn available_blocking(&self) -> bool { loop { if self.inner.slots() > 2 { break true; diff --git a/src/apu/types.rs b/src/apu/types.rs index 01a8016..b7e50d8 100644 --- a/src/apu/types.rs +++ b/src/apu/types.rs @@ -513,21 +513,21 @@ pub(super) mod fs { #[derive(Debug)] pub(crate) struct FrameSequencer { step: u8, - state: FrameSequencerState, + state: State, } impl Default for FrameSequencer { fn default() -> Self { Self { step: Default::default(), - state: FrameSequencerState::Length, + state: State::Length, } } } impl FrameSequencer { pub(crate) fn next(&mut self) { - use FrameSequencerState::*; + use State::*; self.step = (self.step + 1) % 8; self.state = match self.step { @@ -539,18 +539,18 @@ pub(super) mod fs { }; } - pub(crate) fn state(&self) -> FrameSequencerState { + pub(crate) fn state(&self) -> State { self.state } pub(crate) fn reset(&mut self) { self.step = Default::default(); - self.state = FrameSequencerState::Length; + self.state = State::Length; } } #[derive(Debug, Clone, Copy)] - pub(crate) enum FrameSequencerState { + pub(crate) enum State { Length, Nothing, LengthAndSweep, diff --git a/src/main.rs b/src/main.rs index 95eb680..06b2d29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,7 @@ fn main() -> Result<()> { let (_stream, stream_handle) = OutputStream::try_default().expect("Initialized Audio"); let sink = Sink::try_new(&stream_handle)?; sink.append(cons); - game_boy.apu_mut().set_producer(prod); + game_boy.apu_mut().attach_producer(prod); std::thread::spawn(move || { sink.sleep_until_end();