Skip to content

Commit

Permalink
VolumeEnvelope
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacMarovitz committed Feb 23, 2024
1 parent 26096df commit 33bc7c4
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 90 deletions.
38 changes: 0 additions & 38 deletions src/sound/apu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,44 +150,6 @@ impl APU {
self.ch4.cycle();
}

let ch1_vol = {
if self.ch1.dac_enabled {
self.ch1.volume as f64 / 0xF as f64
} else {
0.0
}
};

let ch2_vol = {
if self.ch2.dac_enabled {
self.ch2.volume as f64 / 0xF as f64
} else {
0.0
}
};

let ch3_vol = {
if self.ch3.dac_enabled {
match self.ch3.output_level {
OutputLevel::MUTE => 0.0,
OutputLevel::QUARTER => 0.25,
OutputLevel::HALF => 0.5,
OutputLevel::MAX => 1.0,
_ => 0.0,
}
} else {
0.0
}
};

let ch4_vol = {
if self.ch4.dac_enabled {
self.ch4.final_volume as f64 / 0xF as f64
} else {
0.0
}
};

// TODO: Amplifier on original hardware NEVER completely mutes non-silent input
let global_l = {
if self.audio_enabled {
Expand Down
29 changes: 12 additions & 17 deletions src/sound/ch1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::components::memory::Memory;
use crate::sound::apu::DutyCycle;
use crate::sound::blip::Blip;
use crate::sound::length_counter::LengthCounter;
use crate::sound::volume_envelope::VolumeEnvelope;

pub struct CH1 {
pub blip: Blip,
Expand All @@ -10,12 +11,10 @@ pub struct CH1 {
negative_direction: bool,
sweep_step: u8,
pub duty_cycle: DutyCycle,
pub volume: u8,
positive_envelope: bool,
envelope_pace: u8,
pub period: u16,
sweep_cycle_count: u32,
length_counter: LengthCounter
length_counter: LengthCounter,
volume_envelope: VolumeEnvelope
}

impl CH1 {
Expand All @@ -27,12 +26,10 @@ impl CH1 {
negative_direction: false,
sweep_step: 0,
duty_cycle: DutyCycle::EIGHTH,
volume: 0,
positive_envelope: false,
envelope_pace: 0,
period: 0,
sweep_cycle_count: 0,
length_counter: LengthCounter::new()
length_counter: LengthCounter::new(),
volume_envelope: VolumeEnvelope::new()
}
}

Expand All @@ -42,11 +39,9 @@ impl CH1 {
self.negative_direction = false;
self.sweep_step = 0;
self.duty_cycle = DutyCycle::EIGHTH;
self.volume = 0;
self.positive_envelope = false;
self.envelope_pace = 0;
self.period = 0;
self.length_counter.clear();
self.volume_envelope.clear();
}

pub fn cycle(&mut self) {
Expand Down Expand Up @@ -95,9 +90,9 @@ impl Memory for CH1 {
0xFF11 => (self.duty_cycle.bits()) << 6 | 0x3F,
// NR12: Volume & Envelope
0xFF12 => {
(self.volume & 0b0000_1111) << 4
| (self.positive_envelope as u8) << 3
| (self.envelope_pace & 0b0000_0111)
(self.volume_envelope.volume & 0b0000_1111) << 4
| (self.volume_envelope.positive as u8) << 3
| (self.volume_envelope.positive as u8 & 0b0000_0111)
}
// NR13: Period Low
0xFF13 => 0xFF,
Expand All @@ -122,9 +117,9 @@ impl Memory for CH1 {
}
// NR12: Volume & Envelope
0xFF12 => {
self.volume = (v & 0b1111_0000) >> 4;
self.positive_envelope = ((v & 0b0000_1000) >> 3) != 0;
self.envelope_pace = v & 0b0000_0111;
self.volume_envelope.volume = (v & 0b1111_0000) >> 4;
self.volume_envelope.positive = ((v & 0b0000_1000) >> 3) != 0;
self.volume_envelope.period = (v & 0b0000_0111) as u16;

if self.read(0xFF12) & 0xF8 != 0 {
self.dac_enabled = true;
Expand Down
29 changes: 12 additions & 17 deletions src/sound/ch2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ use crate::components::memory::Memory;
use crate::sound::apu::DutyCycle;
use crate::sound::blip::Blip;
use crate::sound::length_counter::LengthCounter;
use crate::sound::volume_envelope::VolumeEnvelope;

pub struct CH2 {
pub blip: Blip,
pub dac_enabled: bool,
pub duty_cycle: DutyCycle,
pub volume: u8,
positive_envelope: bool,
envelope_pace: u8,
pub period: u16,
length_counter: LengthCounter
length_counter: LengthCounter,
volume_envelope: VolumeEnvelope
}

impl CH2 {
Expand All @@ -20,22 +19,18 @@ impl CH2 {
blip,
dac_enabled: false,
duty_cycle: DutyCycle::EIGHTH,
volume: 0,
positive_envelope: false,
envelope_pace: 0,
period: 0,
length_counter: LengthCounter::new()
length_counter: LengthCounter::new(),
volume_envelope: VolumeEnvelope::new()
}
}

pub fn clear(&mut self) {
self.dac_enabled = false;
self.duty_cycle = DutyCycle::EIGHTH;
self.volume = 0;
self.positive_envelope = false;
self.envelope_pace = 0;
self.period = 0;
self.length_counter.clear();
self.volume_envelope.clear();
}

pub fn cycle(&mut self) {
Expand All @@ -52,9 +47,9 @@ impl Memory for CH2 {
0xFF16 => (self.duty_cycle.bits()) << 6 | 0x3F,
// NR22: Volume & Envelope
0xFF17 => {
(self.volume & 0b0000_1111) << 4
| (self.positive_envelope as u8) << 3
| (self.envelope_pace & 0b0000_0111)
(self.volume_envelope.volume & 0b0000_1111) << 4
| (self.volume_envelope.positive as u8) << 3
| (self.volume_envelope.period as u8 & 0b0000_0111)
}
// NR23: Period Low
0xFF18 => 0xFF,
Expand All @@ -74,9 +69,9 @@ impl Memory for CH2 {
}
// NR22: Volume & Envelope
0xFF17 => {
self.volume = (v & 0b1111_0000) >> 4;
self.positive_envelope = ((v & 0b0000_1000) >> 3) != 0;
self.envelope_pace = v & 0b0000_0111;
self.volume_envelope.volume = (v & 0b1111_0000) >> 4;
self.volume_envelope.positive = ((v & 0b0000_1000) >> 3) != 0;
self.volume_envelope.period = (v & 0b0000_0111) as u16;

if self.read(0xFF17) & 0xF8 != 0 {
self.dac_enabled = true;
Expand Down
31 changes: 13 additions & 18 deletions src/sound/ch4.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use crate::components::memory::Memory;
use crate::sound::blip::Blip;
use crate::sound::length_counter::LengthCounter;
use crate::sound::volume_envelope::VolumeEnvelope;

pub struct CH4 {
pub blip: Blip,
pub dac_enabled: bool,
volume: u8,
positive_envelope: bool,
envelope_pace: u8,
clock: u8,
pub bit: u16,
// False = 15-bit, True = 7-bit
Expand All @@ -17,17 +15,15 @@ pub struct CH4 {
pub lfsr: u16,
pub final_volume: u8,
clock_cycle_count: u32,
length_counter: LengthCounter
length_counter: LengthCounter,
volume_envelope: VolumeEnvelope
}

impl CH4 {
pub fn new(blip: Blip) -> Self {
Self {
blip,
dac_enabled: false,
volume: 0,
positive_envelope: false,
envelope_pace: 0,
clock: 0,
bit: 0,
lfsr_width: false,
Expand All @@ -36,15 +32,13 @@ impl CH4 {
lfsr: 0,
final_volume: 0,
clock_cycle_count: 0,
length_counter: LengthCounter::new()
length_counter: LengthCounter::new(),
volume_envelope: VolumeEnvelope::new()
}
}

pub fn clear(&mut self) {
self.dac_enabled = false;
self.volume = 0;
self.positive_envelope = false;
self.envelope_pace = 0;
self.clock = 0;
self.lfsr_width = false;
self.clock_divider = 0;
Expand All @@ -53,6 +47,7 @@ impl CH4 {
self.final_volume = 0;
self.clock_cycle_count = 0;
self.length_counter.clear();
self.volume_envelope.clear();
}

pub fn cycle(&mut self) {
Expand Down Expand Up @@ -85,7 +80,7 @@ impl CH4 {
if self.lfsr & 0b0000_0000_0000_0001 == 0 {
self.final_volume = 0;
} else {
self.final_volume = self.volume;
self.final_volume = self.volume_envelope.volume;
}
}

Expand All @@ -102,9 +97,9 @@ impl Memory for CH4 {
0xFF20 => 0xFF,
// NR42: Volume & Envelope
0xFF21 => {
(self.volume & 0b0000_1111) << 4
| (self.positive_envelope as u8) << 3
| (self.envelope_pace & 0b0000_0111)
(self.volume_envelope.volume & 0b0000_1111) << 4
| (self.volume_envelope.positive as u8) << 3
| (self.volume_envelope.period as u8 & 0b0000_0111)
}
// NR43: Frequency & Randomness
0xFF22 => {
Expand All @@ -125,9 +120,9 @@ impl Memory for CH4 {
0xFF20 => self.length_counter.counter = (v & 0b0011_1111) as u16,
// NR42: Volume & Envelope
0xFF21 => {
self.volume = (v & 0b1111_0000) >> 4;
self.positive_envelope = ((v & 0b0000_1000) >> 3) != 0;
self.envelope_pace = v & 0b0000_0111;
self.volume_envelope.volume = (v & 0b1111_0000) >> 4;
self.volume_envelope.positive = ((v & 0b0000_1000) >> 3) != 0;
self.volume_envelope.period = (v & 0b0000_0111) as u16;

if self.read(0xFF21) & 0xF8 != 0 {
self.dac_enabled = true;
Expand Down
1 change: 1 addition & 0 deletions src/sound/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod ch3;
mod ch4;
mod blip;
mod length_counter;
mod volume_envelope;

#[allow(unused_imports)]
mod prelude {
Expand Down
41 changes: 41 additions & 0 deletions src/sound/volume_envelope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pub struct VolumeEnvelope {
pub volume: u8,
pub period: u16,
pub positive: bool,
}

impl VolumeEnvelope {
pub fn new() -> Self {
Self {
volume: 0,
period: 0,
positive: false
}
}

pub fn cycle(&mut self) {
if self.period == 0 {
return;
}

let volume = if self.positive {
self.volume.wrapping_add(1)
} else {
self.volume.wrapping_sub(1)
};

if volume <= 15 {
self.volume = volume;
}
}

pub fn reload() {
// TODO!!!
}

pub fn clear(&mut self) {
self.volume = 0;
self.period = 0;
self.positive = false;
}
}

0 comments on commit 33bc7c4

Please sign in to comment.