use super::*;
pub struct MixOscParamIter<T, A, B, C, D, E, F>
where
T: DspFormatBase,
A: Iterator<Item = T::NoteOffset>,
B: Iterator<Item = T::Scalar>,
C: Iterator<Item = T::Scalar>,
D: Iterator<Item = T::Scalar>,
E: Iterator<Item = T::Scalar>,
F: Iterator<Item = T::Scalar>,
{
tune: A,
shape: B,
sin: C,
sq: D,
tri: E,
saw: F,
phantom: core::marker::PhantomData<T>,
}
impl<T, A, B, C, D, E, F> MixOscParamIter<T, A, B, C, D, E, F>
where
T: DspFormatBase,
A: Iterator<Item = T::NoteOffset>,
B: Iterator<Item = T::Scalar>,
C: Iterator<Item = T::Scalar>,
D: Iterator<Item = T::Scalar>,
E: Iterator<Item = T::Scalar>,
F: Iterator<Item = T::Scalar>,
{
pub fn with_tune<New: Iterator<Item = T::NoteOffset>>(
self,
new: New,
) -> MixOscParamIter<T, New, B, C, D, E, F> {
MixOscParamIter {
tune: new,
shape: self.shape,
sin: self.sin,
sq: self.sq,
tri: self.tri,
saw: self.saw,
phantom: self.phantom,
}
}
pub fn with_shape<New: Iterator<Item = T::Scalar>>(
self,
new: New,
) -> MixOscParamIter<T, A, New, C, D, E, F> {
MixOscParamIter {
tune: self.tune,
shape: new,
sin: self.sin,
sq: self.sq,
tri: self.tri,
saw: self.saw,
phantom: self.phantom,
}
}
pub fn with_sin<New: Iterator<Item = T::Scalar>>(
self,
new: New,
) -> MixOscParamIter<T, A, B, New, D, E, F> {
MixOscParamIter {
tune: self.tune,
shape: self.shape,
sin: new,
sq: self.sq,
tri: self.tri,
saw: self.saw,
phantom: self.phantom,
}
}
pub fn with_sq<New: Iterator<Item = T::Scalar>>(
self,
new: New,
) -> MixOscParamIter<T, A, B, C, New, E, F> {
MixOscParamIter {
tune: self.tune,
shape: self.shape,
sin: self.sin,
sq: new,
tri: self.tri,
saw: self.saw,
phantom: self.phantom,
}
}
pub fn with_tri<New: Iterator<Item = T::Scalar>>(
self,
new: New,
) -> MixOscParamIter<T, A, B, C, D, New, F> {
MixOscParamIter {
tune: self.tune,
shape: self.shape,
sin: self.sin,
sq: self.sq,
tri: new,
saw: self.saw,
phantom: self.phantom,
}
}
pub fn with_saw<New: Iterator<Item = T::Scalar>>(
self,
new: New,
) -> MixOscParamIter<T, A, B, C, D, E, New> {
MixOscParamIter {
tune: self.tune,
shape: self.shape,
sin: self.sin,
sq: self.sq,
tri: self.tri,
saw: new,
phantom: self.phantom,
}
}
}
impl<T, A, B, C, D, E, F> Iterator for MixOscParamIter<T, A, B, C, D, E, F>
where
T: DspFormatBase,
A: Iterator<Item = T::NoteOffset>,
B: Iterator<Item = T::Scalar>,
C: Iterator<Item = T::Scalar>,
D: Iterator<Item = T::Scalar>,
E: Iterator<Item = T::Scalar>,
F: Iterator<Item = T::Scalar>,
{
type Item = MixOscParams<T>;
fn next(&mut self) -> Option<MixOscParams<T>> {
Some(MixOscParams {
tune: self.tune.next()?,
shape: self.shape.next()?,
sin: self.sin.next()?,
sq: self.sq.next()?,
tri: self.tri.next()?,
saw: self.saw.next()?,
})
}
}
#[allow(clippy::type_complexity)]
pub fn new_mixosc_param_iter<T: DspFormatBase>() -> MixOscParamIter<
T,
Repeat<T::NoteOffset>,
Repeat<T::Scalar>,
Repeat<T::Scalar>,
Repeat<T::Scalar>,
Repeat<T::Scalar>,
Repeat<T::Scalar>,
> {
MixOscParamIter {
tune: repeat(T::NoteOffset::zero()),
shape: repeat(T::Scalar::zero()),
sin: repeat(T::Scalar::zero()),
sq: repeat(T::Scalar::zero()),
tri: repeat(T::Scalar::zero()),
saw: repeat(T::Scalar::one()),
phantom: Default::default(),
}
}
pub struct SyncedMixOscsParamIter<T, A, B, C>
where
T: DspFormatBase,
A: Iterator<Item = MixOscParams<T>>,
B: Iterator<Item = MixOscParams<T>>,
C: Iterator<Item = bool>,
{
primary: A,
secondary: B,
sync: C,
phantom: core::marker::PhantomData<T>,
}
impl<T, A, B, C> SyncedMixOscsParamIter<T, A, B, C>
where
T: DspFormatBase,
A: Iterator<Item = MixOscParams<T>>,
B: Iterator<Item = MixOscParams<T>>,
C: Iterator<Item = bool>,
{
pub fn with_primary<New: Iterator<Item = MixOscParams<T>>>(
self,
new: New,
) -> SyncedMixOscsParamIter<T, New, B, C> {
SyncedMixOscsParamIter {
primary: new,
secondary: self.secondary,
sync: self.sync,
phantom: self.phantom,
}
}
pub fn with_secondary<New: Iterator<Item = MixOscParams<T>>>(
self,
new: New,
) -> SyncedMixOscsParamIter<T, A, New, C> {
SyncedMixOscsParamIter {
primary: self.primary,
secondary: new,
sync: self.sync,
phantom: self.phantom,
}
}
pub fn with_sync<New: Iterator<Item = bool>>(
self,
new: New,
) -> SyncedMixOscsParamIter<T, A, B, New> {
SyncedMixOscsParamIter {
primary: self.primary,
secondary: self.secondary,
sync: new,
phantom: self.phantom,
}
}
}
impl<T, A, B, C> Iterator for SyncedMixOscsParamIter<T, A, B, C>
where
T: DspFormatBase,
A: Iterator<Item = MixOscParams<T>>,
B: Iterator<Item = MixOscParams<T>>,
C: Iterator<Item = bool>,
{
type Item = SyncedMixOscsParams<T>;
fn next(&mut self) -> Option<SyncedMixOscsParams<T>> {
Some(SyncedMixOscsParams {
primary: self.primary.next()?,
secondary: self.secondary.next()?,
sync: self.sync.next()?,
})
}
}
#[allow(clippy::type_complexity)]
pub fn new_synced_mixoscs_param_iter<T: DspFormatBase>(
) -> SyncedMixOscsParamIter<T, Repeat<MixOscParams<T>>, Repeat<MixOscParams<T>>, Repeat<bool>> {
SyncedMixOscsParamIter {
primary: repeat(MixOscParams {
tune: T::NoteOffset::zero(),
shape: T::Scalar::zero(),
sin: T::Scalar::zero(),
sq: T::Scalar::zero(),
tri: T::Scalar::zero(),
saw: T::Scalar::one(),
}),
secondary: repeat(MixOscParams {
tune: T::NoteOffset::zero(),
shape: T::Scalar::zero(),
sin: T::Scalar::zero(),
sq: T::Scalar::zero(),
tri: T::Scalar::zero(),
saw: T::Scalar::one(),
}),
sync: repeat(false),
phantom: Default::default(),
}
}