use crate::Signal;
use dasp_frame::Frame;
use dasp_ring_buffer as ring_buffer;
use dasp_rms as rms;
pub trait SignalRms: Signal {
fn rms<S>(self, ring_buffer: ring_buffer::Fixed<S>) -> Rms<Self, S>
where
Self: Sized,
S: ring_buffer::Slice<Element = <Self::Frame as Frame>::Float> + ring_buffer::SliceMut,
{
Rms {
signal: self,
rms: rms::Rms::new(ring_buffer),
}
}
}
#[derive(Clone)]
pub struct Rms<S, D>
where
S: Signal,
D: ring_buffer::Slice<Element = <S::Frame as Frame>::Float>,
{
signal: S,
rms: rms::Rms<S::Frame, D>,
}
impl<S, D> Rms<S, D>
where
S: Signal,
D: ring_buffer::Slice<Element = <S::Frame as Frame>::Float> + ring_buffer::SliceMut,
{
pub fn next_squared(&mut self) -> <Self as Signal>::Frame {
self.rms.next_squared(self.signal.next())
}
pub fn into_parts(self) -> (S, rms::Rms<S::Frame, D>) {
let Rms { signal, rms } = self;
(signal, rms)
}
}
impl<S, D> Signal for Rms<S, D>
where
S: Signal,
D: ring_buffer::Slice<Element = <S::Frame as Frame>::Float> + ring_buffer::SliceMut,
{
type Frame = <S::Frame as Frame>::Float;
fn next(&mut self) -> Self::Frame {
self.rms.next(self.signal.next())
}
fn is_exhausted(&self) -> bool {
self.signal.is_exhausted()
}
}
impl<T> SignalRms for T where T: Signal {}