use super::band::{BandType, EqBand};
use super::FilterFactory;
use crate::{Filter, FilterType};
use rill_core::{Error, ErrorCode};
pub struct ParametricEq<F: Filter<f32> + 'static, Factory: FilterFactory<F> + Send + Sync + 'static>
{
factory: Factory,
bands: Vec<EqBand<F>>,
sample_rate: f32,
output_gain: f32,
}
impl<F: Filter<f32> + 'static, Factory: FilterFactory<F> + Send + Sync + 'static>
ParametricEq<F, Factory>
{
pub fn new(factory: Factory, num_bands: usize, sample_rate: f32) -> Self {
let mut eq = Self {
factory,
bands: Vec::with_capacity(num_bands),
sample_rate,
output_gain: 1.0,
};
for i in 0..num_bands {
let freq = if num_bands > 1 {
20.0 * (1000.0_f32).powf(i as f32 / (num_bands - 1) as f32)
} else {
1000.0
};
let band = EqBand::new(
eq.factory.create_filter(FilterType::Peak, freq, 1.0, 0.0),
BandType::Peak,
freq,
1.0,
0.0,
);
eq.bands.push(band);
}
eq
}
pub fn set_band(
&mut self,
index: usize,
frequency: f32,
q: f32,
gain_db: f32,
) -> Result<(), Error> {
if index >= self.bands.len() {
return Err(Error::new(
ErrorCode::InvalidParameter,
format!("Band index {} out of range", index),
));
}
let band = &mut self.bands[index];
band.set_frequency(frequency);
band.set_q(q);
band.set_gain_db(gain_db);
band.update_filter();
Ok(())
}
pub fn set_band_type(&mut self, index: usize, band_type: BandType) -> Result<(), Error> {
if index >= self.bands.len() {
return Err(Error::new(
ErrorCode::InvalidParameter,
format!("Band index {} out of range", index),
));
}
let band = &mut self.bands[index];
band.band_type = band_type;
band.update_filter();
Ok(())
}
pub fn set_band_enabled(&mut self, index: usize, enabled: bool) -> Result<(), Error> {
if index >= self.bands.len() {
return Err(Error::new(
ErrorCode::InvalidParameter,
format!("Band index {} out of range", index),
));
}
self.bands[index].set_enabled(enabled);
Ok(())
}
pub fn set_output_gain(&mut self, gain: f32) {
self.output_gain = gain.clamp(0.0, 4.0);
}
pub fn get_band_frequency(&self, index: usize) -> Option<f32> {
self.bands.get(index).map(|b| b.frequency())
}
pub fn get_band_q(&self, index: usize) -> Option<f32> {
self.bands.get(index).map(|b| b.q())
}
pub fn get_band_gain(&self, index: usize) -> Option<f32> {
self.bands.get(index).map(|b| b.gain_db())
}
pub fn get_band_type(&self, index: usize) -> Option<BandType> {
self.bands.get(index).map(|b| b.band_type())
}
pub fn get_band_enabled(&self, index: usize) -> Option<bool> {
self.bands.get(index).map(|b| b.is_enabled())
}
pub fn num_bands(&self) -> usize {
self.bands.len()
}
pub fn init(&mut self, sample_rate: f32) {
self.sample_rate = sample_rate;
for band in &mut self.bands {
band.init(sample_rate);
}
}
pub fn reset(&mut self) {
for band in &mut self.bands {
band.reset();
}
}
pub fn process_block(&mut self, input: &[f32], output: &mut [f32]) {
assert_eq!(input.len(), output.len());
for (dest, &src) in output.iter_mut().zip(input.iter()) {
let mut sample = src;
for band in &mut self.bands {
if band.is_enabled() {
sample = band.process(sample);
}
}
*dest = sample * self.output_gain;
}
}
}