Add support for stereo sound

This commit is contained in:
Gwilym Kuiper 2021-10-26 22:14:34 +01:00
parent 8a0bb13dba
commit 5bd656d8cb
2 changed files with 68 additions and 12 deletions

View file

@ -93,6 +93,46 @@ same_modification:
agb_arm_end agb_rs__mixer_add
agb_arm_func agb_rs__mixer_add_stereo
@ Arguments
@ r0 - pointer to the data to be copied (u8 array)
@ r1 - pointer to the sound buffer (i16 array which will alternate left and right channels, 32-bit aligned)
@
@ The sound buffer must be SOUND_BUFFER_SIZE * 2 in size = 176 * 2
push {r4-r8}
ldr r5, =0x0000FFFF
.macro mixer_add_loop_simple_stereo
ldrsh r6, [r0], #2 @ load the current sound sample to r6
ldr r4, [r1] @ read the current value
mov r7, r6, asr #8
and r7, r7, r5
lsl r6, r6, #24
orr r6, r7, r6, asr #8
add r4, r4, r6, lsl #4 @ r4 += r6 << 4 (calculating both the left and right samples together)
str r4, [r1], #4 @ store the new value, and increment the pointer
.endm
mov r8, #SOUND_BUFFER_SIZE
1:
mixer_add_loop_simple_stereo
mixer_add_loop_simple_stereo
mixer_add_loop_simple_stereo
mixer_add_loop_simple_stereo
subs r8, r8, #4 @ loop counter
bne 1b @ jump back if we're done with the loop
pop {r4-r8}
bx lr
agb_arm_end agb_rs__mixer_add_stereo
.macro clamp_s8 reg:req
cmn \reg, #127
mvnlt \reg, #127

View file

@ -13,6 +13,8 @@ extern "C" {
right_amount: Num<i16, 4>,
);
fn agb_rs__mixer_add_stereo(sound_data: *const u8, sound_buffer: *mut Num<i16, 4>);
fn agb_rs__mixer_collapse(sound_buffer: *mut i8, input_buffer: *const Num<i16, 4>);
}
@ -133,12 +135,16 @@ impl MixerBuffer {
continue;
}
let playback_speed = if channel.is_stereo {
2.into()
} else {
channel.playback_speed
};
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).floor()
>= channel.data.len()
{
if (channel.pos + 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 {
channel.pos -= channel.data.len();
@ -148,16 +154,26 @@ impl MixerBuffer {
}
}
unsafe {
agb_rs__mixer_add(
channel.data.as_ptr().add(channel.pos.floor()),
buffer.as_mut_ptr(),
channel.playback_speed,
left_amount,
right_amount,
);
if channel.is_stereo {
unsafe {
agb_rs__mixer_add_stereo(
channel.data.as_ptr().add(channel.pos.floor()),
buffer.as_mut_ptr(),
);
}
} else {
unsafe {
agb_rs__mixer_add(
channel.data.as_ptr().add(channel.pos.floor()),
buffer.as_mut_ptr(),
playback_speed,
left_amount,
right_amount,
);
}
}
channel.pos += channel.playback_speed * SOUND_BUFFER_SIZE;
channel.pos += playback_speed * SOUND_BUFFER_SIZE;
}
let write_buffer = self.get_write_buffer();