Skip to main content

autoeq_iir/
mod.rs

1#![doc = include_str!("../README.md")]
2
3// Module declarations
4mod fir;
5mod iir;
6
7// Re-export IIR types and functions
8pub use iir::{
9    Biquad, BiquadFilterType, FilterRow, Peq, compute_peq_response, peq_butterworth_highpass,
10    peq_butterworth_lowpass, peq_butterworth_q, peq_equal, peq_format_apo, peq_format_aupreset,
11    peq_format_rme_channel, peq_format_rme_room, peq_linkwitzriley_highpass,
12    peq_linkwitzriley_lowpass, peq_linkwitzriley_q, peq_loudness_gain, peq_preamp_gain,
13    peq_preamp_gain_max, peq_print, peq_spl,
14};
15
16// Re-export FIR types and functions
17pub use fir::{
18    Fir, FirBank, FirFilterType, WindowType, compute_fir_bank_response, fir_bank_preamp_gain,
19    fir_bank_spl, generate_window,
20};
21
22// ============================================================================
23// Common Helper Functions and Constants
24// ============================================================================
25
26/// Converts bandwidth in octaves to a Q factor.
27pub fn bw2q(bw: f64) -> f64 {
28    let two_pow_bw = 2.0_f64.powf(bw);
29    two_pow_bw.sqrt() / (two_pow_bw - 1.0)
30}
31
32/// Converts a Q factor to bandwidth in octaves.
33pub fn q2bw(q: f64) -> f64 {
34    let q2 = (2.0 * q * q + 1.0) / (2.0 * q * q);
35    (q2 + (q2 * q2 - 1.0).sqrt()).log(2.0)
36}
37
38// Constants
39/// Default Q factor for high/low pass filters
40pub const DEFAULT_Q_HIGH_LOW_PASS: f64 = 1.0 / std::f64::consts::SQRT_2;
41/// Default Q factor for high/low shelf filters
42pub const DEFAULT_Q_HIGH_LOW_SHELF: f64 = 1.0668676536332304; // Value of bw2q(0.9)
43
44/// Sample rate constant (matching Python SRATE)
45pub const SRATE: f64 = 48000.0;
46
47// ============================================================================
48// Tests for Common Functions
49// ============================================================================
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    fn approx_eq(a: f64, b: f64, tol: f64) -> bool {
56        (a - b).abs() <= tol
57    }
58
59    #[test]
60    fn test_bw_q_roundtrip() {
61        let qs = [0.5, 1.0, 2.0, 5.0];
62        for &q in &qs {
63            let bw = q2bw(q);
64            let q2 = bw2q(bw);
65            assert!(
66                approx_eq(q, q2, 1e-9),
67                "roundtrip failed: q={} -> bw={} -> q2={}",
68                q,
69                bw,
70                q2
71            );
72        }
73    }
74}