# Copyright 2025 XMOS LIMITED. # This Software is subject to the terms of the XMOS Public Licence: Version 1. """Pydantic models of the different biquad types.""" from audio_dsp.models.stage import StageParameters from functools import partial from pydantic import BaseModel, RootModel, Field, create_model from typing import Literal, Annotated, List, Union from annotated_types import Len from audio_dsp.dsp.generic import HEADROOM_DB, MIN_SIG_DB, Q_SIG from audio_dsp.dsp import utils def _ws(locals): """ Without self. Parameters ---------- locals : dict a dictionary Returns ------- dict l with the entry "self" removed """ return {k: v for k, v in locals.items() if k != "self"} DEFAULT_Q = partial(Field, default=0.707, gt=0, le=10, description="Q factor of the filter.") DEFAULT_FILTER_FREQ = partial( Field, default=1000, gt=0, lt=24000, description="Frequency of the filter in Hz." ) DEFAULT_BW = partial( Field, default=1, gt=0, le=10, description="Bandwidth of the filter in octaves." ) DEFAULT_BOOST_DB = partial( Field, default=0.0, ge=-24, le=24, description="Gain of the filter in dB." ) DEFAULT_GAIN_DB = partial( Field, default=0.0, ge=MIN_SIG_DB, le=HEADROOM_DB, description="Gain of the stage in dB." ) DEFAULT_ATTACK_T = partial( Field, default=0.01, gt=0, le=1, description="Attack time of the stage in seconds." ) DEFAULT_RELEASE_T = partial( Field, default=0.2, gt=0, le=5, description="Release time of the stage in seconds." ) DEFAULT_COMPRESSOR_RATIO = partial( Field, default=4.0, gt=1, le=100, description="Compression ratio of the stage." ) DEFAULT_THRESHOLD_DB = DEFAULT_GAIN_DB RMS_HEADROOM_DB = utils.db_pow((utils.Q_max(31) + 1) / utils.Q_max(Q_SIG)) MIN_RMS_SIG_DB = utils.db_pow(1 / 2**Q_SIG) DEFAULT_RMS_THRESHOLD_DB = partial( Field, default=0.0, ge=MIN_RMS_SIG_DB, le=RMS_HEADROOM_DB, description="Threshold of the stage in dB.", ) class biquad_allpass(StageParameters): """Parameters for a Biquad Stage configured to allpass.""" type: Literal["allpass"] = "allpass" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() class biquad_bandpass(StageParameters): """Parameters for a Biquad Stage configured to bandpass.""" type: Literal["bandpass"] = "bandpass" filter_freq: float = DEFAULT_FILTER_FREQ() bw: float = DEFAULT_BW() class biquad_bandstop(StageParameters): """Parameters for a Biquad Stage configured to bandstop.""" type: Literal["bandstop"] = "bandstop" filter_freq: float = DEFAULT_FILTER_FREQ() bw: float = DEFAULT_BW() class biquad_bypass(StageParameters): """Parameters for a Biquad Stage configured to bypass.""" type: Literal["bypass"] = "bypass" class biquad_constant_q(StageParameters): """Parameters for a Biquad Stage configured to constant_q.""" type: Literal["constant_q"] = "constant_q" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() boost_db: float = DEFAULT_BOOST_DB() class biquad_gain(StageParameters): """Parameters for a Biquad Stage configured to gain.""" type: Literal["gain"] = "gain" gain_db: float = DEFAULT_GAIN_DB() class biquad_highpass(StageParameters): """Parameters for a Biquad Stage configured to highpass.""" type: Literal["highpass"] = "highpass" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() class biquad_highshelf(StageParameters): """Parameters for a Biquad Stage configured to highshelf.""" type: Literal["highshelf"] = "highshelf" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() boost_db: float = DEFAULT_BOOST_DB() class biquad_linkwitz(StageParameters): """Parameters for a Biquad Stage configured to linkwitz.""" type: Literal["linkwitz"] = "linkwitz" f0: float = DEFAULT_FILTER_FREQ() q0: float = DEFAULT_Q() fp: float = DEFAULT_FILTER_FREQ() qp: float = DEFAULT_Q() class biquad_lowpass(StageParameters): """Parameters for a Biquad Stage configured to lowpass.""" type: Literal["lowpass"] = "lowpass" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() class biquad_lowshelf(StageParameters): """Parameters for a Biquad Stage configured to lowshelf.""" type: Literal["lowshelf"] = "lowshelf" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() boost_db: float = DEFAULT_BOOST_DB() class biquad_mute(StageParameters): """Parameters for a Biquad Stage configured to mute.""" type: Literal["mute"] = "mute" class biquad_notch(StageParameters): """Parameters for a Biquad Stage configured to notch.""" type: Literal["notch"] = "notch" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() class biquad_peaking(StageParameters): """Parameters for a Biquad Stage configured to peaking.""" type: Literal["peaking"] = "peaking" filter_freq: float = DEFAULT_FILTER_FREQ() q_factor: float = DEFAULT_Q() boost_db: float = DEFAULT_BOOST_DB() BIQUAD_TYPES = Union[ biquad_allpass, biquad_bandpass, biquad_bandstop, biquad_bypass, biquad_constant_q, biquad_gain, biquad_highpass, biquad_highshelf, biquad_linkwitz, biquad_lowpass, biquad_lowshelf, biquad_mute, biquad_notch, biquad_peaking, ]