From 13dc368d185bda7301d7ac81fe3a91cac21246ad Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 6 Jun 2021 00:28:59 +0100 Subject: [PATCH] Add basic noise channel support --- agb/examples/beep.rs | 4 ++++ agb/src/sound/mod.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/agb/examples/beep.rs b/agb/examples/beep.rs index d44562f6..0e7ebf42 100644 --- a/agb/examples/beep.rs +++ b/agb/examples/beep.rs @@ -27,5 +27,9 @@ pub fn main() -> ! { sound::DutyCycle::Half, ); + gba.sound + .noise() + .play_sound(Some(0), &sound::EnvelopeSettings::default(), 4, false, 1); + loop {} } diff --git a/agb/src/sound/mod.rs b/agb/src/sound/mod.rs index 0bd8a9c3..4a91aa65 100644 --- a/agb/src/sound/mod.rs +++ b/agb/src/sound/mod.rs @@ -7,6 +7,9 @@ const CHANNEL_1_FREQUENCY_CONTROL: MemoryMapped = unsafe { MemoryMapped::ne const CHANNEL_2_LENGTH_DUTY_ENVELOPE: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0068) }; const CHANNEL_2_FREQUENCY_CONTROL: MemoryMapped = unsafe { MemoryMapped::new(0x0400_006c) }; +const CHANNEL_4_LENGTH_ENVELOPE: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0078) }; +const CHANNEL_4_FREQUENCY_CONTROL: MemoryMapped = unsafe { MemoryMapped::new(0x0400_007c) }; + const MASTER_SOUND_VOLUME_ENABLE: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0080) }; const MASTER_SOUND_VOLUME_MIXING: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0082) }; const MASTER_SOUND_STATUS: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0084) }; @@ -27,6 +30,10 @@ impl Sound { Channel2 {} } + pub fn noise(&self) -> Noise { + Noise {} + } + pub fn enable(&self) { MASTER_SOUND_STATUS.set_bits(1, 1, 7); @@ -88,6 +95,46 @@ impl Channel2 { } } +#[non_exhaustive] +pub struct Noise {} + +impl Noise { + pub fn play_sound( + &self, + length: Option, + envelope_setting: &EnvelopeSettings, + frequency_divider: u8, + counter_step_width_15: bool, + shift_clock_frequency: u8, + ) { + let length_bits = length.unwrap_or(0) as u16; + assert!(length_bits < 64, "length must be less than 16"); + + assert!( + frequency_divider < 8, + "frequency divider must be less than 8" + ); + assert!( + shift_clock_frequency < 16, + "frequency clock divider must be less than 16" + ); + + let length_flag: u16 = length.map(|_| 1 << 14).unwrap_or(0); + let initial: u16 = 1 << 15; + + let counter_step_bit = if counter_step_width_15 { 0 } else { 1 << 3 }; + + CHANNEL_4_LENGTH_ENVELOPE.set(length_bits | envelope_setting.as_bits()); + CHANNEL_4_FREQUENCY_CONTROL.set( + (frequency_divider as u16) + | counter_step_bit + | ((shift_clock_frequency as u16) << 4) + | length_flag + | initial, + ) + } +} + pub enum SoundDirection { Increase, Decrease,