Have 2 buffers for left or right control

This commit is contained in:
Gwilym Kuiper 2021-06-10 22:42:04 +01:00
parent 74f2fdbc8b
commit a41bb0b89b
2 changed files with 32 additions and 10 deletions

View file

@ -31,14 +31,27 @@ const DMA_CONTROL_SETTING_FOR_SOUND: u16 = {
dest_fixed | repeat | transfer_type | dma_start_timing | enable 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_CONTROL.set(0);
DMA1_SOURCE_ADDR.set(sound_memory.as_ptr() as u32); DMA1_SOURCE_ADDR.set(sound_memory.as_ptr() as u32);
DMA1_DEST_ADDR.set(FIFOA_DEST_ADDR); DMA1_DEST_ADDR.set(FIFOA_DEST_ADDR);
DMA1_CONTROL.set(DMA_CONTROL_SETTING_FOR_SOUND); 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_CONTROL.set(0);
DMA2_SOURCE_ADDR.set(sound_memory.as_ptr() as u32); DMA2_SOURCE_ADDR.set(sound_memory.as_ptr() as u32);
DMA2_DEST_ADDR.set(FIFOB_DEST_ADDR); DMA2_DEST_ADDR.set(FIFOB_DEST_ADDR);

View file

@ -1,15 +1,18 @@
use super::hw; use super::hw;
use super::hw::LeftOrRight;
use super::SoundChannel; use super::SoundChannel;
pub struct Mixer { pub struct Mixer {
buffer: MixerBuffer, buffer_l: MixerBuffer,
buffer_r: MixerBuffer,
channels: [Option<SoundChannel>; 16], channels: [Option<SoundChannel>; 16],
} }
impl Mixer { impl Mixer {
pub(super) fn new() -> Self { pub(super) fn new() -> Self {
Mixer { Mixer {
buffer: MixerBuffer::new(), buffer_l: MixerBuffer::new(LeftOrRight::Left),
buffer_r: MixerBuffer::new(LeftOrRight::Right),
channels: Default::default(), channels: Default::default(),
} }
} }
@ -20,14 +23,17 @@ impl Mixer {
} }
pub fn vblank(&mut self) { pub fn vblank(&mut self) {
self.buffer.swap(); self.buffer_l.swap();
self.buffer.clear(); self.buffer_r.swap();
self.buffer_l.clear();
self.buffer_r.clear();
for channel in self.channels.iter_mut() { for channel in self.channels.iter_mut() {
let mut has_finished = false; let mut has_finished = false;
if let Some(some_channel) = channel { 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; some_channel.pos += SOUND_BUFFER_SIZE;
if some_channel.pos >= some_channel.data.len() { if some_channel.pos >= some_channel.data.len() {
@ -69,15 +75,18 @@ struct MixerBuffer {
buffer2: [i8; SOUND_BUFFER_SIZE], buffer2: [i8; SOUND_BUFFER_SIZE],
buffer_1_active: bool, buffer_1_active: bool,
lr: LeftOrRight,
} }
impl MixerBuffer { impl MixerBuffer {
fn new() -> Self { fn new(lr: LeftOrRight) -> Self {
MixerBuffer { MixerBuffer {
buffer1: [0; SOUND_BUFFER_SIZE], buffer1: [0; SOUND_BUFFER_SIZE],
buffer2: [0; SOUND_BUFFER_SIZE], buffer2: [0; SOUND_BUFFER_SIZE],
buffer_1_active: true, buffer_1_active: true,
lr,
} }
} }
@ -85,9 +94,9 @@ impl MixerBuffer {
self.buffer_1_active = !self.buffer_1_active; self.buffer_1_active = !self.buffer_1_active;
if 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 { } else {
hw::enable_dma1_for_sound(&self.buffer2); hw::enable_dma_for_sound(&self.buffer2, self.lr);
} }
} }