Upcast multiply (#436)

- [ ] Changelog updated / no changelog update needed
This commit is contained in:
Corwin 2023-06-05 21:00:46 +01:00 committed by GitHub
commit 53937b4fa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 22 deletions

View file

@ -79,6 +79,8 @@ pub trait FixedWidthUnsignedInteger:
fn ten() -> Self; fn ten() -> Self;
/// Converts an i32 to it's own representation, panics on failure /// Converts an i32 to it's own representation, panics on failure
fn from_as_i32(v: i32) -> Self; fn from_as_i32(v: i32) -> Self;
/// Returns (a * b) >> N
fn upcast_multiply(a: Self, b: Self, n: usize) -> Self;
} }
/// Trait for an integer that includes negation /// Trait for an integer that includes negation
@ -89,7 +91,7 @@ pub trait FixedWidthSignedInteger: FixedWidthUnsignedInteger + Neg<Output = Self
} }
macro_rules! fixed_width_unsigned_integer_impl { macro_rules! fixed_width_unsigned_integer_impl {
($T: ty) => { ($T: ty, $Upcast: ty) => {
impl FixedWidthUnsignedInteger for $T { impl FixedWidthUnsignedInteger for $T {
#[inline(always)] #[inline(always)]
fn zero() -> Self { fn zero() -> Self {
@ -107,6 +109,10 @@ macro_rules! fixed_width_unsigned_integer_impl {
fn from_as_i32(v: i32) -> Self { fn from_as_i32(v: i32) -> Self {
v as $T v as $T
} }
#[inline(always)]
fn upcast_multiply(a: Self, b: Self, n: usize) -> Self {
(((a as $Upcast) * (b as $Upcast)) >> n) as $T
}
} }
}; };
} }
@ -122,12 +128,11 @@ macro_rules! fixed_width_signed_integer_impl {
}; };
} }
fixed_width_unsigned_integer_impl!(u8); fixed_width_unsigned_integer_impl!(u8, u32);
fixed_width_unsigned_integer_impl!(i16); fixed_width_unsigned_integer_impl!(i16, i32);
fixed_width_unsigned_integer_impl!(u16); fixed_width_unsigned_integer_impl!(u16, u32);
fixed_width_unsigned_integer_impl!(i32); fixed_width_unsigned_integer_impl!(i32, i64);
fixed_width_unsigned_integer_impl!(u32); fixed_width_unsigned_integer_impl!(u32, u64);
fixed_width_unsigned_integer_impl!(usize);
fixed_width_signed_integer_impl!(i16); fixed_width_signed_integer_impl!(i16);
fixed_width_signed_integer_impl!(i32); fixed_width_signed_integer_impl!(i32);
@ -204,9 +209,7 @@ where
{ {
type Output = Self; type Output = Self;
fn mul(self, rhs: Num<I, N>) -> Self::Output { fn mul(self, rhs: Num<I, N>) -> Self::Output {
Num(((self.floor() * rhs.floor()) << N) Num(I::upcast_multiply(self.0, rhs.0, N))
+ (self.floor() * rhs.frac() + rhs.floor() * self.frac())
+ ((self.frac() * rhs.frac()) >> N))
} }
} }

View file

@ -26,7 +26,7 @@ fn main(mut gba: Gba) -> ! {
{ {
if let Some(channel) = mixer.channel(&channel_id) { if let Some(channel) = mixer.channel(&channel_id) {
let half: Num<i16, 4> = num!(0.5); let half: Num<i16, 4> = num!(0.5);
let half_usize: Num<usize, 8> = num!(0.5); let half_usize: Num<u32, 8> = num!(0.5);
match input.x_tri() { match input.x_tri() {
Tri::Negative => channel.panning(-half), Tri::Negative => channel.panning(-half),
Tri::Zero => channel.panning(0), Tri::Zero => channel.panning(0),

View file

@ -224,10 +224,10 @@ impl Frequency {
/// ``` /// ```
pub struct SoundChannel { pub struct SoundChannel {
data: &'static [u8], data: &'static [u8],
pos: Num<usize, 8>, pos: Num<u32, 8>,
should_loop: bool, should_loop: bool,
playback_speed: Num<usize, 8>, playback_speed: Num<u32, 8>,
volume: Num<i16, 4>, // between 0 and 1 volume: Num<i16, 4>, // between 0 and 1
panning: Num<i16, 4>, // between -1 and 1 panning: Num<i16, 4>, // between -1 and 1
@ -336,7 +336,7 @@ impl SoundChannel {
/// Note that this only works for mono sounds. Stereo sounds will not change /// Note that this only works for mono sounds. Stereo sounds will not change
/// how fast they play. /// how fast they play.
#[inline(always)] #[inline(always)]
pub fn playback(&mut self, playback_speed: impl Into<Num<usize, 8>>) -> &mut Self { pub fn playback(&mut self, playback_speed: impl Into<Num<u32, 8>>) -> &mut Self {
self.playback_speed = playback_speed.into(); self.playback_speed = playback_speed.into();
self self
} }
@ -392,13 +392,13 @@ impl SoundChannel {
/// Gets how far along the sound has played. /// Gets how far along the sound has played.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn pos(&self) -> Num<usize, 8> { pub fn pos(&self) -> Num<u32, 8> {
self.pos self.pos
} }
/// Sets the playback position /// Sets the playback position
#[inline] #[inline]
pub fn set_pos(&mut self, pos: impl Into<Num<usize, 8>>) -> &mut Self { pub fn set_pos(&mut self, pos: impl Into<Num<u32, 8>>) -> &mut Self {
self.pos = pos.into(); self.pos = pos.into();
self self
} }

View file

@ -24,7 +24,7 @@ extern "C" {
fn agb_rs__mixer_add( fn agb_rs__mixer_add(
sound_data: *const u8, sound_data: *const u8,
sound_buffer: *mut Num<i16, 4>, sound_buffer: *mut Num<i16, 4>,
playback_speed: Num<usize, 8>, playback_speed: Num<u32, 8>,
left_amount: Num<i16, 4>, left_amount: Num<i16, 4>,
right_amount: Num<i16, 4>, right_amount: Num<i16, 4>,
); );
@ -415,8 +415,8 @@ impl MixerBuffer {
channel.playback_speed channel.playback_speed
}; };
if (channel.pos + playback_speed * self.frequency.buffer_size()).floor() if (channel.pos + playback_speed * self.frequency.buffer_size() as u32).floor()
>= channel.data.len() >= channel.data.len() as u32
{ {
// TODO: This should probably play what's left rather than skip the last bit // TODO: This should probably play what's left rather than skip the last bit
if channel.should_loop { if channel.should_loop {
@ -431,7 +431,7 @@ impl MixerBuffer {
if channel.is_stereo { if channel.is_stereo {
unsafe { unsafe {
agb_rs__mixer_add_stereo( agb_rs__mixer_add_stereo(
channel.data.as_ptr().add(channel.pos.floor()), channel.data.as_ptr().add(channel.pos.floor() as usize),
working_buffer.as_mut_ptr(), working_buffer.as_mut_ptr(),
channel.volume, channel.volume,
); );
@ -442,7 +442,7 @@ impl MixerBuffer {
unsafe { unsafe {
agb_rs__mixer_add( agb_rs__mixer_add(
channel.data.as_ptr().add(channel.pos.floor()), channel.data.as_ptr().add(channel.pos.floor() as usize),
working_buffer.as_mut_ptr(), working_buffer.as_mut_ptr(),
playback_speed, playback_speed,
left_amount, left_amount,
@ -452,7 +452,7 @@ impl MixerBuffer {
} }
} }
channel.pos += playback_speed * self.frequency.buffer_size(); channel.pos += playback_speed * self.frequency.buffer_size() as u32;
} }
let write_buffer = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced()); let write_buffer = free(|cs| self.state.borrow(cs).borrow_mut().active_advanced());