Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.4 kB · 165 lines
Rust
at sans-io
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166use core::slice;use std::{ array, ops::{Div, DivAssign, IndexMut},};
use dasp::sample::ToSample;
pub(crate) mod instrument;pub mod playback;pub(crate) mod sample;
pub use sample::Interpolation;
#[repr(transparent)]#[derive(Clone, Copy, Default, Debug, PartialEq)]pub struct Frame([f32; 2]);
impl std::ops::AddAssign for Frame { fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; }}
impl std::ops::Add for Frame { type Output = Self;
fn add(self, rhs: Self) -> Self::Output { Self([self.0[0] + rhs.0[0], self.0[1] + rhs.0[1]]) }}
impl std::ops::Sub for Frame { type Output = Self;
fn sub(self, rhs: Self) -> Self::Output { Self([self.0[0] - rhs.0[0], self.0[1] - rhs.0[1]]) }}
impl std::ops::SubAssign for Frame { fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; }}
impl std::ops::MulAssign<f32> for Frame { fn mul_assign(&mut self, rhs: f32) { *self.0.index_mut(0) *= rhs; *self.0.index_mut(1) *= rhs; }}
impl std::ops::Mul<f32> for Frame { type Output = Self;
fn mul(self, rhs: f32) -> Self::Output { Self([self.0[0] * rhs, self.0[1] * rhs]) }}
impl Div<f32> for Frame { type Output = Frame;
fn div(self, rhs: f32) -> Self::Output { Self([self.0[0] / rhs, self.0[1] / rhs]) }}
impl DivAssign<f32> for Frame { fn div_assign(&mut self, rhs: f32) { *self.0.index_mut(0) *= rhs; *self.0.index_mut(1) *= rhs; }}
impl crate::sample::ProcessingFrame for Frame { fn mul_add(self, mul: f32, add: Self) -> Self { Self([ f32::mul_add(self.0[0], mul, add.0[0]), f32::mul_add(self.0[1], mul, add.0[1]), ]) }}
impl std::iter::Sum for Frame { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { iter.reduce(|acc, x| acc + x).unwrap_or_default() }}
impl From<[f32; 2]> for Frame { fn from(value: [f32; 2]) -> Self { Self(value) }}
impl From<f32> for Frame { fn from(value: f32) -> Self { Self([value, value]) }}
impl Frame { // split into left and right. pub fn split_array<const N: usize>(value: [Frame; N]) -> ([f32; N], [f32; N]) { ( array::from_fn(|i| value[i].0[0]), array::from_fn(|i| value[i].0[1]), ) }
pub fn sum_to_mono(self) -> f32 { self.0[0] + self.0[1] }
pub fn from_mut<'a>(value: &'a mut [f32; 2]) -> &'a mut Self { // SAFETY: lifetime is specified, both mut, Self is repr(transparent). unsafe { std::mem::transmute::<&'a mut [f32; 2], &'a mut Self>(value) } }
pub fn from_interleaved(value: &[f32]) -> &[Frame] { debug_assert!(value.len().rem_euclid(2) == 0); let len = value.len() / 2; let ptr = value.as_ptr().cast(); // SAFETY: keeps the same lifetime and mutability. // [f32; 2] is a valid frame unsafe { slice::from_raw_parts(ptr, len) } }
pub fn from_ref<'a>(value: &'a [f32; 2]) -> &'a Self { // SAFETY: lifetime is specified, both not mut, Self is repr(transparent). unsafe { std::mem::transmute::<&'a [f32; 2], &'a Self>(value) } }
pub fn to_sample<S: dasp::sample::FromSample<f32>>(self) -> [S; 2] { [self.0[0].to_sample_(), self.0[1].to_sample_()] }
pub fn to_raw<'a>(into: &mut [Self]) -> &'a mut [[f32; 2]] { unsafe { std::mem::transmute(into) } }
// pan laws taken from: https://www.cs.cmu.edu/~music/icm-online/readings/panlaws/index.html
// /// angle in radians between 0 and 90° // pub fn pan_linear(&mut self, angle: f32) { // self.0[0] *= (std::f32::consts::FRAC_PI_2 - angle) * std::f32::consts::FRAC_2_PI; // self.0[1] *= angle * std::f32::consts::FRAC_2_PI; // }
/// angle in radians between 0 and 90° pub fn pan_constant_power(&mut self, angle: f32) { self.0[0] *= angle.cos(); self.0[1] *= angle.sin(); }
// /// angle in radians between 0 and 90° // pub fn pan_compromise(&mut self, angle: f32) { // self.0[0] *= f32::sqrt( // (std::f32::consts::FRAC_PI_2 - angle) * std::f32::consts::FRAC_2_PI * angle.cos(), // ); // self.0[1] *= f32::sqrt(angle * std::f32::consts::FRAC_2_PI * angle.sin()); // }}