1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
//! Defines filters and their coefficients.

use crate::prelude::*;

mod coefficients;
mod design;
pub use coefficients::*;
pub use design::*;

/// A trait for a filter's function.
///
/// A `FilterMap` returns an audio sample, given ring buffers for the previous inputs and outputs.
/// These might need to have a minimum length in order to avoid panicking.
pub trait FilterMap {
    /// Evaluates the function, given the previous inputs and outputs.
    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>;
}

/// In its most general form, a filter is defined by its previous inputs, its previous outputs, and
/// a function that maps these to a new output. Traditionally, this function would take the form of
/// a difference equation [`DiffEq`],
///
/// The inputs and outputs can be stored in any kind of ring buffer. These include [`buf::Shift`]
/// and [`buf::Circ`], where the former is preferred for very small buffers, while the latter is
/// preferred otherwise. You may also use [`buf::EmptyRing`] if you want to ignore the
/// inputs/outputs, at no cost.
pub struct Filter<A: Audio, I: Ring, O: Ring, F: FilterMap>
where
    I::Buf: buf::BufferMut<Item = A>,
    O::Buf: buf::BufferMut<Item = A>,
{
    /// The filter map.
    pub func: F,
    /// Previous inputs to the filter.
    inputs: I,
    /// Previous outputs to the filter.
    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>,
{
    /// Initializes a filter with given preconditions.
    pub const fn new_prev(func: F, inputs: I, outputs: O) -> Self {
        Self {
            func,
            inputs,
            outputs,
        }
    }

    /// Takes in a new input, returns a new output.
    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
    }

    /// A reference to the previous input values.
    pub const fn inputs(&self) -> &I {
        &self.inputs
    }

    /// A reference to the previous output values.
    pub const fn outputs(&self) -> &O {
        &self.outputs
    }

    /// Gets the last output value.
    pub fn get(&self) -> A {
        self.outputs.fst()
    }

    /// Resets the previous values to zero.
    pub fn retrigger(&mut self) {
        self.inputs.clear();
        self.outputs.clear();
    }
}

/// Filters a [`Signal`] through a [`Filter`].
///
/// Note that the implementation of [`Done`] assumes that the filtered signal stops right after the
/// original. This isn't exactly accurate, even for the simplest filters, but it should be
/// approximately so in practice.
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>,
{
    /// The filtered signal.
    pub sgn: S,
    /// The filter employed.
    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>,
{
    /// Initializes a [`Filtered`] signal.
    pub const fn new(sgn: S, filter: Filter<S::Sample, I, O, F>) -> Self {
        Self { sgn, filter }
    }

    /// Returns the current filter function.
    pub const fn func(&self) -> &F {
        &self.filter.func
    }

    /// Returns a mutable reference to the current filter function.
    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()
    }
}

/// Aliases for [`Filtered::func`] and [`Filtered::func_mut`].
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>,
{
    /// Returns the coefficients of the filter.
    pub fn coefs(&self) -> &DiffEq<T, U> {
        self.func()
    }

    /// Returns a mutable reference to the coefficients of the filter.
    pub fn coefs_mut(&mut self) -> &mut DiffEq<T, U> {
        self.func_mut()
    }
}

/// A low order filter defined by its [`Coefficients`]. **This is not the same as a low-pass!**
///
/// This is recommended only for simple filters like biquads, as it makes use of a [`buf::Shift`]
/// buffer. Higher order filters can be implemented in more than one way, and you'll probably want
/// to build your [`Filter`] manually.
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> {
    /// Initializes a [`LoFilter`] from its coefficients.
    #[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()),
        )
    }
}

/// Filters a signal through a [`LoFilter`]. **This is not the same as a low-pass!**
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,
{
    /// Initializes a [`LoFilter`] from its coefficients.
    pub const fn new_coefs(sgn: S, coefs: LoDiffEq<T, U>) -> Self {
        Self::new(sgn, LoFilter::new_coefs(coefs))
    }
}