#![allow(clippy::type_complexity)]
use crate::prelude::*;
use futuredsp::ComputationStatus;
use futuredsp::IirFilter;
use futuredsp::prelude::*;
#[derive(Block)]
pub struct Iir<
InputType,
OutputType,
TapsType,
Core,
I = DefaultCpuReader<InputType>,
O = DefaultCpuWriter<OutputType>,
> where
InputType: 'static + Send,
OutputType: 'static + Send,
TapsType: 'static + Send + Taps,
Core: 'static + StatefulFilter<InputType, OutputType, TapsType::TapType> + Send,
I: CpuBufferReader<Item = InputType>,
O: CpuBufferWriter<Item = OutputType>,
{
#[input]
input: I,
#[output]
output: O,
core: Core,
_tap_type: std::marker::PhantomData<TapsType>,
}
impl<InputType, OutputType, TapsType, I, O>
Iir<InputType, OutputType, TapsType, IirFilter<InputType, OutputType, TapsType>, I, O>
where
InputType: 'static + Send,
OutputType: 'static + Send,
TapsType: 'static + Send + Taps,
IirFilter<InputType, OutputType, TapsType>:
StatefulFilter<InputType, OutputType, TapsType::TapType>,
I: CpuBufferReader<Item = InputType>,
O: CpuBufferWriter<Item = OutputType>,
{
pub fn new(
a_taps: TapsType,
b_taps: TapsType,
) -> Iir<InputType, OutputType, TapsType, IirFilter<InputType, OutputType, TapsType>, I, O>
{
Iir::with_core(IirFilter::new(a_taps, b_taps))
}
}
impl<InputType, OutputType, TapsType, Core, I, O> Iir<InputType, OutputType, TapsType, Core, I, O>
where
InputType: 'static + Send,
OutputType: 'static + Send,
TapsType: 'static + Send + Taps,
Core: 'static + StatefulFilter<InputType, OutputType, TapsType::TapType> + Send,
IirFilter<InputType, OutputType, TapsType>:
StatefulFilter<InputType, OutputType, TapsType::TapType>,
I: CpuBufferReader<Item = InputType>,
O: CpuBufferWriter<Item = OutputType>,
{
pub fn with_core(core: Core) -> Self {
let mut input = I::default();
input.set_min_items(core.length());
Self {
input,
output: O::default(),
core,
_tap_type: std::marker::PhantomData,
}
}
}
#[doc(hidden)]
impl<InputType, OutputType, TapsType, Core, I, O> Kernel
for Iir<InputType, OutputType, TapsType, Core, I, O>
where
InputType: 'static + Send,
OutputType: 'static + Send,
TapsType: 'static + Send + Taps,
Core: 'static + StatefulFilter<InputType, OutputType, TapsType::TapType> + Send,
IirFilter<InputType, OutputType, TapsType>:
StatefulFilter<InputType, OutputType, TapsType::TapType>,
I: CpuBufferReader<Item = InputType>,
O: CpuBufferWriter<Item = OutputType>,
{
async fn work(
&mut self,
io: &mut WorkIo,
_mio: &mut MessageOutputs,
_meta: &mut BlockMeta,
) -> Result<()> {
let i = self.input.slice();
let o = self.output.slice();
let (consumed, produced, status) = self.core.filter(i, o);
self.input.consume(consumed);
self.output.produce(produced);
if self.input.finished() && !matches!(status, ComputationStatus::InsufficientOutput) {
io.finished = true;
}
Ok(())
}
}