euphony-store 0.1.1

storage component for rendered output
Documentation
use crate::{
    dc::LeakDc,
    storage::{self, Storage},
};
use core::fmt;
use euphony_node::Sink;
use euphony_units::coordinates::{Cartesian, Polar};

pub struct Writer<O: storage::Output> {
    leak_dc: LeakDc,
    samples: O,
    coordinates: O,
    sink: O,
}

impl<W: storage::Output> fmt::Debug for Writer<W> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("RawWriter").finish()
    }
}

impl<O: storage::Output> Writer<O> {
    pub fn new<S: Storage<Output = O>>(storage: &mut S, sink: O) -> Self {
        Self {
            leak_dc: Default::default(),
            samples: storage.create(),
            coordinates: storage.create(),
            sink,
        }
    }
}

impl<W: storage::Output> Sink for Writer<W> {
    #[inline]
    fn write<S: Iterator<Item = (f64, Polar<f64>)>>(&mut self, samples: S) {
        for (sample, coord) in samples {
            let sample = self.leak_dc.apply(sample);
            let sample = sample.to_ne_bytes();
            self.samples.write(&sample);

            let cart: Cartesian<f64> = coord.into();
            let mut bytes = [0u8; 4 * 3];
            bytes[..4].copy_from_slice(&(cart.x as f32).to_ne_bytes());
            bytes[4..8].copy_from_slice(&(cart.y as f32).to_ne_bytes());
            bytes[8..].copy_from_slice(&(cart.z as f32).to_ne_bytes());
            self.coordinates.write(&bytes);
        }
    }
}

impl<W: storage::Output> Drop for Writer<W> {
    fn drop(&mut self) {
        let a = self.samples.finish();
        self.sink.write(&a);
        let b = self.coordinates.finish();
        self.sink.write(&b);
    }
}