use std::{
f32::consts::SQRT_2,
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Frame {
pub left: f32,
pub right: f32,
}
impl Frame {
pub const ZERO: Frame = Frame {
left: 0.0,
right: 0.0,
};
pub fn new(left: f32, right: f32) -> Self {
Self { left, right }
}
pub fn from_mono(value: f32) -> Self {
Self::new(value, value)
}
#[allow(clippy::float_cmp)]
pub fn panned(self, x: f32) -> Self {
if x == 0.5 {
return self;
}
Self::new(self.left * (1.0 - x).sqrt(), self.right * x.sqrt()) * SQRT_2
}
}
impl Add for Frame {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::new(self.left + rhs.left, self.right + rhs.right)
}
}
impl AddAssign for Frame {
fn add_assign(&mut self, rhs: Self) {
self.left += rhs.left;
self.right += rhs.right;
}
}
impl Sub for Frame {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self::new(self.left - rhs.left, self.right - rhs.right)
}
}
impl SubAssign for Frame {
fn sub_assign(&mut self, rhs: Self) {
self.left -= rhs.left;
self.right -= rhs.right;
}
}
impl Mul<f32> for Frame {
type Output = Self;
fn mul(self, rhs: f32) -> Self::Output {
Self::new(self.left * rhs, self.right * rhs)
}
}
impl MulAssign<f32> for Frame {
fn mul_assign(&mut self, rhs: f32) {
self.left *= rhs;
self.right *= rhs;
}
}
impl Div<f32> for Frame {
type Output = Self;
fn div(self, rhs: f32) -> Self::Output {
Self::new(self.left / rhs, self.right / rhs)
}
}
impl DivAssign<f32> for Frame {
fn div_assign(&mut self, rhs: f32) {
self.left /= rhs;
self.right /= rhs;
}
}
impl Neg for Frame {
type Output = Self;
fn neg(self) -> Self::Output {
Self::new(-self.left, -self.right)
}
}