diff --git a/examples/beep.rs b/examples/beep.rs index d45a8f19..4cdbffb3 100644 --- a/examples/beep.rs +++ b/examples/beep.rs @@ -20,5 +20,12 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize { sound::DutyCycle::Half, ); + gba.sound.channel2().play_sound( + 1524, + Some(0), + &sound::EnvelopeSettings::default(), + sound::DutyCycle::Half, + ); + loop {} } diff --git a/src/sound/mod.rs b/src/sound/mod.rs index 7dfc04c6..214b3b43 100644 --- a/src/sound/mod.rs +++ b/src/sound/mod.rs @@ -4,6 +4,9 @@ const CHANNEL_1_SWEEP: MemoryMapped = unsafe { MemoryMapped::new(0x0400_006 const CHANNEL_1_LENGTH_DUTY_ENVELOPE: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0062) }; const CHANNEL_1_FREQUENCY_CONTROL: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0064) }; +const CHANNEL_2_LENGTH_DUTY_ENVELOPE: MemoryMapped = unsafe { MemoryMapped::new(0x0400_0068) }; +const CHANNEL_2_FREQUENCY_CONTROL: MemoryMapped = unsafe { MemoryMapped::new(0x0400_006c) }; + 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) }; @@ -20,6 +23,10 @@ impl Sound { Channel1 {} } + pub fn channel2(&self) -> Channel2 { + Channel2 {} + } + pub fn enable(&self) { MASTER_SOUND_STATUS.set_bits(1, 1, 7); @@ -31,20 +38,6 @@ impl Sound { #[non_exhaustive] pub struct Channel1 {} -pub enum SoundDirection { - Increase, - Decrease, -} - -impl SoundDirection { - fn as_bits(&self) -> u16 { - match &self { - SoundDirection::Increase => 1, - SoundDirection::Decrease => 0, - } - } -} - impl Channel1 { pub fn play_sound( &self, @@ -69,6 +62,45 @@ impl Channel1 { } } +#[non_exhaustive] +pub struct Channel2 {} + +impl Channel2 { + pub fn play_sound( + &self, + frequency: u16, + length: Option, + envelope_settings: &EnvelopeSettings, + duty_cycle: DutyCycle, + ) { + let length_bits = length.unwrap_or(0) as u16; + assert!(length_bits < 64, "Length must be less than 64"); + + let length_flag: u16 = length.map(|_| 1 << 14).unwrap_or(0); + let initial: u16 = 1 << 15; + + assert!(frequency < 2048, "Frequency must be less than 2048"); + + CHANNEL_2_LENGTH_DUTY_ENVELOPE + .set(envelope_settings.as_bits() | duty_cycle.as_bits() | length_bits); + CHANNEL_2_FREQUENCY_CONTROL.set(frequency | length_flag | initial); + } +} + +pub enum SoundDirection { + Increase, + Decrease, +} + +impl SoundDirection { + fn as_bits(&self) -> u16 { + match &self { + SoundDirection::Increase => 1, + SoundDirection::Decrease => 0, + } + } +} + pub struct SweepSettings { number_of_sweep_shifts: u8, sound_direction: SoundDirection,