mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 17:41:33 +11:00
Add support for stereo sound
This commit is contained in:
parent
8a0bb13dba
commit
5bd656d8cb
|
@ -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
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
|
||||
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(),
|
||||
channel.playback_speed,
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue