Move buffer management entirely to the mixer state

This commit is contained in:
Gwilym Kuiper 2022-12-10 00:28:30 +00:00
parent 93d0fe5700
commit 5a71db0c17
2 changed files with 21 additions and 24 deletions

View file

@ -46,23 +46,23 @@ pub(super) enum LeftOrRight {
Right, Right,
} }
pub(super) fn enable_dma_for_sound(sound_memory: &[i8], lr: LeftOrRight) { pub(super) fn enable_dma_for_sound(sound_memory: *const i8, lr: LeftOrRight) {
match lr { match lr {
LeftOrRight::Left => enable_dma1_for_sound(sound_memory), LeftOrRight::Left => enable_dma1_for_sound(sound_memory),
LeftOrRight::Right => enable_dma2_for_sound(sound_memory), LeftOrRight::Right => enable_dma2_for_sound(sound_memory),
} }
} }
fn enable_dma1_for_sound(sound_memory: &[i8]) { fn enable_dma1_for_sound(sound_memory: *const 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 u32);
DMA1_DEST_ADDR.set(FIFO_A_DEST_ADDR); DMA1_DEST_ADDR.set(FIFO_A_DEST_ADDR);
DMA1_CONTROL.set(DMA_CONTROL_SETTING_FOR_SOUND); DMA1_CONTROL.set(DMA_CONTROL_SETTING_FOR_SOUND);
} }
fn enable_dma2_for_sound(sound_memory: &[i8]) { fn enable_dma2_for_sound(sound_memory: *const 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 u32);
DMA2_DEST_ADDR.set(FIFO_B_DEST_ADDR); DMA2_DEST_ADDR.set(FIFO_B_DEST_ADDR);
DMA2_CONTROL.set(DMA_CONTROL_SETTING_FOR_SOUND); DMA2_CONTROL.set(DMA_CONTROL_SETTING_FOR_SOUND);
} }

View file

@ -321,7 +321,6 @@ impl SoundBuffer {
} }
struct MixerBuffer { struct MixerBuffer {
buffers: [SoundBuffer; 3],
frequency: Frequency, frequency: Frequency,
state: Mutex<RefCell<MixerBufferState>>, state: Mutex<RefCell<MixerBufferState>>,
@ -330,6 +329,7 @@ struct MixerBuffer {
struct MixerBufferState { struct MixerBufferState {
active_buffer: usize, active_buffer: usize,
playing_buffer: usize, playing_buffer: usize,
buffers: [SoundBuffer; 3],
} }
/// Only returns a valid result if 0 <= x <= 3 /// Only returns a valid result if 0 <= x <= 3
@ -348,29 +348,28 @@ impl MixerBufferState {
mod3_estimate(self.active_buffer + 1) != self.playing_buffer mod3_estimate(self.active_buffer + 1) != self.playing_buffer
} }
fn playing_advanced(&mut self) -> usize { fn playing_advanced(&mut self) -> *const i8 {
self.playing_buffer = mod3_estimate(self.playing_buffer + 1); self.playing_buffer = mod3_estimate(self.playing_buffer + 1);
self.playing_buffer self.buffers[self.playing_buffer].0.as_ptr()
} }
fn active_advanced(&mut self) -> usize { fn active_advanced(&mut self) -> *mut i8 {
self.active_buffer = mod3_estimate(self.active_buffer + 1); self.active_buffer = mod3_estimate(self.active_buffer + 1);
self.active_buffer self.buffers[self.active_buffer].0.as_mut_ptr()
} }
} }
impl MixerBuffer { impl MixerBuffer {
fn new(frequency: Frequency) -> Self { fn new(frequency: Frequency) -> Self {
MixerBuffer { MixerBuffer {
buffers: [
SoundBuffer::new(frequency),
SoundBuffer::new(frequency),
SoundBuffer::new(frequency),
],
state: Mutex::new(RefCell::new(MixerBufferState { state: Mutex::new(RefCell::new(MixerBufferState {
active_buffer: 0, active_buffer: 0,
playing_buffer: 0, playing_buffer: 0,
buffers: [
SoundBuffer::new(frequency),
SoundBuffer::new(frequency),
SoundBuffer::new(frequency),
],
})), })),
frequency, frequency,
@ -384,16 +383,16 @@ impl MixerBuffer {
fn swap(&self, cs: CriticalSection) { fn swap(&self, cs: CriticalSection) {
let buffer = self.state.borrow(cs).borrow_mut().playing_advanced(); let buffer = self.state.borrow(cs).borrow_mut().playing_advanced();
let (left_buffer, right_buffer) = self.buffers[buffer] let left_buffer = buffer;
.0 // SAFETY: starting pointer is fine, resulting pointer also fine because buffer has length buffer_size() * 2 by construction
.split_at(self.frequency.buffer_size()); let right_buffer = unsafe { buffer.add(self.frequency.buffer_size()) };
hw::enable_dma_for_sound(left_buffer, LeftOrRight::Left); hw::enable_dma_for_sound(left_buffer, LeftOrRight::Left);
hw::enable_dma_for_sound(right_buffer, LeftOrRight::Right); hw::enable_dma_for_sound(right_buffer, LeftOrRight::Right);
} }
fn write_channels<'a>( fn write_channels<'a>(
&mut self, &self,
working_buffer: &mut [Num<i16, 4>], working_buffer: &mut [Num<i16, 4>],
channels: impl Iterator<Item = &'a mut SoundChannel>, channels: impl Iterator<Item = &'a mut SoundChannel>,
) { ) {
@ -448,12 +447,10 @@ impl MixerBuffer {
channel.pos += playback_speed * self.frequency.buffer_size(); channel.pos += playback_speed * self.frequency.buffer_size();
} }
let write_buffer_index = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced()); let write_buffer = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced());
let write_buffer = &mut self.buffers[write_buffer_index].0;
unsafe { unsafe {
agb_rs__mixer_collapse(write_buffer.as_mut_ptr(), working_buffer.as_ptr()); agb_rs__mixer_collapse(write_buffer, working_buffer.as_ptr());
} }
} }
} }