use crate::prelude::*;
mod coefficients;
mod design;
pub use coefficients::*;
pub use design::*;
pub trait FilterMap {
fn eval<A: Audio, I: Ring, O: Ring>(&self, inputs: &I, outputs: &O) -> A
where
I::Buf: buf::BufferMut<Item = A>,
O::Buf: buf::BufferMut<Item = A>;
}
pub struct Filter<A: Audio, I: Ring, O: Ring, F: FilterMap>
where
I::Buf: buf::BufferMut<Item = A>,
O::Buf: buf::BufferMut<Item = A>,
{
pub func: F,
inputs: I,
outputs: O,
}
impl<A: Audio, I: Ring, O: Ring, F: FilterMap> Filter<A, I, O, F>
where
I::Buf: buf::BufferMut<Item = A>,
O::Buf: buf::BufferMut<Item = A>,
{
pub const fn new_prev(func: F, inputs: I, outputs: O) -> Self {
Self {
func,
inputs,
outputs,
}
}
pub fn eval(&mut self, input: A) -> A {
self.inputs.push(input);
let output = self.func.eval(&self.inputs, &self.outputs);
self.outputs.push(output);
output
}
pub const fn inputs(&self) -> &I {
&self.inputs
}
pub const fn outputs(&self) -> &O {
&self.outputs
}
pub fn get(&self) -> A {
self.outputs.fst()
}
pub fn retrigger(&mut self) {
self.inputs.clear();
self.outputs.clear();
}
}
pub struct Filtered<S: Signal, I: Ring, O: Ring, F: FilterMap>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
pub sgn: S,
pub filter: Filter<S::Sample, I, O, F>,
}
impl<S: Signal, I: Ring, O: Ring, F: FilterMap> Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
pub const fn new(sgn: S, filter: Filter<S::Sample, I, O, F>) -> Self {
Self { sgn, filter }
}
pub const fn func(&self) -> &F {
&self.filter.func
}
pub fn func_mut(&mut self) -> &mut F {
&mut self.filter.func
}
}
impl<S: Signal, I: Ring, O: Ring, F: FilterMap> Signal for Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
type Sample = S::Sample;
fn get(&self) -> S::Sample {
self.filter.get()
}
}
impl<S: SignalMut, I: Ring, O: Ring, F: FilterMap> SignalMut for Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
fn advance(&mut self) {
self.next();
}
fn retrigger(&mut self) {
self.sgn.retrigger();
self.filter.retrigger();
}
fn next(&mut self) -> S::Sample {
self.filter.eval(self.sgn.next())
}
}
impl<S: Base, I: Ring, O: Ring, F: FilterMap> Base for Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
type Base = S::Base;
fn base(&self) -> &Self::Base {
self.sgn.base()
}
fn base_mut(&mut self) -> &mut Self::Base {
self.sgn.base_mut()
}
}
impl<S: Stop, I: Ring, O: Ring, F: FilterMap> Stop for Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
fn stop(&mut self) {
self.sgn.stop();
}
}
impl<S: Panic, I: Ring, O: Ring, F: FilterMap> Panic for Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: buf::BufferMut<Item = S::Sample>,
O::Buf: buf::BufferMut<Item = S::Sample>,
{
fn panic(&mut self) {
self.sgn.panic();
self.filter.inputs.clear();
self.filter.outputs.clear();
}
}
impl<S: Done, I: Ring, O: Ring, F: FilterMap> Done for Filtered<S, I, O, F>
where
S::Sample: Audio,
I::Buf: BufferMut<Item = S::Sample>,
O::Buf: BufferMut<Item = S::Sample>,
{
fn is_done(&self) -> bool {
self.sgn.is_done()
}
}
impl<S: Signal, I: Ring, O: Ring, T: Coefficients, U: Coefficients> Filtered<S, I, O, DiffEq<T, U>>
where
S::Sample: Audio,
I::Buf: BufferMut<Item = S::Sample>,
O::Buf: BufferMut<Item = S::Sample>,
{
pub fn coefs(&self) -> &DiffEq<T, U> {
self.func()
}
pub fn coefs_mut(&mut self) -> &mut DiffEq<T, U> {
self.func_mut()
}
}
pub type LoFilter<A, const T: usize, const U: usize> =
Filter<A, buf::Shift<buf::Stc<A, T>>, buf::Shift<buf::Stc<A, U>>, LoDiffEq<T, U>>;
impl<A: Audio, const T: usize, const U: usize> LoFilter<A, T, U> {
#[must_use]
pub const fn new_coefs(coefs: LoDiffEq<T, U>) -> Self {
Self::new_prev(
coefs,
buf::Shift::new(buf::Stc::new()),
buf::Shift::new(buf::Stc::new()),
)
}
}
pub type LoFiltered<S, const T: usize, const U: usize> = Filtered<
S,
buf::Shift<buf::Stc<<S as Signal>::Sample, T>>,
buf::Shift<buf::Stc<<S as Signal>::Sample, U>>,
LoDiffEq<T, U>,
>;
impl<S: Signal, const T: usize, const U: usize> LoFiltered<S, T, U>
where
S::Sample: Audio,
{
pub const fn new_coefs(sgn: S, coefs: LoDiffEq<T, U>) -> Self {
Self::new(sgn, LoFilter::new_coefs(coefs))
}
}