From f5d771d3497e724f9edcd09e1c88327503539f23 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 31 Jul 2021 21:47:05 +0100 Subject: [PATCH 01/16] Use asm for the tight loops in the sound mixer --- agb/build.rs | 1 + agb/crt0.s | 1 + agb/examples/mixer_basic.rs | 6 +- agb/src/number.rs | 1 + agb/src/sound/mixer/mixer.s | 98 +++++++++++++++++++++++++++++++++ agb/src/sound/mixer/sw_mixer.rs | 32 ++++++++--- 6 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 agb/src/sound/mixer/mixer.s diff --git a/agb/build.rs b/agb/build.rs index e0b833cc..ee0cb111 100644 --- a/agb/build.rs +++ b/agb/build.rs @@ -4,6 +4,7 @@ fn main() { println!("cargo:rerun-if-changed=crt0.s"); println!("cargo:rerun-if-changed=gba_mb.ld"); println!("cargo:rerun-if-changed=interrupt_simple.s"); + println!("cargo:rerun-if-changed=src/sound/mixer/mixer.s"); println!("cargo:rerun-if-changed=gfx/test_logo.png"); let out_file_name = "crt0.o"; diff --git a/agb/crt0.s b/agb/crt0.s index a71b819b..1b51ec83 100644 --- a/agb/crt0.s +++ b/agb/crt0.s @@ -63,3 +63,4 @@ b .Initialise_mb .pool .include "interrupt_simple.s" +.include "src/sound/mixer/mixer.s" diff --git a/agb/examples/mixer_basic.rs b/agb/examples/mixer_basic.rs index 7b288633..c234642f 100644 --- a/agb/examples/mixer_basic.rs +++ b/agb/examples/mixer_basic.rs @@ -3,10 +3,10 @@ extern crate agb; +use agb::input::{Button, ButtonController, Tri}; +use agb::number::Num; use agb::sound::mixer::SoundChannel; use agb::Gba; -use agb::input::{ButtonController, Tri, Button}; -use agb::number::Num; // Music - "I will not let you let me down" by Josh Woodward, free download at http://joshwoodward.com const I_WILL_NOT_LET_YOU_LET_ME_DOWN: &[u8] = include_bytes!("i-will-not-let-you-let-me-down.raw"); @@ -35,7 +35,7 @@ pub fn main() -> ! { Tri::Zero => channel.panning(0.into()), Tri::Positive => channel.panning(half), }; - + match input.y_tri() { Tri::Negative => channel.playback(half_usize.change_base() + 1), Tri::Zero => channel.playback(1.into()), diff --git a/agb/src/number.rs b/agb/src/number.rs index 250b0a50..bf9c57f3 100644 --- a/agb/src/number.rs +++ b/agb/src/number.rs @@ -91,6 +91,7 @@ fixed_width_unsigned_integer_impl!(usize); fixed_width_signed_integer_impl!(i16); fixed_width_signed_integer_impl!(i32); +#[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Num(I); diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s new file mode 100644 index 00000000..60d10eab --- /dev/null +++ b/agb/src/sound/mixer/mixer.s @@ -0,0 +1,98 @@ +.arm +.global agb_rs__mixer_add +.section .iwram, "ax" +.align +agb_rs__mixer_add: + @ Arguments + @ r0 - pointer to the data to be copied (u8 array) + @ r1 - pointer to the sound buffer (i16 array) + @ r2 - playback speed (usize fixnum with 8 bits) + @ r3 - amount to modify the left channel by (u16 fixnum with 4 bits) + @ stack position 1 - amount to modify the right channel by (u16 fixnum with 4 bits) + @ + @ The sound buffer must be SOUND_BUFFER_SIZE * 2 in size = 176 * 2 + + @ lr = amount to modify right channel by + + push {r4-r10, lr} + + @ load the right channel modification amount into lr + ldr lr, [sp, #32] + + @ current write offset into the resulting buffer + mov r12, #0 + mov r8, #352 + + @ current index + mov r5, #0 + +1: + @ load the current sound buffer location + mov r6, r1 + + @ calculate the address of the next read form the sound buffer + add r4, r0, r5, asr #8 + + @ calculate the position to read the next step from + add r5, r5, r2 + + @ load the current buffer value (r6 being the current location, r12 being the offset) + @ but pre-increment r6 by r12 + ldrh r9, [r6, r12]! + + @ load the current value we want to read + ldrsb r10, [r4] + + @ increment the current write offset in the resulting buffer + add r12, r12, #2 + + @ check if we're done + cmp r12, #352 + + @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value + mla r7, r10, r3, r9 + @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side + strh r7, [r6], r8 + + @ same for the left hand side (slightly confused here, but this is what was generated) + ldrh r7, [r6] + mla r4, r10, lr, r7 + strh r4, [r6] + + bne 1b + + pop {r4-r10, lr} + bx lr +.pool + +.arm +.global agb_rs__mixer_collapse +.section .iwram +.align +agb_rs__mixer_collapse: + @ Arguments: + @ r0 = target buffer (i8) + @ r1 = input buffer (i16) of fixnums with 4 bits of precision + + mov r2, #0 + +1: + @ r12 = *r1; r1++ + ldrsh r12, [r1], #2 + + lsr r3, r12, #4 @ r3 = r12 >> 4 + + cmn r12, #2048 @ compare r12 against -2048 + mvnlt r3, #127 @ r3 = -127 if r12 <= 2048 + + cmp r12, #2048 @ compare r12 against 2048 + movge r3, #127 @ r3 = 127 if r12 >= 2048 + + strb r3, [r0, -r2] @ r2 counts down, so need a negative offset + + sub r2, r2, #1 @ r2 -= 1 + cmn r2, #352 @ compare r2 against -352 + + bne 1b @ loop if not equal + + bx lr diff --git a/agb/src/sound/mixer/sw_mixer.rs b/agb/src/sound/mixer/sw_mixer.rs index accc4168..54ad67c0 100644 --- a/agb/src/sound/mixer/sw_mixer.rs +++ b/agb/src/sound/mixer/sw_mixer.rs @@ -3,6 +3,19 @@ use super::hw::LeftOrRight; use super::{SoundChannel, SoundPriority}; use crate::number::Num; +// Defined in mixer.s +extern "C" { + fn agb_rs__mixer_add( + sound_data: *const u8, + sound_buffer: *mut Num, + playback_speed: Num, + left_amount: Num, + right_amount: Num, + ); + + fn agb_rs__mixer_collapse(sound_buffer: *mut i8, input_buffer: *const Num); +} + pub struct Mixer { buffer: MixerBuffer, channels: [Option; 16], @@ -131,18 +144,21 @@ impl MixerBuffer { } } - for i in 0..SOUND_BUFFER_SIZE { - let v = (channel.data[channel.pos.floor()] as i8) as i16; - channel.pos += channel.playback_speed; - - buffer[i] += left_amount * v; - buffer[i + SOUND_BUFFER_SIZE] += right_amount * v; + unsafe { + agb_rs__mixer_add( + channel.data.as_ptr().offset(channel.pos.floor() as isize), + buffer.as_mut_ptr(), + channel.playback_speed, + left_amount, + right_amount, + ); } + channel.pos += channel.playback_speed * SOUND_BUFFER_SIZE; } let write_buffer = self.get_write_buffer(); - for i in 0..SOUND_BUFFER_SIZE * 2 { - write_buffer[i] = buffer[i].floor().clamp(i8::MIN as i16, i8::MAX as i16) as i8 + unsafe { + agb_rs__mixer_collapse(write_buffer.as_mut_ptr(), buffer.as_ptr()); } } From 8cffa4ae3de0f18609a4ea78f110db811b3118da Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 31 Jul 2021 22:00:41 +0100 Subject: [PATCH 02/16] Better comparison --- agb/src/sound/mixer/sw_mixer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agb/src/sound/mixer/sw_mixer.rs b/agb/src/sound/mixer/sw_mixer.rs index 54ad67c0..f44026bc 100644 --- a/agb/src/sound/mixer/sw_mixer.rs +++ b/agb/src/sound/mixer/sw_mixer.rs @@ -133,7 +133,7 @@ impl MixerBuffer { let right_amount = ((channel.panning + 1) / 2) * channel.volume; let left_amount = ((-channel.panning + 1) / 2) * channel.volume; - if channel.pos + channel.playback_speed * SOUND_BUFFER_SIZE >= channel.data.len().into() + if (channel.pos + channel.playback_speed * SOUND_BUFFER_SIZE).floor() >= channel.data.len() { // TODO: This should probably play what's left rather than skip the last bit if channel.should_loop { From f1b6b1035bdf6f1e90cb367d892df1aa518c5b19 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 31 Jul 2021 22:01:20 +0100 Subject: [PATCH 03/16] Reduce mixer_collapse by 1 instruction --- agb/src/sound/mixer/mixer.s | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 60d10eab..8879376f 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -74,7 +74,7 @@ agb_rs__mixer_collapse: @ r0 = target buffer (i8) @ r1 = input buffer (i16) of fixnums with 4 bits of precision - mov r2, #0 + mov r2, #352 1: @ r12 = *r1; r1++ @@ -88,11 +88,9 @@ agb_rs__mixer_collapse: cmp r12, #2048 @ compare r12 against 2048 movge r3, #127 @ r3 = 127 if r12 >= 2048 - strb r3, [r0, -r2] @ r2 counts down, so need a negative offset + strb r3, [r0], #1 @ *r0 = r3; r0++ - sub r2, r2, #1 @ r2 -= 1 - cmn r2, #352 @ compare r2 against -352 - - bne 1b @ loop if not equal + subs r2, r2, #1 @ r2 -= 1 + bne 1b @ loop if not 0 bx lr From 9f259fdc0a9715827a36806788b0001841be1a83 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sat, 31 Jul 2021 23:18:26 +0100 Subject: [PATCH 04/16] Make clippy happy by using .add rather than .offset --- agb/src/sound/mixer/sw_mixer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agb/src/sound/mixer/sw_mixer.rs b/agb/src/sound/mixer/sw_mixer.rs index f44026bc..333c4550 100644 --- a/agb/src/sound/mixer/sw_mixer.rs +++ b/agb/src/sound/mixer/sw_mixer.rs @@ -146,7 +146,7 @@ impl MixerBuffer { unsafe { agb_rs__mixer_add( - channel.data.as_ptr().offset(channel.pos.floor() as isize), + channel.data.as_ptr().add(channel.pos.floor()), buffer.as_mut_ptr(), channel.playback_speed, left_amount, From cc99aad4c503f84a1900ee54a086c5238c206edb Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:23:05 +0100 Subject: [PATCH 05/16] Move the comments to a nicer place in the file --- agb/src/sound/mixer/mixer.s | 49 ++++++++++++++----------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 8879376f..b228298e 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -16,46 +16,33 @@ agb_rs__mixer_add: push {r4-r10, lr} - @ load the right channel modification amount into lr - ldr lr, [sp, #32] + ldr lr, [sp, #32] @ load the right channel modification amount into lr - @ current write offset into the resulting buffer - mov r12, #0 - mov r8, #352 + mov r12, #0 @ current write offset into the resulting buffer + mov r8, #352 @ the offset for writing to the resulting buffer between left and right channels - @ current index - mov r5, #0 + mov r5, #0 @ current index we're reading from 1: - @ load the current sound buffer location - mov r6, r1 - - @ calculate the address of the next read form the sound buffer - add r4, r0, r5, asr #8 - - @ calculate the position to read the next step from - add r5, r5, r2 + @ r6 = current buffer location, later gets set to the value we're reading and writing from + mov r6, r1 @ load the current sound buffer location - @ load the current buffer value (r6 being the current location, r12 being the offset) - @ but pre-increment r6 by r12 - ldrh r9, [r6, r12]! + add r4, r0, r5, asr #8 @ calculate the address of the next read form the sound buffer + add r5, r5, r2 @ calculate the position to read the next step from - @ load the current value we want to read - ldrsb r10, [r4] + ldrh r9, [r6, r12]! @ load the current buffer value (r6 being the current location, r12 being the offset) + @ but pre-increment r6 by r12 - @ increment the current write offset in the resulting buffer - add r12, r12, #2 + ldrsb r10, [r4] @ load the current value we want to read - @ check if we're done - cmp r12, #352 + add r12, r12, #2 @ increment the current write offset in the resulting buffer - @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value - mla r7, r10, r3, r9 - @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side - strh r7, [r6], r8 + cmp r12, #352 @ check if we're done - @ same for the left hand side (slightly confused here, but this is what was generated) - ldrh r7, [r6] + mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value + strh r7, [r6], r8 @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side + + ldrh r7, [r6] @ same for the right hand side (slightly confused here, but this is what was generated) mla r4, r10, lr, r7 strh r4, [r6] @@ -79,7 +66,7 @@ agb_rs__mixer_collapse: 1: @ r12 = *r1; r1++ ldrsh r12, [r1], #2 - + lsr r3, r12, #4 @ r3 = r12 >> 4 cmn r12, #2048 @ compare r12 against -2048 From 1af53aacb42867f955d7042cb6590ac06e8b0edd Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:23:39 +0100 Subject: [PATCH 06/16] Done check makes sense to go at the end --- agb/src/sound/mixer/mixer.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index b228298e..7aa520fb 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -37,8 +37,6 @@ agb_rs__mixer_add: add r12, r12, #2 @ increment the current write offset in the resulting buffer - cmp r12, #352 @ check if we're done - mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value strh r7, [r6], r8 @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side @@ -46,6 +44,7 @@ agb_rs__mixer_add: mla r4, r10, lr, r7 strh r4, [r6] + cmp r12, #352 @ check if we're done bne 1b pop {r4-r10, lr} From 80e03073fd9f6cc1869ee3e5bf5d2e557275b9af Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:29:45 +0100 Subject: [PATCH 07/16] Reorder the asm instructions to make better sense --- agb/src/sound/mixer/mixer.s | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 7aa520fb..c66922b9 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -24,13 +24,11 @@ agb_rs__mixer_add: mov r5, #0 @ current index we're reading from 1: - @ r6 = current buffer location, later gets set to the value we're reading and writing from - mov r6, r1 @ load the current sound buffer location - add r4, r0, r5, asr #8 @ calculate the address of the next read form the sound buffer add r5, r5, r2 @ calculate the position to read the next step from - ldrh r9, [r6, r12]! @ load the current buffer value (r6 being the current location, r12 being the offset) + mov r6, r1 @ r6 = current buffer location + ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) @ but pre-increment r6 by r12 ldrsb r10, [r4] @ load the current value we want to read From 09ad082f3f202a85b1a103d7729a26cbbe6cb15d Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:41:56 +0100 Subject: [PATCH 08/16] Furter rearranging for more sense making --- agb/src/sound/mixer/mixer.s | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index c66922b9..8c2ebe3b 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -26,15 +26,11 @@ agb_rs__mixer_add: 1: add r4, r0, r5, asr #8 @ calculate the address of the next read form the sound buffer add r5, r5, r2 @ calculate the position to read the next step from - - mov r6, r1 @ r6 = current buffer location - ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) - @ but pre-increment r6 by r12 - ldrsb r10, [r4] @ load the current value we want to read - add r12, r12, #2 @ increment the current write offset in the resulting buffer + mov r6, r1 @ r6 = current buffer location + ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value strh r7, [r6], r8 @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side @@ -42,6 +38,7 @@ agb_rs__mixer_add: mla r4, r10, lr, r7 strh r4, [r6] + add r12, r12, #2 @ increment the current write offset in the resulting buffer cmp r12, #352 @ check if we're done bne 1b From d1c312ab79ec9ca320180deb864a82d11b60dc58 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:44:37 +0100 Subject: [PATCH 09/16] Remove loads of whitespace --- agb/src/sound/mixer/mixer.s | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 8c2ebe3b..595885b7 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -16,30 +16,30 @@ agb_rs__mixer_add: push {r4-r10, lr} - ldr lr, [sp, #32] @ load the right channel modification amount into lr + ldr lr, [sp, #32] @ load the right channel modification amount into lr - mov r12, #0 @ current write offset into the resulting buffer - mov r8, #352 @ the offset for writing to the resulting buffer between left and right channels + mov r12, #0 @ current write offset into the resulting buffer + mov r8, #352 @ the offset for writing to the resulting buffer between left and right channels - mov r5, #0 @ current index we're reading from + mov r5, #0 @ current index we're reading from 1: - add r4, r0, r5, asr #8 @ calculate the address of the next read form the sound buffer - add r5, r5, r2 @ calculate the position to read the next step from - ldrsb r10, [r4] @ load the current value we want to read + add r4, r0, r5, asr #8 @ calculate the address of the next read form the sound buffer + add r5, r5, r2 @ calculate the position to read the next step from + ldrsb r10, [r4] @ load the current value we want to read - mov r6, r1 @ r6 = current buffer location + mov r6, r1 @ r6 = current buffer location - ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 - mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value - strh r7, [r6], r8 @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side + ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 + mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value + strh r7, [r6], r8 @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side - ldrh r7, [r6] @ same for the right hand side (slightly confused here, but this is what was generated) + ldrh r7, [r6] @ same for the right hand side (slightly confused here, but this is what was generated) mla r4, r10, lr, r7 strh r4, [r6] - add r12, r12, #2 @ increment the current write offset in the resulting buffer - cmp r12, #352 @ check if we're done + add r12, r12, #2 @ increment the current write offset in the resulting buffer + cmp r12, #352 @ check if we're done bne 1b pop {r4-r10, lr} From 451f38604d3068ee775478f054ab5fa42e37bbfd Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:45:57 +0100 Subject: [PATCH 10/16] Add an explicit .pool at the end of the mixer --- agb/src/sound/mixer/mixer.s | 1 + 1 file changed, 1 insertion(+) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 595885b7..c3cd29af 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -75,3 +75,4 @@ agb_rs__mixer_collapse: bne 1b @ loop if not 0 bx lr +.pool \ No newline at end of file From 18d96e4349fefbb29c7614ca7761f6202849a98f Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:50:52 +0100 Subject: [PATCH 11/16] Update comments now I understand what's happening --- agb/src/sound/mixer/mixer.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index c3cd29af..69399f33 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -32,9 +32,9 @@ agb_rs__mixer_add: ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value - strh r7, [r6], r8 @ *(r6 + r8) = r7, r8 = 352 = offset for the right hand side + strh r7, [r6], r8 @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side - ldrh r7, [r6] @ same for the right hand side (slightly confused here, but this is what was generated) + ldrh r7, [r6] @ same for the right hand side, r6 now points to the right hand side location mla r4, r10, lr, r7 strh r4, [r6] From 2db696f8bf9a2df5e2029ce1eb68728bce932ce8 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 20:59:01 +0100 Subject: [PATCH 12/16] reuse r4 --- agb/src/sound/mixer/mixer.s | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 69399f33..3b16eeb5 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -23,15 +23,21 @@ agb_rs__mixer_add: mov r5, #0 @ current index we're reading from + @ kept between iterations: + @ r12 - current write offset into the output buffer (r1) + @ r8 - the constant 352 + @ r5 - the current index from the input buffer we're reading from (r0) + + @ all other registers are temporary 1: add r4, r0, r5, asr #8 @ calculate the address of the next read form the sound buffer - add r5, r5, r2 @ calculate the position to read the next step from ldrsb r10, [r4] @ load the current value we want to read + add r5, r5, r2 @ calculate the position to read the next step from mov r6, r1 @ r6 = current buffer location - ldrh r9, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 - mla r7, r10, r3, r9 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value + ldrh r4, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 + mla r7, r10, r3, r4 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value strh r7, [r6], r8 @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side ldrh r7, [r6] @ same for the right hand side, r6 now points to the right hand side location From cce3ecdde5becac51e7d2cec5dbe40b59b2dacc9 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 21:00:49 +0100 Subject: [PATCH 13/16] Use r9 rather than lr --- agb/src/sound/mixer/mixer.s | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 3b16eeb5..e52b59b7 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -12,11 +12,11 @@ agb_rs__mixer_add: @ @ The sound buffer must be SOUND_BUFFER_SIZE * 2 in size = 176 * 2 - @ lr = amount to modify right channel by + @ r9 = amount to modify right channel by - push {r4-r10, lr} + push {r4-r10} - ldr lr, [sp, #32] @ load the right channel modification amount into lr + ldr r9, [sp, #28] @ load the right channel modification amount into r9 mov r12, #0 @ current write offset into the resulting buffer mov r8, #352 @ the offset for writing to the resulting buffer between left and right channels @@ -41,14 +41,14 @@ agb_rs__mixer_add: strh r7, [r6], r8 @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side ldrh r7, [r6] @ same for the right hand side, r6 now points to the right hand side location - mla r4, r10, lr, r7 + mla r4, r10, r9, r7 strh r4, [r6] add r12, r12, #2 @ increment the current write offset in the resulting buffer cmp r12, #352 @ check if we're done bne 1b - pop {r4-r10, lr} + pop {r4-r10} bx lr .pool From 809d3f52ee81bdb34999bbc84784ee38cc0f4887 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 21:01:59 +0100 Subject: [PATCH 14/16] update the comment about what's kept between iterations --- agb/src/sound/mixer/mixer.s | 2 ++ 1 file changed, 2 insertions(+) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index e52b59b7..8acc9f75 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -25,8 +25,10 @@ agb_rs__mixer_add: @ kept between iterations: @ r12 - current write offset into the output buffer (r1) + @ r9 - the amount to modify the right channel by @ r8 - the constant 352 @ r5 - the current index from the input buffer we're reading from (r0) + @ the provided arguments are all unmodified @ all other registers are temporary 1: From ec65b18fd271a4f36c5c33caebd2f1d5dfe9b991 Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 21:23:31 +0100 Subject: [PATCH 15/16] Make the str consistent with the ldr --- agb/src/sound/mixer/mixer.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 8acc9f75..4784fc15 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -40,7 +40,7 @@ agb_rs__mixer_add: ldrh r4, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 mla r7, r10, r3, r4 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value - strh r7, [r6], r8 @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side + strh r7, [r6, r8] @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side ldrh r7, [r6] @ same for the right hand side, r6 now points to the right hand side location mla r4, r10, r9, r7 From ac8e2dfe9d5815b5067bde514a97b4257ca48b1b Mon Sep 17 00:00:00 2001 From: Gwilym Kuiper Date: Sun, 1 Aug 2021 21:29:44 +0100 Subject: [PATCH 16/16] Go back to the other way of addressing as they aren't equivalent --- agb/src/sound/mixer/mixer.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agb/src/sound/mixer/mixer.s b/agb/src/sound/mixer/mixer.s index 4784fc15..8acc9f75 100644 --- a/agb/src/sound/mixer/mixer.s +++ b/agb/src/sound/mixer/mixer.s @@ -40,7 +40,7 @@ agb_rs__mixer_add: ldrh r4, [r6, r12]! @ load the current buffer value (r12 being the offset) but pre-increment r6 by r12 mla r7, r10, r3, r4 @ r7 = r10 * r3 + r9 = current sound value * left amount + previous buffer value - strh r7, [r6, r8] @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side + strh r7, [r6], r8 @ *r6 = r7, r6 += r8 where r8 = 352 = offset for the right hand side ldrh r7, [r6] @ same for the right hand side, r6 now points to the right hand side location mla r4, r10, r9, r7