math_audio_iir_fir/mod.rs
1//! IIR and FIR filter library for audio processing.
2//!
3//! This crate provides digital filter implementations for audio signal processing,
4//! including biquad IIR filters and FIR filters. The filters are designed for
5//! parametric equalization and audio processing applications.
6//!
7//! # Features
8//!
9//! - **Biquad IIR filters**: Peak, Lowpass, Highpass, Lowshelf, Highshelf, Bandpass, Notch
10//! - **FIR filters**: Windowed sinc filters with various window types
11//! - **Frequency response computation**: For both IIR and FIR filters
12//! - **Multiple output formats**: APO, RME, AU Preset
13//!
14//! # Example
15//!
16//! ```rust
17//! use math_audio_iir_fir::{Biquad, BiquadFilterType, SRATE};
18//!
19//! // Create a peak filter at 1kHz with Q=2 and +3dB gain
20//! let filter = Biquad::new(BiquadFilterType::Peak, 1000.0, SRATE, 2.0, 3.0);
21//!
22//! // Get the frequency response at 1kHz (in dB)
23//! let response_db = filter.log_result(1000.0);
24//! assert!((response_db - 3.0).abs() < 0.1);
25//! ```
26#![doc = include_str!("../README.md")]
27#![warn(missing_docs)]
28
29// Module declarations
30pub mod denormals;
31mod error;
32mod fir;
33mod fir_design;
34mod iir;
35mod phase_smooth;
36
37// Re-export error types
38pub use error::{IirError, Result};
39
40// Re-export IIR types and functions
41pub use iir::{
42 Biquad, BiquadFilterType, FilterRow, Peq, compute_peq_response, peq_butterworth_highpass,
43 peq_butterworth_lowpass, peq_butterworth_q, peq_equal, peq_format_apo, peq_format_aupreset,
44 peq_format_rme_channel, peq_format_rme_room, peq_linkwitzriley_highpass,
45 peq_linkwitzriley_lowpass, peq_linkwitzriley_q, peq_loudness_gain, peq_preamp_gain,
46 peq_preamp_gain_max, peq_print, peq_spl,
47};
48
49// Re-export FIR types and functions
50pub use fir::{
51 Fir, FirBank, FirFilterType, WindowType, compute_fir_bank_response, fir_bank_preamp_gain,
52 fir_bank_spl, generate_window,
53};
54
55// Re-export FIR design types and functions (frequency response matching)
56pub use fir_design::{
57 FirDesignConfig, FirPhase, generate_fir_from_response, generate_kirkeby_correction,
58 save_fir_to_wav,
59};
60
61// Re-export phase smoothing functions
62pub use phase_smooth::{interpolate_phase_complex, smooth_phase_via_group_delay, unwrap_phase};
63
64// ============================================================================
65// Common Helper Functions and Constants
66// ============================================================================
67
68/// Converts bandwidth in octaves to a Q factor.
69pub fn bw2q(bw: f64) -> f64 {
70 let two_pow_bw = 2.0_f64.powf(bw);
71 two_pow_bw.sqrt() / (two_pow_bw - 1.0)
72}
73
74/// Converts a Q factor to bandwidth in octaves.
75pub fn q2bw(q: f64) -> f64 {
76 let q2 = (2.0 * q * q + 1.0) / (2.0 * q * q);
77 (q2 + (q2 * q2 - 1.0).sqrt()).log(2.0)
78}
79
80// Constants
81/// Default Q factor for high/low pass filters
82pub const DEFAULT_Q_HIGH_LOW_PASS: f64 = 1.0 / std::f64::consts::SQRT_2;
83/// Default Q factor for high/low shelf filters
84pub const DEFAULT_Q_HIGH_LOW_SHELF: f64 = 1.0668676536332304; // Value of bw2q(0.9)
85
86/// Sample rate constant (matching Python SRATE)
87pub const SRATE: f64 = 48000.0;
88
89// ============================================================================
90// Tests for Common Functions
91// ============================================================================
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 fn approx_eq(a: f64, b: f64, tol: f64) -> bool {
98 (a - b).abs() <= tol
99 }
100
101 #[test]
102 fn test_bw_q_roundtrip() {
103 let qs = [0.5, 1.0, 2.0, 5.0];
104 for &q in &qs {
105 let bw = q2bw(q);
106 let q2 = bw2q(bw);
107 assert!(
108 approx_eq(q, q2, 1e-9),
109 "roundtrip failed: q={} -> bw={} -> q2={}",
110 q,
111 bw,
112 q2
113 );
114 }
115 }
116}