use super::encoder::Encoder;
use crate::building_blocks::SynthParameterValue;
use crate::building_blocks::{Panner, StereoPanner};
pub struct StereoEncoder<const BUFSIZE: usize, const NCHAN: usize> {
left_enc: Encoder<BUFSIZE, NCHAN>,
right_enc: Encoder<BUFSIZE, NCHAN>,
}
impl<const BUFSIZE: usize, const NCHAN: usize> Default for StereoEncoder<BUFSIZE, NCHAN> {
fn default() -> Self {
Self::new()
}
}
impl<const BUFSIZE: usize, const NCHAN: usize> StereoEncoder<BUFSIZE, NCHAN> {
pub fn new() -> Self {
StereoEncoder {
left_enc: Encoder::new(),
right_enc: Encoder::new(),
}
}
}
impl<const BUFSIZE: usize, const NCHAN: usize> StereoPanner<BUFSIZE, NCHAN>
for StereoEncoder<BUFSIZE, NCHAN>
{
fn set_parameter(
&mut self,
par: crate::building_blocks::SynthParameterLabel,
value: &crate::building_blocks::SynthParameterValue,
) {
if let crate::building_blocks::SynthParameterLabel::AmbisonicAzimuth = par {
let offset = std::f32::consts::PI / 6.0;
let val_left = match value {
SynthParameterValue::ScalarF32(s) => &SynthParameterValue::ScalarF32(s + offset),
_ => value,
};
let val_right = match value {
SynthParameterValue::ScalarF32(s) => &SynthParameterValue::ScalarF32(s - offset),
_ => value,
};
self.left_enc.set_parameter(par, val_left);
self.right_enc.set_parameter(par, val_right);
} else {
self.left_enc.set_parameter(par, value);
self.right_enc.set_parameter(par, value);
}
}
fn set_modulator(
&mut self,
par: crate::building_blocks::SynthParameterLabel,
init: f32,
modulator: crate::building_blocks::Modulator<BUFSIZE>,
) {
if let crate::building_blocks::SynthParameterLabel::AmbisonicAzimuth = par {
let offset = std::f32::consts::PI / 6.0;
let mut mod_left = modulator.clone();
let mut mod_right = modulator.clone();
mod_left.add = offset;
mod_right.add = -offset;
self.left_enc.set_modulator(par, init, mod_left);
self.right_enc.set_modulator(par, init, mod_right);
} else {
self.left_enc.set_modulator(par, init, modulator.clone());
self.right_enc.set_modulator(par, init, modulator);
}
}
fn process_block(
&mut self,
block: [[f32; BUFSIZE]; 2],
start_sample: usize,
sample_buffers: &[crate::building_blocks::SampleBuffer],
) -> [[f32; BUFSIZE]; NCHAN] {
let left_out = self
.left_enc
.process_block(block[0], start_sample, sample_buffers);
let right_out = self
.right_enc
.process_block(block[1], start_sample, sample_buffers);
let mut out = [[0.0; BUFSIZE]; NCHAN];
for ch in 0..NCHAN {
for s in 0..BUFSIZE {
out[ch][s] = left_out[ch][s] + right_out[ch][s];
}
}
out
}
}