From a41bb0b89be052f2eb6164aa41a5c40e4228ba13 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Thu, 10 Jun 2021 22:42:04 +0100 Subject: [PATCH] Have 2 buffers for left or right control --- agb/src/sound/mixer/hw.rs | 17 +++++++++++++++-- agb/src/sound/mixer/mixer.rs | 25 +++++++++++++++++-------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/agb/src/sound/mixer/hw.rs b/agb/src/sound/mixer/hw.rs index 313e9a06..2c10275a 100644 --- a/agb/src/sound/mixer/hw.rs +++ b/agb/src/sound/mixer/hw.rs @@ -31,14 +31,27 @@ const DMA_CONTROL_SETTING_FOR_SOUND: u16 = { dest_fixed | repeat | transfer_type | dma_start_timing | enable }; -pub(super) fn enable_dma1_for_sound(sound_memory: &[i8]) { +#[derive(Copy, Clone)] +pub(super) enum LeftOrRight { + Left, + Right, +} + +pub(super) fn enable_dma_for_sound(sound_memory: &[i8], lr: LeftOrRight) { + match lr { + LeftOrRight::Left => enable_dma1_for_sound(sound_memory), + LeftOrRight::Right => enable_dma2_for_sound(sound_memory), + } +} + +fn enable_dma1_for_sound(sound_memory: &[i8]) { DMA1_CONTROL.set(0); DMA1_SOURCE_ADDR.set(sound_memory.as_ptr() as u32); DMA1_DEST_ADDR.set(FIFOA_DEST_ADDR); DMA1_CONTROL.set(DMA_CONTROL_SETTING_FOR_SOUND); } -pub(super) fn enable_dma2_for_sound(sound_memory: &[i8]) { +fn enable_dma2_for_sound(sound_memory: &[i8]) { DMA2_CONTROL.set(0); DMA2_SOURCE_ADDR.set(sound_memory.as_ptr() as u32); DMA2_DEST_ADDR.set(FIFOB_DEST_ADDR); diff --git a/agb/src/sound/mixer/mixer.rs b/agb/src/sound/mixer/mixer.rs index 323f7d6f..a88d0355 100644 --- a/agb/src/sound/mixer/mixer.rs +++ b/agb/src/sound/mixer/mixer.rs @@ -1,15 +1,18 @@ use super::hw; +use super::hw::LeftOrRight; use super::SoundChannel; pub struct Mixer { - buffer: MixerBuffer, + buffer_l: MixerBuffer, + buffer_r: MixerBuffer, channels: [Option; 16], } impl Mixer { pub(super) fn new() -> Self { Mixer { - buffer: MixerBuffer::new(), + buffer_l: MixerBuffer::new(LeftOrRight::Left), + buffer_r: MixerBuffer::new(LeftOrRight::Right), channels: Default::default(), } } @@ -20,14 +23,17 @@ impl Mixer { } pub fn vblank(&mut self) { - self.buffer.swap(); - self.buffer.clear(); + self.buffer_l.swap(); + self.buffer_r.swap(); + self.buffer_l.clear(); + self.buffer_r.clear(); for channel in self.channels.iter_mut() { let mut has_finished = false; if let Some(some_channel) = channel { - self.buffer.write_channel(some_channel); + self.buffer_l.write_channel(some_channel); + self.buffer_r.write_channel(some_channel); some_channel.pos += SOUND_BUFFER_SIZE; if some_channel.pos >= some_channel.data.len() { @@ -69,15 +75,18 @@ struct MixerBuffer { buffer2: [i8; SOUND_BUFFER_SIZE], buffer_1_active: bool, + + lr: LeftOrRight, } impl MixerBuffer { - fn new() -> Self { + fn new(lr: LeftOrRight) -> Self { MixerBuffer { buffer1: [0; SOUND_BUFFER_SIZE], buffer2: [0; SOUND_BUFFER_SIZE], buffer_1_active: true, + lr, } } @@ -85,9 +94,9 @@ impl MixerBuffer { self.buffer_1_active = !self.buffer_1_active; if self.buffer_1_active { - hw::enable_dma1_for_sound(&self.buffer1); + hw::enable_dma_for_sound(&self.buffer1, self.lr); } else { - hw::enable_dma1_for_sound(&self.buffer2); + hw::enable_dma_for_sound(&self.buffer2, self.lr); } }