use crate::cli::PeqModel;
use crate::iir::{Biquad, Peq};
use crate::param_utils::{self, FilterParams};
use ndarray::Array1;
pub fn x2peq(x: &[f64], srate: f64, peq_model: PeqModel) -> Peq {
let num_filters = param_utils::num_filters(x, peq_model);
let mut peq = Vec::with_capacity(num_filters);
for i in 0..num_filters {
let params = param_utils::get_filter_params(x, i, peq_model);
let freq = 10f64.powf(params.freq);
let q = params.q;
let gain = params.gain;
let ftype =
param_utils::determine_filter_type(i, num_filters, peq_model, params.filter_type);
let filter = Biquad::new(ftype, freq, srate, q, gain);
peq.push((1.0, filter));
}
peq
}
pub fn peq2x(peq: &Peq, peq_model: PeqModel) -> Vec<f64> {
let ppf = param_utils::params_per_filter(peq_model);
let mut x = Vec::with_capacity(peq.len() * ppf);
for (_weight, filter) in peq {
let params = FilterParams {
filter_type: if ppf == 4 {
Some(param_utils::encode_filter_type(filter.filter_type))
} else {
None
},
freq: filter.freq.log10(),
q: filter.q,
gain: filter.db_gain,
};
match peq_model {
PeqModel::Pk
| PeqModel::HpPk
| PeqModel::HpPkLp
| PeqModel::LsPk
| PeqModel::LsPkHs => {
x.push(params.freq);
x.push(params.q);
x.push(params.gain);
}
PeqModel::FreePkFree | PeqModel::Free => {
x.push(params.filter_type.unwrap_or(0.0));
x.push(params.freq);
x.push(params.q);
x.push(params.gain);
}
}
}
x
}
pub fn x2spl(freqs: &Array1<f64>, x: &[f64], srate: f64, peq_model: PeqModel) -> Array1<f64> {
let peq = x2peq(x, srate, peq_model);
crate::iir::compute_peq_response(freqs, &peq, srate)
}
pub fn compute_peq_response_from_x(
freqs: &Array1<f64>,
x: &[f64],
sample_rate: f64,
peq_model: PeqModel,
) -> Array1<f64> {
x2spl(freqs, x, sample_rate, peq_model)
}
pub fn build_sorted_filters(x: &[f64], peq_model: PeqModel) -> Vec<crate::iir::FilterRow> {
let num_filters = param_utils::num_filters(x, peq_model);
let mut rows: Vec<crate::iir::FilterRow> = Vec::with_capacity(num_filters);
for i in 0..num_filters {
let params = param_utils::get_filter_params(x, i, peq_model);
let freq = 10f64.powf(params.freq);
let q = params.q;
let gain = params.gain;
let ftype =
param_utils::determine_filter_type(i, num_filters, peq_model, params.filter_type);
rows.push(crate::iir::FilterRow {
freq,
q,
gain,
kind: ftype.short_name(),
});
}
rows.sort_by(|a, b| {
a.freq
.partial_cmp(&b.freq)
.unwrap_or(std::cmp::Ordering::Equal)
});
for row in &mut rows {
if row.kind == "HPQ" || row.kind == "LP" || row.kind == "HP" {
row.gain = 0.0;
}
}
rows
}
pub fn peq_print_from_x(x: &[f64], srate: f64, peq_model: PeqModel) {
let peq = x2peq(x, srate, peq_model);
crate::iir::peq_print(&peq);
}