use crate::cli::PeqModel;
use crate::iir::BiquadFilterType;
pub fn params_per_filter(peq_model: PeqModel) -> usize {
match peq_model {
PeqModel::Pk | PeqModel::HpPk | PeqModel::HpPkLp | PeqModel::LsPk | PeqModel::LsPkHs => 3,
PeqModel::FreePkFree | PeqModel::Free => 4,
}
}
pub fn num_filters(x: &[f64], peq_model: PeqModel) -> usize {
x.len() / params_per_filter(peq_model)
}
pub fn get_filter_params(x: &[f64], i: usize, peq_model: PeqModel) -> FilterParams {
let ppf = params_per_filter(peq_model);
let offset = i * ppf;
match peq_model {
PeqModel::Pk | PeqModel::HpPk | PeqModel::HpPkLp | PeqModel::LsPk | PeqModel::LsPkHs => {
FilterParams {
filter_type: None,
freq: x[offset],
q: x[offset + 1],
gain: x[offset + 2],
}
}
PeqModel::FreePkFree | PeqModel::Free => {
FilterParams {
filter_type: Some(x[offset]),
freq: x[offset + 1],
q: x[offset + 2],
gain: x[offset + 3],
}
}
}
}
pub fn set_filter_params(x: &mut [f64], i: usize, params: &FilterParams, peq_model: PeqModel) {
let ppf = params_per_filter(peq_model);
let offset = i * ppf;
match peq_model {
PeqModel::Pk | PeqModel::HpPk | PeqModel::HpPkLp | PeqModel::LsPk | PeqModel::LsPkHs => {
x[offset] = params.freq;
x[offset + 1] = params.q;
x[offset + 2] = params.gain;
}
PeqModel::FreePkFree | PeqModel::Free => {
x[offset] = params.filter_type.unwrap_or(0.0);
x[offset + 1] = params.freq;
x[offset + 2] = params.q;
x[offset + 3] = params.gain;
}
}
}
#[derive(Debug, Clone)]
pub struct FilterParams {
pub filter_type: Option<f64>,
pub freq: f64,
pub q: f64,
pub gain: f64,
}
pub fn determine_filter_type(
i: usize,
num_filters: usize,
peq_model: PeqModel,
type_param: Option<f64>,
) -> BiquadFilterType {
match peq_model {
PeqModel::Pk => BiquadFilterType::Peak,
PeqModel::HpPk => {
if i == 0 {
BiquadFilterType::HighpassVariableQ
} else {
BiquadFilterType::Peak
}
}
PeqModel::HpPkLp => {
if i == 0 {
BiquadFilterType::HighpassVariableQ
} else if i == num_filters - 1 {
BiquadFilterType::Lowpass
} else {
BiquadFilterType::Peak
}
}
PeqModel::LsPk => {
if i == 0 {
BiquadFilterType::Lowshelf
} else {
BiquadFilterType::Peak
}
}
PeqModel::LsPkHs => {
if i == 0 {
BiquadFilterType::Lowshelf
} else if i == num_filters - 1 {
BiquadFilterType::Highshelf
} else {
BiquadFilterType::Peak
}
}
PeqModel::FreePkFree => {
if i == 0 || i == num_filters - 1 {
decode_filter_type(type_param.unwrap_or(0.0))
} else {
BiquadFilterType::Peak
}
}
PeqModel::Free => {
decode_filter_type(type_param.unwrap_or(0.0))
}
}
}
pub fn decode_filter_type(type_value: f64) -> BiquadFilterType {
let idx = type_value.floor() as i32;
match idx {
0 => BiquadFilterType::Peak,
1 => BiquadFilterType::Lowpass,
2 => BiquadFilterType::Highpass,
3 => BiquadFilterType::Lowshelf,
4 => BiquadFilterType::Highshelf,
5 => BiquadFilterType::HighpassVariableQ,
6 => BiquadFilterType::Bandpass,
7 => BiquadFilterType::Notch,
8 => BiquadFilterType::AllPass,
_ => BiquadFilterType::Peak, }
}
pub fn encode_filter_type(filter_type: BiquadFilterType) -> f64 {
match filter_type {
BiquadFilterType::Peak => 0.0,
BiquadFilterType::Lowpass => 1.0,
BiquadFilterType::Highpass => 2.0,
BiquadFilterType::Lowshelf => 3.0,
BiquadFilterType::Highshelf => 4.0,
BiquadFilterType::HighpassVariableQ => 5.0,
BiquadFilterType::Bandpass => 6.0,
BiquadFilterType::Notch => 7.0,
BiquadFilterType::AllPass => 8.0,
BiquadFilterType::LowshelfOrf => 9.0,
BiquadFilterType::HighshelfOrf => 10.0,
BiquadFilterType::PeakMatched => 11.0,
}
}
pub fn filter_type_bounds() -> (f64, f64) {
(0.0, 8.999) }
#[inline]
pub fn freq_from_log10(log_freq: f64) -> f64 {
10f64.powf(log_freq)
}
#[inline]
pub fn freq_from_log10_clamped(log_freq: f64, min_freq: f64) -> f64 {
10f64.powf(log_freq).max(min_freq)
}