diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 07dc466..49422a4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,25 @@ adheres to `Semantic Versioning `_. - Validation for results from tests in every module (so far many tests are only regarding functionality) +`0.4.2 `_ - +--------------------- +Added +~~~~~~~ +- `apply_gain` utility function in ``standard`` +- beta parameter for arbitrary noise generation +- `GroupDelayDesigner` in ``filterbanks`` +- nomalization of signals now accepts rms values + +Misc +~~~~~ +- frequency response interpolation with more interpolation modes +- refactored `PhaseLinearizer` + +Bugfix +~~~~~~ +- corrected a case where scaling of spectrum while plotting was wrong + + `0.4.1 `_ - --------------------- diff --git a/dsptoolbox/__init__.py b/dsptoolbox/__init__.py index 397c535..42d9658 100644 --- a/dsptoolbox/__init__.py +++ b/dsptoolbox/__init__.py @@ -15,6 +15,7 @@ CalibrationData, envelope, dither, + apply_gain, ) from .classes import ( Filter, @@ -59,6 +60,7 @@ "CalibrationData", "envelope", "dither", + "apply_gain", # Modules "transfer_functions", "distances", @@ -73,4 +75,4 @@ "tools", ] -__version__ = "0.4.1" +__version__ = "0.4.2" diff --git a/dsptoolbox/_general_helpers.py b/dsptoolbox/_general_helpers.py index bbc029d..4289a78 100644 --- a/dsptoolbox/_general_helpers.py +++ b/dsptoolbox/_general_helpers.py @@ -21,6 +21,72 @@ from scipy.fft import next_fast_len +def to_db( + x: NDArray[np.float64], + amplitude_input: bool, + dynamic_range_db: float | None = None, + min_value: float | None = float(np.finfo(np.float64).smallest_normal), +) -> NDArray[np.float64]: + """Convert to dB from amplitude or power representation. Clipping small + values can be activated in order to avoid -inf dB outcomes. + + Parameters + ---------- + x : NDArray[np.float64] + Array to convert to dB. + amplitude_input : bool + Set to True if the values in x are in their linear form. False means + they have been already squared, i.e., they are in their power form. + dynamic_range_db : float, None, optional + If specified, a dynamic range in dB for the vector is applied by + finding its largest value and clipping to `max - dynamic_range_db`. + This will always overwrite `min_value` if specified. Pass None to + ignore. Default: None. + min_value : float, None, optional + Minimum value to clip `x` before converting into dB in order to avoid + `np.nan` or `-np.inf` in the output. Pass None to ignore. Default: + `np.finfo(np.float64).smallest_normal`. + + Returns + ------- + NDArray[np.float64] + New array or float in dB. + + """ + factor = 20.0 if amplitude_input else 10.0 + + if min_value is None and dynamic_range_db is None: + return factor * np.log10(np.abs(x)) + + x_abs = np.abs(x) + + if dynamic_range_db is not None: + min_value = np.max(x_abs) * 10.0 ** (-abs(dynamic_range_db) / factor) + + return factor * np.log10(np.clip(x_abs, a_min=min_value, a_max=None)) + + +def from_db(x: float | NDArray[np.float64], amplitude_output: bool): + """Get the values in their amplitude or power form from dB. + + Parameters + ---------- + x : float, NDArray[np.float64] + Values in dB. + amplitude_output : bool + When True, the values are returned in their linear form. Otherwise, + the squared (power) form is returned. + + Returns + ------- + float NDArray[np.float64] + Converted values + + """ + factor = 20.0 if amplitude_output else 10.0 + return 10 ** (x / factor) + + def _find_nearest(points, vector) -> NDArray[np.int_]: """Gives back the indexes with the nearest points in vector @@ -193,10 +259,10 @@ def _get_normalized_spectrum( # Factor if scaling == "amplitude": scale_factor = 20e-6 if calibrated_data and normalize is None else 1 - factor = 20 + amplitude_scaling = True elif scaling == "power": scale_factor = 4e-10 if calibrated_data and normalize is None else 1 - factor = 10 + amplitude_scaling = False else: raise ValueError( f"{scaling} is not supported. Please select amplitude or " @@ -228,10 +294,7 @@ def _get_normalized_spectrum( _fractional_octave_smoothing(mag_spectra**0.5, smoothe) ** 2 ) - epsilon = 10 ** (-800 / 10) - mag_spectra = factor * np.log10( - np.clip(mag_spectra, a_min=epsilon, a_max=None) / scale_factor - ) + mag_spectra = to_db(mag_spectra / scale_factor, amplitude_scaling, 500) if normalize is not None: for i in range(spectra.shape[1]): @@ -263,8 +326,9 @@ def _get_normalized_spectrum( def _find_frequencies_above_threshold( spec, f, threshold_db, normalize=True ) -> list: - """Finds frequencies above a certain threshold in a given spectrum.""" - denum_db = 20 * np.log10(np.abs(spec)) + """Finds frequencies above a certain threshold in a given (amplitude) + spectrum.""" + denum_db = to_db(spec, True) if normalize: denum_db -= np.max(denum_db) freqs = f[denum_db > threshold_db] @@ -352,14 +416,15 @@ def _compute_number_frames( def _normalize( - s: NDArray[np.float64], dbfs: float, mode="peak" + s: NDArray[np.float64], dbfs: float, mode: str, per_channel: bool ) -> NDArray[np.float64]: """Normalizes a signal. Parameters ---------- s: NDArray[np.float64] - Signal to normalize. + Signal to normalize. It can be 1 or 2D. Time samples are assumed to + be in the outer axis. dbfs: float dbfs value to normalize to. mode: str, optional @@ -372,22 +437,44 @@ def _normalize( Normalized signal. """ - s = s.copy() assert mode in ("peak", "rms"), ( "Mode of normalization is not " + "available. Select either peak or rms" ) + + onedim = s.ndim == 1 + if onedim: + s = s[..., None] + + factor = from_db(dbfs, True) if mode == "peak": - s /= np.max(np.abs(s)) - s *= 10 ** (dbfs / 20) - if mode == "rms": - s *= 10 ** (dbfs / 20) / _rms(s) - return s + factor /= np.max(np.abs(s), axis=0 if per_channel else None) + elif mode == "rms": + factor /= _rms(s if per_channel else s.flatten()) + s_norm = s * factor + + return s_norm[..., 0] if onedim else s_norm -def _rms(x: NDArray[np.float64]) -> NDArray[np.float64]: - """Root mean square computation.""" - return np.sqrt(np.sum(x**2) / len(x)) +def _rms(x: NDArray[np.float64]) -> float | NDArray[np.float64]: + """Root mean squared value of a discrete time series. + + Parameters + ---------- + x : NDArray[np.float64] + Time series. + + Returns + ------- + rms : float or NDArray[np.float64] + Root mean squared of a signal. Float or NDArray[np.float64] depending + on input. + + """ + single_dim = x.ndim == 1 + x = x[..., None] if single_dim else x + rms_vals = np.std(x, axis=0) + return rms_vals[..., 0] if single_dim else rms_vals def _amplify_db(s: NDArray[np.float64], db: float) -> NDArray[np.float64]: @@ -645,7 +732,7 @@ def _frequency_weightning( weights = 12194**2 * f**2 / ((f**2 + 20.6**2) * (f**2 + 12194**2)) weights /= weights[ind1k] if db_output: - weights = 20 * np.log10(weights) + weights = to_db(weights, True) return weights @@ -1077,16 +1164,15 @@ def _get_chirp_rate(range_hz: list, length_seconds: float) -> float: def _correct_for_real_phase_spectrum(phase_spectrum: NDArray[np.float64]): - """This function takes in a wrapped phase spectrum and corrects it to - be for a real signal (assuming the last frequency bin corresponds to - nyquist, i.e., time data had an even length). This effectively adds a - small linear phase offset so that the phase at nyquist is either 0 or - np.pi. + """This function takes in a phase spectrum and corrects it to be for a real + signal (assuming the last frequency bin corresponds to nyquist, i.e., time + data had an even length). This effectively adds a small linear phase offset + so that the phase at nyquist is either 0 or np.pi. Parameters ---------- phase_spectrum : NDArray[np.float64] - Wrapped phase to be corrected. It is assumed that its last element + Phase to be corrected. It is assumed that its last element corresponds to the nyquist frequency. Returns @@ -1095,11 +1181,7 @@ def _correct_for_real_phase_spectrum(phase_spectrum: NDArray[np.float64]): Phase spectrum that can correspond to a real signal. """ - factor = ( - phase_spectrum[-1] - if phase_spectrum[-1] >= 0 - else np.pi + phase_spectrum[-1] - ) + factor = phase_spectrum[-1] % np.pi return ( phase_spectrum - np.linspace(0, 1, len(phase_spectrum), endpoint=True) * factor @@ -1456,16 +1538,18 @@ def _interpolate_fr( Frequency response to be interpolated. f_target : NDArray[np.float64] Target frequency vector. - mode : str, optional - Convert to amplitude or power representation from dB during - interpolation (or the other way around) using the modes `"db2power"` - (input in dB, interpolation in power spectrum, output in dB), - `"db2amplitude"`, `"amplitude2db"`, `"power2db"`. Pass `None` to avoid - any conversion. Default: `None`. - interpolation_scheme : str, optional + mode : str, None, {"db2amplitude", "amplitude2db", "power2db",\ + "power2amplitude", "amplitude2power"}, optional + Convert between amplitude, power or dB representation during the + interpolation step. For instance, using the modes "db2power" means + input in dB, interpolation in power spectrum, output in dB. Available + modes are "db2amplitude", "amplitude2db", "power2db", + "power2amplitude", "amplitude2power". Pass None to avoid any + conversion. Default: None. + interpolation_scheme : str, {"linear", "quadratic", "cubic"}, optional Type of interpolation to use. See `scipy.interpolation.interp1d` for - details. Choose from `"quadratic"` or `"cubic"` splines, or `"linear"`. - Default: `"linear"`. + details. Choose from "quadratic" or "cubic" splines, or "linear". + Default: "linear". Returns ------- @@ -1476,11 +1560,11 @@ def _interpolate_fr( ----- - The input is always assumed to be already sorted. - In case `f_target` has values outside the boundaries of `f_interp`, - the first and last values of `fr_interp` are used for extrapolation. This - also applies if interpolation is done in dB. If done in amplitude or - power units, the fill value outside the boundaries is 0. + 0 is used as the fill value. For interpolation in dB, fill values are + the vector's edges. - The interpolation is always done along the first (outer) axis or the vector. + - When converting to dB, the default clipping value of `to_db` is used. - Theoretical thoughts on interpolating an amplitude or power frequency response: - Using complex and dB values during interpolation are not very precise @@ -1519,31 +1603,29 @@ def _interpolate_fr( """ - fill_value = (fr_interp[0], fr_interp[-1]) + fill_value = (0.0, 0.0) + y = fr_interp.copy() # Conversion if necessary if mode is not None: mode = mode.lower() - factor = 20 if "amplitude" in mode else 10 - if mode[:3] == "db2": - fr_interp = 10 ** (fr_interp / factor) - fill_value = (0.0, 0.0) + if mode == "power2amplitude": + y **= 0.5 + elif mode == "amplitude2power": + y **= 2.0 + elif mode[:3] == "db2": + y = from_db(y, "amplitude" in mode) elif mode[-3:] == "2db": - fr_interp = factor * np.log10( - np.clip( - np.abs(fr_interp), - a_min=np.finfo(np.float64).smallest_normal, - a_max=None, - ) - ) - fill_value = (fr_interp[0], fr_interp[-1]) + y = to_db(y, "amplitude" in mode) + fill_value = (y[0], y[-1]) else: raise ValueError(f"Unsupported interpolation mode: {mode}") interpolated = interp1d( f_interp, - fr_interp, + y, kind=interpolation_scheme, + copy=False, bounds_error=False, assume_sorted=True, fill_value=fill_value, @@ -1552,16 +1634,14 @@ def _interpolate_fr( # Back conversion if activated if mode is not None: - if mode[:3] == "db2": - interpolated = factor * np.log10( - np.clip( - np.abs(interpolated), - a_min=np.finfo(np.float64).smallest_normal, - a_max=None, - ) - ) + if mode == "power2amplitude": + interpolated **= 2.0 + elif mode == "amplitude2power": + interpolated **= 0.5 + elif mode[:3] == "db2": + interpolated = to_db(interpolated, "amplitude" in mode) elif mode[-3:] == "2db": - interpolated = 10 ** (interpolated / factor) + interpolated = from_db(interpolated, "amplitude" in mode) return interpolated diff --git a/dsptoolbox/_standard.py b/dsptoolbox/_standard.py index 2638868..e9915cb 100644 --- a/dsptoolbox/_standard.py +++ b/dsptoolbox/_standard.py @@ -830,37 +830,6 @@ def _detrend( return time_data -def _rms(x: NDArray[np.float64]) -> float | NDArray[np.float64]: - """Root mean squared value of a discrete time series. - - Parameters - ---------- - x : NDArray[np.float64] - Time series. - - Returns - ------- - rms : float or NDArray[np.float64] - Root mean squared of a signal. Float or NDArray[np.float64] depending - on input. - - """ - single_dim = False - if x.ndim < 2: - single_dim = True - x = x[..., None] - elif x.ndim == 2: - pass - else: - raise ValueError( - "Shape of array is not valid. Only 2D-Arrays " + "are valid" - ) - rms_vals = np.sqrt(np.mean(x**2, axis=0)) - if single_dim: - rms_vals = np.squeeze(rms_vals) - return rms_vals - - def _get_framed_signal( td: NDArray[np.float64], window_length_samples: int, diff --git a/dsptoolbox/beamforming/beamforming.py b/dsptoolbox/beamforming/beamforming.py index caed06d..1ff0748 100644 --- a/dsptoolbox/beamforming/beamforming.py +++ b/dsptoolbox/beamforming/beamforming.py @@ -19,6 +19,7 @@ ) from ._beamforming import BasePoints, _clean_sc_deconvolve from ..plots import general_matrix_plot +from ..tools import to_db try: from seaborn import set_style @@ -218,7 +219,7 @@ def plot_map( ), "Map shape does not match grid shape" # Get right extent ex = self.extent - map = 20 * np.log10(np.clip(np.abs(map), a_min=1e-25, a_max=None)) + map = to_db(map, False, dynamic_range_db=500) fig, ax = general_matrix_plot( map, # First dimension vertical and second dimension horizontal @@ -379,7 +380,7 @@ def plot_map( # Get right extent ex = self.extent - map = 20 * np.log10(np.clip(np.abs(map), a_min=1e-25, a_max=None)) + map = to_db(map, False, dynamic_range_db=500) fig, ax = general_matrix_plot( map, range_x=ex[extent_dimensions[1]], diff --git a/dsptoolbox/classes/group_delay_designer_phase_linearizer.py b/dsptoolbox/classes/group_delay_designer_phase_linearizer.py new file mode 100644 index 0000000..a4f1eb9 --- /dev/null +++ b/dsptoolbox/classes/group_delay_designer_phase_linearizer.py @@ -0,0 +1,223 @@ +from .filter import Filter +from .impulse_response import ImpulseResponse +import numpy as np +from scipy.integrate import cumulative_trapezoid +from scipy.interpolate import PchipInterpolator +from numpy.typing import NDArray +from .._general_helpers import _correct_for_real_phase_spectrum, _pad_trim +from warnings import warn + + +class GroupDelayDesigner: + """This class designs an FIR filter with a desired group delay response.""" + + def __init__( + self, + target_group_delay_s: NDArray[np.float64], + time_data_length_samples: int, + sampling_rate_hz: int, + ): + """GroupDelayDesigner creates an FIR filter with a desired group delay + response. Use the method `set_parameters` to define specific design + parameters. + + Parameters + ---------- + target_group_delay_s : NDArray[np.float64] + Target group delay in seconds. It is expected to contain the whole + positive frequency spectrum (including dc and eventually nyquist) + and be linearly spaced. + time_data_length_samples : NDArray[np.float64] + Length of the time signal that corresponds to the frequency vector + of `target_group_delay_s`. + sampling_rate_hz : int + Sampling rate to design the filter. It corresponds to the implicit + frequency vector of the group delay. + + """ + self.time_data_length_samples = time_data_length_samples + self.sampling_rate_hz = sampling_rate_hz + self._set_target_group_delay_s(target_group_delay_s) + self.set_parameters() + + def set_parameters( + self, + delay_increase_percent: float = 100.0, + ): + """Set parameters for the FIR filter. + + Parameters + ---------- + delay_increase_percent : float, optional + This is the increase (in percentage) in delay to the current + maximum group delay. Increasing this improves the quality of the + designed filter but also makes it longer. Passing a value of 100 + means that the total group delay will be 2 times larger than the + longest group delay. Default: 100. + + """ + assert ( + delay_increase_percent >= 0 + ), "Delay increase must be larger than zero" + self.group_delay_increase_factor = 1 + delay_increase_percent / 100 + self.total_length_factor = 1.0 + + def _set_target_group_delay_s( + self, target_group_delay_s: NDArray[np.float64] + ): + """Set target group delay to use instead of phase response. + + Parameters + ---------- + target_group_delay : NDArray[np.float64] + Target group delay (in samples) to use. + + """ + assert ( + target_group_delay_s.ndim == 1 + ), "Target group delay can only have 1 dimension" + assert self.time_data_length_samples // 2 + 1 == len( + target_group_delay_s + ), ( + f"Target group delay with length {len(target_group_delay_s)} and " + + f"length {self.time_data_length_samples} do not match." + ) + self.target_group_delay_s = target_group_delay_s + + def _get_unscaled_preprocessed_group_delay(self) -> NDArray[np.float64]: + """Obtain reprocessed group delay for designing the FIR filter.""" + return ( + self.target_group_delay_s + + np.max(self.target_group_delay_s) + * self.group_delay_increase_factor + ) / self._get_group_delay_factor_in_seconds() + + def _get_group_delay_factor_in_samples(self) -> float: + """This is the conversion factor from unscaled to delay in samples.""" + return self.time_data_length_samples / 2 / np.pi + + def _get_group_delay_factor_in_seconds(self) -> float: + """This is the conversion factor from unscaled to delay in seconds.""" + return ( + self.time_data_length_samples / 2 / np.pi / self.sampling_rate_hz + ) + + def get_filter(self) -> Filter: + """Get FIR filter.""" + return Filter.from_ba(self.__design(), [1], self.sampling_rate_hz) + + def get_filter_as_ir(self) -> ImpulseResponse: + """Get the phase filter as an ImpulseResponse.""" + return ImpulseResponse(None, self.__design(), self.sampling_rate_hz) + + def __design(self) -> NDArray[np.float64]: + """Compute filter.""" + target_gd = self._get_unscaled_preprocessed_group_delay() + max_delay_samples_synthesized = int( + np.max(target_gd) * self._get_group_delay_factor_in_samples() + 1 + ) + gd_time_length_samples = self.time_data_length_samples + + # Interpolate if phase response is not much longer than maximum + # expected delay to increase frequency resolution + if max_delay_samples_synthesized * 20 > gd_time_length_samples: + warn( + f"Phase response (length {gd_time_length_samples}) " + + "is not much longer than maximum expected " + + f"group delay {max_delay_samples_synthesized} (less " + + "than 20 times longer). Spectrum interpolation " + + "is triggered, but it is recommended to pass a phase " + + "spectrum with finer resolution!" + ) + # Define new time length for the group delay + new_gd_time_length_samples = ( + int(max_delay_samples_synthesized * 20) + 1 + ) + # Ensure even length + new_gd_time_length_samples += new_gd_time_length_samples % 2 + # Interpolate + new_freqs = np.fft.rfftfreq( + new_gd_time_length_samples, 1 / self.sampling_rate_hz + ) + frequency_vector_hz = np.fft.rfftfreq( + self.time_data_length_samples, 1 / self.sampling_rate_hz + ) + target_gd = PchipInterpolator( + frequency_vector_hz, target_gd, extrapolate=True + )(new_freqs) * (gd_time_length_samples / len(new_freqs)) + gd_time_length_samples = new_gd_time_length_samples + + # Get new phase using group target group delay + new_phase = -cumulative_trapezoid(target_gd, initial=0) + + # Correct if nyquist is given + add_extra_sample = False + if gd_time_length_samples % 2 == 0: + add_extra_sample = new_phase[-1] % np.pi > np.pi / 2.0 + new_phase = _correct_for_real_phase_spectrum(new_phase) + + # Convert to time domain and trim + ir = np.fft.irfft(np.exp(1j * new_phase), gd_time_length_samples) + trim_length = int(max_delay_samples_synthesized + 1 + add_extra_sample) + ir = _pad_trim(ir, trim_length) + return ir + + +class PhaseLinearizer(GroupDelayDesigner): + """This class designs an FIR filter that linearizes a known phase + response. + + """ + + def __init__( + self, + phase_response: NDArray[np.float64], + time_data_length_samples: int, + sampling_rate_hz: int, + ): + """PhaseLinearizer creates an FIR filter that can linearize a phase + response. Use the method `set_parameters` to define specific design + parameters. + + Parameters + ---------- + phase_response : NDArray[np.float64] + Wrapped phase response that should be linearized. It is expected + to contain only the positive frequencies (including dc and + eventually nyquist). + time_data_length_samples : NDArray[np.float64] + Length of the time signal that gave the phase response. + sampling_rate_hz : int + Sampling rate corresponding to the passed phase response. It is + also used for the designed FIR filter. + + """ + self.phase_response = phase_response + self.set_parameters() + self.time_data_length_samples = time_data_length_samples + self.sampling_rate_hz = sampling_rate_hz + target_group_delay_s = ( + self._get_target_group_delay_in_seconds_from_phase() + ) + self._set_target_group_delay_s(target_group_delay_s) + + def __get_group_delay(self, phase_response) -> NDArray[np.float64]: + """Return the unscaled group delay from the phase response.""" + return -np.gradient(np.unwrap(phase_response)) + + def _get_target_group_delay_in_seconds_from_phase( + self, + ) -> NDArray[np.float64]: + """Return the target group delay in seconds. It is computed from the + phase response and has already the increase factor.""" + gd = self.__get_group_delay(self.phase_response) + target_gd = np.max(gd) * self.group_delay_increase_factor - gd + return target_gd * self._get_group_delay_factor_in_seconds() + + def _get_unscaled_preprocessed_group_delay(self) -> NDArray[np.float64]: + """Get the target group delay already corrected by the increase factor + and in no physical units (neither samples nor seconds).""" + return ( + self._get_target_group_delay_in_seconds_from_phase() + / self._get_group_delay_factor_in_seconds() + ) diff --git a/dsptoolbox/classes/impulse_response.py b/dsptoolbox/classes/impulse_response.py index d1e3851..de8319f 100644 --- a/dsptoolbox/classes/impulse_response.py +++ b/dsptoolbox/classes/impulse_response.py @@ -5,6 +5,7 @@ from .signal import Signal from ..plots import general_subplots_line +from ..tools import to_db class ImpulseResponse(Signal): @@ -300,11 +301,10 @@ def plot_spl( normalize_at_peak, range_db, window_length_s ) - peak_values = 10 * np.log10(np.max(self.time_data**2.0, axis=0)) + peak_values = to_db(np.max(np.abs(self.time_data), axis=0), True) - add_to_peak = 1 # Add 1 dB for better plotting max_values = ( - peak_values + add_to_peak + peak_values + 1 # Add 1 dB for better plotting if not normalize_at_peak else np.ones(self.number_of_channels) ) @@ -313,14 +313,7 @@ def plot_spl( if hasattr(self, "window"): ax[n].plot( self.time_vector_s, - 20 - * np.log10( - np.clip( - np.abs(self.window[:, n] / 1.1), - a_min=1e-40, - a_max=None, - ) - ) + to_db(self.window[:, n] / 1.1, True, dynamic_range_db=500) + max_values[n], alpha=0.75, ) @@ -339,12 +332,12 @@ def plot_time(self) -> tuple[Figure, list[Axes]]: """ fig, ax = super().plot_time() if hasattr(self, "window"): - mx = np.max(np.abs(self.time_data), axis=0) * 1.1 + mx = np.max(np.abs(self.time_data), axis=0) for n in range(self.number_of_channels): ax[n].plot( self.time_vector_s, - self.window[:, n] * mx[n] / 1.1, + self.window[:, n] * mx[n], alpha=0.75, ) return fig, ax diff --git a/dsptoolbox/classes/phase_linearizer.py b/dsptoolbox/classes/phase_linearizer.py deleted file mode 100644 index 4066cec..0000000 --- a/dsptoolbox/classes/phase_linearizer.py +++ /dev/null @@ -1,224 +0,0 @@ -from .filter import Filter -from .impulse_response import ImpulseResponse -import numpy as np -from scipy.integrate import cumulative_trapezoid -from scipy.interpolate import interp1d -from numpy.typing import NDArray -from .._general_helpers import ( - _correct_for_real_phase_spectrum, - _pad_trim, - _wrap_phase, -) -from warnings import warn - - -class PhaseLinearizer: - """This class designs an FIR filter that linearizes a known phase - response. - - """ - - def __init__( - self, - phase_response: NDArray[np.float64], - time_data_length_samples: int, - sampling_rate_hz: int, - target_group_delay_samples: NDArray[np.float64] | None = None, - ): - """PhaseLinearizer creates an FIR filter that can linearize a phase - response. Use the method `set_parameters` to define specific design - parameters. - - Parameters - ---------- - phase_response : NDArray[np.float64] - Wrapped phase response that should be linearized. It is expected - to contain only the positive frequencies (including dc and - eventually nyquist). - time_data_length_samples : NDArray[np.float64] - Length of the time signal that gave the phase response. - sampling_rate_hz : int - Sampling rate corresponding to the passed phase response. It is - also used for the designed FIR filter. - target_group_delay_samples : NDArray[np.float64] or `None`, optional - If passed, this overwrites the phase response and becomes the - target for the FIR filter. It must be given in samples for the - whole spectrum (only positive frequencies). For producing - satisfactory amplitude responses of the filter, it is recommended - that the target group delay be smooth and not very close to 0. - Default: `None`. - - """ - self.frequency_vector = np.fft.rfftfreq( - time_data_length_samples, 1 / sampling_rate_hz - ) - self.time_data_length_samples = time_data_length_samples - assert len(self.frequency_vector) == len(phase_response), ( - f"Phase response with length {len(phase_response)} and " - + f"length {time_data_length_samples} do not match." - ) - assert ( - phase_response.ndim == 1 - ), "Phase response should have only one dimension" - self.phase_response = phase_response - self.sampling_rate_hz = sampling_rate_hz - self.set_parameters() - if target_group_delay_samples is not None: - self._set_target_group_delay(target_group_delay_samples) - - def _set_target_group_delay(self, target_group_delay: NDArray[np.float64]): - """Set target group delay to use instead of phase response. - - Parameters - ---------- - target_group_delay : NDArray[np.float64] - Target group delay (in samples) to use. - - """ - assert ( - target_group_delay.ndim == 1 - ), "Target group delay can only have 1 dimension" - assert len(self.frequency_vector) == len( - target_group_delay - ), f"Target group delay shape {target_group_delay.shape} is invalid" - self.target_group_delay = target_group_delay - - def set_parameters( - self, - delay_increase_percent: float = 100.0, - total_length_factor: float = 1.0, - ): - """Set parameters for the FIR filter. - - Parameters - ---------- - delay_increase_percent : float, optional - This is the increase (in percentage) in delay to the current - maximum group delay of the phase response. Increasing this improves - the quality of the designed filter but also makes it longer. - Passing a value of 100 means that the total group delay will be - 2 times larger than the longest group delay in the phase response. - Default: 100. - total_length_factor : float, optional - The total length of the filter is based on the longest group delay. - This factor can augment it. Default: 1. - - Notes - ----- - - If there is a target group delay, no increase is applied by - `delay_increase_percent`, but `total_length_factor` is still used - for the output filter. - - """ - assert ( - delay_increase_percent >= 0 - ), "Delay increase must be larger than zero" - if total_length_factor < 1.0: - warn( - "Total length factor should not be less than 1. It " - + "will be clipped." - ) - self.group_delay_increase_factor = 1 + delay_increase_percent / 100 - self.total_length_factor = np.clip( - total_length_factor, a_min=1.0, a_max=None - ) - - def get_filter(self) -> Filter: - """Get FIR filter.""" - return Filter( - "other", - {"ba": [self._design(), [1]]}, - sampling_rate_hz=self.sampling_rate_hz, - ) - - def get_filter_as_ir(self) -> ImpulseResponse: - return ImpulseResponse(None, self._design(), self.sampling_rate_hz) - - def _design(self) -> NDArray[np.float64]: - """Compute filter.""" - if not hasattr(self, "target_group_delay"): - gd = self._get_group_delay() - gd_time_length_samples = self.time_data_length_samples - - max_delay_samples_synthesized = int( - np.max(gd) - * self._get_group_delay_factor_in_samples() - * self.group_delay_increase_factor - # Ceil - + 0.99999999999 - ) - target_gd = np.max(gd) * self.group_delay_increase_factor - gd - else: - target_gd = ( - self.target_group_delay - / self._get_group_delay_factor_in_samples() - ) - max_delay_samples_synthesized = int( - np.max(self.target_group_delay) + 1 - ) - gd_time_length_samples = self.time_data_length_samples - - # Interpolate if phase response is not much longer than maximum - # expected delay - if max_delay_samples_synthesized * 20 > gd_time_length_samples: - warn( - f"Phase response (length {gd_time_length_samples}) " - + "is not much longer than maximum expected " - + f"group delay {max_delay_samples_synthesized} (less " - + "than 20 times longer). Spectrum interpolation " - + "is triggered, but it is recommended to pass a phase " - + "spectrum with finer resolution!" - ) - # Define new time length for the group delay - new_gd_time_length_samples = ( - int(max_delay_samples_synthesized * 20) + 1 - ) - # Ensure even length - new_gd_time_length_samples += new_gd_time_length_samples % 2 - # Interpolate - new_freqs = np.fft.rfftfreq( - new_gd_time_length_samples, 1 / self.sampling_rate_hz - ) - target_gd = interp1d( - self.frequency_vector, - target_gd, - "cubic", - assume_sorted=True, - # Extrapolate if nyquist goes above last frequency bin - bounds_error=False, - fill_value=(target_gd[0], target_gd[-1]), - )(new_freqs) * (gd_time_length_samples / len(new_freqs)) - gd_time_length_samples = new_gd_time_length_samples - - # Get new phase using group target group delay - new_phase = -cumulative_trapezoid(target_gd, initial=0) - # Correct if nyquist is given - if gd_time_length_samples % 2 == 0: - new_phase = _correct_for_real_phase_spectrum( - _wrap_phase(new_phase) - ) - - # Convert to time domain and trim - ir = np.fft.irfft(np.exp(1j * new_phase), gd_time_length_samples) - trim_length = ( - int(max_delay_samples_synthesized * self.total_length_factor) - if self.total_length_factor - > 1.0 + (1 / max_delay_samples_synthesized) - else int(max_delay_samples_synthesized + 1) - ) - ir = _pad_trim(ir, trim_length) - return ir - - def _get_group_delay(self) -> NDArray[np.float64]: - """Return the unscaled group delay.""" - return -np.gradient(np.unwrap(self.phase_response)) - - def _get_group_delay_factor_in_samples(self) -> float: - """This is the conversion factor from unscaled to delay in samples.""" - return self.time_data_length_samples / 2 / np.pi - - def _get_group_delay_factor_in_seconds(self) -> float: - """This is the conversion factor from unscaled to delay in seconds.""" - return ( - self.time_data_length_samples / 2 / np.pi / self.sampling_rate_hz - ) diff --git a/dsptoolbox/classes/plots.py b/dsptoolbox/classes/plots.py index 54c5892..b59f1e7 100644 --- a/dsptoolbox/classes/plots.py +++ b/dsptoolbox/classes/plots.py @@ -5,7 +5,9 @@ import matplotlib.pyplot as plt from matplotlib.ticker import ScalarFormatter import numpy as np + from .._general_helpers import _find_nearest +from ..tools import to_db def _zp_plot(z, p, returns: bool = False): @@ -57,7 +59,7 @@ def _csm_plot(f, csm, range_x=None, log=True, with_phase=True, returns=True): ticks = ticks[(ticks > range_x[0]) & (ticks < range_x[-1])] ax[c1, c2].set_xticks(ticks) ax[c1, c2].get_xaxis().set_major_formatter(ScalarFormatter()) - ax[c1, c2].plot(f, 10 * np.log10(np.abs(csm[:, c1, c2]))) + ax[c1, c2].plot(f, to_db(csm[:, c1, c2], False)) if c1 != c2: axRight = ax[c1, c2].twinx() axRight.plot( diff --git a/dsptoolbox/classes/signal.py b/dsptoolbox/classes/signal.py index 3665bf7..f4da29f 100644 --- a/dsptoolbox/classes/signal.py +++ b/dsptoolbox/classes/signal.py @@ -25,6 +25,7 @@ _remove_ir_latency_from_phase, ) from .._standard import _welch, _group_delay_direct, _stft, _csm +from ..tools import to_db class Signal: @@ -364,8 +365,8 @@ def set_spectrum_parameters( scaling : str, optional Scaling for welch's method. Use `'power spectrum'`, `'power spectral density'`, `'amplitude spectrum'` or - `'amplitude spectral density'`. Pass `None` to avoid any scaling. - See references for details about scaling. + `'amplitude spectral density'`. Pass `None` to avoid any scaling + (power representation). See references for details about scaling. Default: `None`. References @@ -911,11 +912,15 @@ def plot_magnitude( self._spectrum_parameters["smoothe"] = prior_smoothing - scaling = ( - "amplitude" - if self._spectrum_parameters["scaling"] is None - else self._spectrum_parameters["scaling"] - ) + if self._spectrum_parameters["scaling"] is None: + scaling = ( + "power" + if self._spectrum_parameters["method"] == "welch" + else "amplitude" + ) + else: + scaling = self._spectrum_parameters["scaling"] + f, mag_db = _get_normalized_spectrum( f=f, spectra=sp, @@ -1045,16 +1050,14 @@ def plot_spl( td_squared_imaginary = oaconvolve( td_squared_imaginary, window, mode="same", axes=0 ) - complex_etc = 10 * np.log10( - np.clip( - td_squared_imaginary, - a_min=1e-80, - a_max=None, - ) + complex_etc = to_db( + td_squared_imaginary, + False, + 500 if range_db is None else range_db, ) - peak_values = 10 * np.log10(np.max(td_squared, axis=0)) - etc = 10 * np.log10(np.clip(td_squared, a_min=1e-80, a_max=None)) + etc = to_db(td_squared, False, 500) + peak_values = np.max(etc, axis=0) if normalize_at_peak: etc -= peak_values @@ -1201,16 +1204,15 @@ def plot_spectrogram( stft = stft[ids[0] : ids[1], :] if self._spectrogram_parameters["scaling"]: - if "power" in self._spectrogram_parameters["scaling"]: - factor = 10 - else: - factor = 20 + amplitude_scaling = ( + "power" not in self._spectrogram_parameters["scaling"] + ) zlabel = "dBFS" else: - factor = 20 + amplitude_scaling = True zlabel = "dBFS" - stft_db = factor * np.log10(np.clip(np.abs(stft), 1e-30, None)) + stft_db = to_db(stft, amplitude_scaling) if self.calibrated_signal: stft_db -= 20 * np.log10(2e-5) diff --git a/dsptoolbox/distances/_distances.py b/dsptoolbox/distances/_distances.py index 4f95ca5..04a136f 100644 --- a/dsptoolbox/distances/_distances.py +++ b/dsptoolbox/distances/_distances.py @@ -5,8 +5,7 @@ import numpy as np from scipy.integrate import simpson from numpy.typing import NDArray -from .._general_helpers import _compute_number_frames, _pad_trim -from .._standard import _rms +from .._general_helpers import _compute_number_frames, _pad_trim, _rms def _log_spectral_distance( diff --git a/dsptoolbox/effects/effects.py b/dsptoolbox/effects/effects.py index 648d730..9dfbdbf 100644 --- a/dsptoolbox/effects/effects.py +++ b/dsptoolbox/effects/effects.py @@ -4,9 +4,8 @@ _get_framed_signal, _reconstruct_framed_signal, _pad_trim, - _rms, ) -from .._general_helpers import _get_next_power_2 +from .._general_helpers import _get_next_power_2, _rms from ._effects import ( _arctan_distortion, _clean_signal, @@ -19,6 +18,7 @@ get_time_period_from_musical_rhythm, ) from ..plots import general_plot +from ..tools import to_db from scipy.signal.windows import get_window import numpy as np @@ -527,9 +527,7 @@ def _apply_adaptive_mode(self, signal: Signal) -> Signal: td = _get_framed_signal(td, len(self.window), self.step_size) # Get RMS values in dB for each time frame and channel - td_rms_db = 20 * np.log10( - np.clip(np.var(td, axis=0), a_min=1e-25, a_max=None) - ) + td_rms_db = to_db(np.var(td, axis=0), False) # Windowed signal td_windowed = td * self.window[:, np.newaxis, np.newaxis] @@ -1518,7 +1516,7 @@ def plot_delay(self): imp[i - delay_samples] ) - imp = 20 * np.log10(np.clip(np.abs(imp), a_min=1e-15, a_max=None)) + imp = to_db(imp, True) x = np.arange(len(imp)) / fs * 1e3 fig, ax = general_plot( diff --git a/dsptoolbox/filterbanks/__init__.py b/dsptoolbox/filterbanks/__init__.py index d4773c1..6c87a72 100644 --- a/dsptoolbox/filterbanks/__init__.py +++ b/dsptoolbox/filterbanks/__init__.py @@ -24,8 +24,9 @@ - `complementary_fir_filter()`: Create a complementary FIR filter from a linear-phase FIR prototype. - `LatticeLadderFilter()`: Filter with lattice-ladder topology. -- `PhaseLinearizer()`: Design an FIR filter that linearizes a phase spectrum - or matches a target group delay. +- `PhaseLinearizer()`: Design an FIR filter that linearizes a phase spectrum. +- `GroupDelayDesigner()`: Design an FIR filter that matches a target group + delay. - `StateVariableFilter()`: SV-Filter discretized with a topology-preserving transform. - `convert_into_lattice_filter()`: Turns a conventional filter into its @@ -51,7 +52,10 @@ ) from ..classes.lattice_ladder_filter import LatticeLadderFilter -from ..classes.phase_linearizer import PhaseLinearizer +from ..classes.group_delay_designer_phase_linearizer import ( + PhaseLinearizer, + GroupDelayDesigner, +) from ..classes.sv_filter import StateVariableFilter __all__ = [ @@ -65,6 +69,7 @@ "convert_into_lattice_filter", "LatticeLadderFilter", "PhaseLinearizer", + "GroupDelayDesigner", "StateVariableFilter", "pinking_filter", "matched_biquad", diff --git a/dsptoolbox/filterbanks/filterbanks.py b/dsptoolbox/filterbanks/filterbanks.py index ac978c5..f9b278a 100644 --- a/dsptoolbox/filterbanks/filterbanks.py +++ b/dsptoolbox/filterbanks/filterbanks.py @@ -1,6 +1,5 @@ """ -General use filter banks to be created and given back as a filter bank -object +General use filters and filter banks. """ import numpy as np diff --git a/dsptoolbox/generators/generators.py b/dsptoolbox/generators/generators.py index ee43818..bd15987 100644 --- a/dsptoolbox/generators/generators.py +++ b/dsptoolbox/generators/generators.py @@ -17,7 +17,7 @@ def noise( - type_of_noise: str = "white", + type_of_noise: str | float = "white", length_seconds: float = 1.0, sampling_rate_hz: int | None = None, peak_level_dbfs: float = -10.0, @@ -29,10 +29,12 @@ def noise( Parameters ---------- - type_of_noise : str, optional - Choose from `'white'`, `'pink'`, `'red'`, `'blue'`, `'violet'` or - `'grey'`. - Default: `'white'`. + type_of_noise : str {"white", "pink", "red", "blue", "violet", "grey"}, \ + float, optional + Type of noise to generate. If a float is passed, it corresponds to + `beta`, where `beta` is used to define the slope of the power spectral + density (psd) with `psd * frequency**(-beta)`. See notes for details. + Default: "white". length_seconds : float, optional Length of the generated signal in seconds. Default: 1. sampling_rate_hz : int @@ -45,8 +47,8 @@ def noise( fade : str, optional Type of fade done on the generated signal. By default, 10% of signal length (without the padding in the end) is faded at the beginning and - end. Options are `'exp'`, `'lin'`, `'log'`. Pass `None` for no - fading. Default: `'log'`. + end. Options are "exp", "lin", "log". Pass `None` for no + fading. Default: "log". padding_end_seconds : float, optional Padding at the end of signal. Default: 0. @@ -59,11 +61,22 @@ def noise( ---------- - https://en.wikipedia.org/wiki/Colors_of_noise + Notes + ----- + - Using the `beta` parameter to define noise is the most flexible approach. + For instance, `beta=1.0` will deliver pink noise, `beta=-1.0` corresponds + to blue. + """ assert sampling_rate_hz is not None, "Sampling rate can not be None" - valid_noises = ("white", "pink", "red", "blue", "violet", "grey") - type_of_noise = type_of_noise.lower() - assert type_of_noise in valid_noises, f"{type_of_noise} is not valid" + if type(type_of_noise) is str: + valid_noises = ("white", "pink", "red", "blue", "violet", "grey") + type_of_noise = type_of_noise.lower() + assert type_of_noise in valid_noises, f"{type_of_noise} is not valid" + else: + assert ( + type(type_of_noise) is float + ), "type_of_noise must be either str or float" assert length_seconds > 0, "Length has to be positive" assert peak_level_dbfs <= 0, "Peak level cannot surpass 0 dBFS" assert number_of_channels >= 1, "At least one channel should be generated" @@ -85,7 +98,7 @@ def noise( # frequencies id_low = np.argmin(np.abs(f - 15)) mag[0] = 0 - if type_of_noise != "white": + if type_of_noise != "white" or type_of_noise != 0.0: mag[:id_low] *= 1e-20 ph = np.random.uniform(-np.pi, np.pi, (len(f), number_of_channels)) @@ -106,9 +119,11 @@ def noise( elif type_of_noise == "grey": w = _frequency_weightning(f, "a", db_output=False) mag[id_low:, :] /= w[id_low:][..., None] + elif type(type_of_noise) is float: + mag[id_low:, :] *= (f[id_low:] ** (-type_of_noise * 0.5))[..., None] vec = np.fft.irfft(mag * np.exp(1j * ph), n=l_samples, axis=0) - vec = _normalize(vec, dbfs=peak_level_dbfs, mode="peak") + vec = _normalize(vec, dbfs=peak_level_dbfs, mode="peak", per_channel=True) if fade is not None: fade_length = 0.05 * length_seconds vec = _fade( @@ -147,8 +162,8 @@ def chirp( Parameters ---------- type_of_chirp : str, optional - Choose from `'lin'`, `'log'`. - Default: `'log'`. + Choose from "lin", "log". + Default: "log". range_hz : array-like with length 2 Define range of chirp in Hz. When `None`, all frequencies between 15 Hz and nyquist are taken. Default: `None`. @@ -163,8 +178,8 @@ def chirp( fade : str, optional Type of fade done on the generated signal. By default, 10% of signal length (without the padding in the end) is faded at the beginning and - end. Options are `'exp'`, `'lin'`, `'log'`. - Pass `None` for no fading. Default: `'log'`. + end. Options are "exp", "lin", "log". + Pass `None` for no fading. Default: "log". phase_offset : float, optional This is an offset in radians for the phase of the sine. Default: 0. padding_end_seconds : float, optional @@ -218,7 +233,9 @@ def chirp( chirp_td = np.sin( 2 * np.pi * range_hz[0] / np.log(k) * (k**t - 1) + phase_offset ) - chirp_td = _normalize(chirp_td, peak_level_dbfs, mode="peak") + chirp_td = _normalize( + chirp_td, peak_level_dbfs, mode="peak", per_channel=True + ) if fade is not None: fade_length = 0.05 * length_seconds @@ -324,8 +341,8 @@ def harmonic( fade : str, optional Type of fade done on the generated signal. By default, 5% of signal length (without the padding in the end) is faded at the beginning and - end. Options are `'exp'`, `'lin'`, `'log'`. - Pass `None` for no fading. Default: `'log'`. + end. Options are "exp", "lin", "log". + Pass `None` for no fading. Default: "log". padding_end_seconds : float, optional Padding at the end of signal. Default: 0. @@ -358,7 +375,7 @@ def harmonic( # Generate wave td = np.sin(n_vec) - td = _normalize(td, peak_level_dbfs, mode="peak") + td = _normalize(td, peak_level_dbfs, mode="peak", per_channel=True) if fade is not None: fade_length = 0.05 * length_seconds @@ -405,8 +422,8 @@ def oscillator( length_seconds : float, optional Length of the generated signal in seconds. Default: 1. mode : str, optional - Type of wave to generate. Choose from `'harmonic'`, `'square'`, - `'triangle'` or `'sawtooth'`. Default: `'harmonic'`. + Type of wave to generate. Choose from "harmonic", "square", + "triangle" or "sawtooth". Default: "harmonic". harmonic_cutoff_hz : float, optional It is possible to pass a cutoff frequency for the harmonics. If `None`, they are computed up until before the nyquist frequency. @@ -423,8 +440,8 @@ def oscillator( fade : str, optional Type of fade done on the generated signal. By default, 5% of signal length (without the padding in the end) is faded at the beginning and - end. Options are `'exp'`, `'lin'`, `'log'`. - Pass `None` for no fading. Default: `'log'`. + end. Options are "exp", "lin", "log". + Pass `None` for no fading. Default: "log". padding_end_seconds : float, optional Padding at the end of signal. Default: 0. @@ -512,7 +529,7 @@ def oscillator( k += 1 td *= -8 / np.pi**2 - td = _normalize(td, peak_level_dbfs, mode="peak") + td = _normalize(td, peak_level_dbfs, mode="peak", per_channel=True) if fade is not None: fade_length = 0.05 * length_seconds diff --git a/dsptoolbox/room_acoustics/_room_acoustics.py b/dsptoolbox/room_acoustics/_room_acoustics.py index 23d3a7b..5c2a182 100644 --- a/dsptoolbox/room_acoustics/_room_acoustics.py +++ b/dsptoolbox/room_acoustics/_room_acoustics.py @@ -6,8 +6,10 @@ from numpy.typing import NDArray from scipy.stats import pearsonr from warnings import warn + from ..plots import general_plot from ..transfer_functions._transfer_functions import _trim_ir +from ..tools import from_db, to_db def _reverb( @@ -103,19 +105,23 @@ def _find_ir_start( Returns ------- - ind : int + int Index of the start of the IR. It is the sample before the given threshold is surpassed for the first time. """ - energy_curve = ir**2 - energy_curve_db = 10 * np.log10( - np.clip(energy_curve / np.max(energy_curve), a_min=1e-30, a_max=None) + signal_power = ir**2 + start_ir = int(np.argmax(ir)) + + # -20 dB distance from peak value according to ISO 3382-1:2009-10 + threshold = signal_power[start_ir] * from_db( + -np.abs(threshold_dbfs), False ) - ind = int(np.where(energy_curve_db > threshold_dbfs)[0][0] - 1) - if ind < 0: - ind = 0 - return ind + + for start_ir in range(start_ir, -1, -1): + if signal_power[start_ir] < threshold: + break + return start_ir def _complex_mode_identification( @@ -695,10 +701,11 @@ def get_analytical_transfer_function( modes = modes[modes[:, 0].argsort()] if generate_plot: - ind_norm = np.argmax(np.abs(p)) + p_db = to_db(p, True) + p_db -= np.max(p_db) plot = general_plot( f, - 20 * np.log10(np.abs(p)) - 20 * np.log10(np.abs(p[ind_norm])), + p_db, range_x=[f[0], f[-1]], tight_layout=True, returns=True, @@ -985,7 +992,7 @@ def _c80_from_rir( else: stop = len(td) td **= 2 - return 10 * np.log10(np.sum(td[:window]) / np.sum(td[window:stop])) + return to_db(np.sum(td[:window]) / np.sum(td[window:stop]), False) def _ts_from_rir( @@ -1178,25 +1185,23 @@ def _compute_energy_decay_curve( trim_automatically: bool, fs_hz: int, ) -> NDArray[np.float64]: - """Get the energy decay curve from an energy time curve.""" + """Get the energy decay curve.""" # start_index might be the last index below -20 dB relative to peak value. # If so, the normalization of the edc should be done with the beginning if trim_automatically: - start_index, stopping_index, impulse_index = _trim_ir( + _, stopping_index, _ = _trim_ir( time_data, fs_hz, - offset_start_s=20e-3, + offset_start_s=1e-3, ) else: - start_index = 0 stopping_index = len(time_data) + start_index = _find_ir_start(time_data) signal_power = time_data[start_index:stopping_index] ** 2 edc = np.sum(signal_power) - np.cumsum(signal_power) - epsilon = 1e-50 - edc = 10 * np.log10(np.clip(edc, a_min=epsilon, a_max=None)) - edc -= edc[impulse_index] - return edc + edc = to_db(edc, False) + return edc - edc[0] if __name__ == "__main__": @@ -1228,7 +1233,7 @@ def _compute_energy_decay_curve( )[0] import matplotlib.pyplot as plt - plt.semilogx(f, 20 * np.log10(np.abs(p1)), label="mean alpha") - plt.semilogx(f, 20 * np.log10(np.abs(p2)), label="detailed alpha") + plt.semilogx(f, to_db(p1, True), label="mean alpha") + plt.semilogx(f, to_db(p2, True), label="detailed alpha") plt.legend() plt.show() diff --git a/dsptoolbox/room_acoustics/room_acoustics.py b/dsptoolbox/room_acoustics/room_acoustics.py index 81dd4d4..d0bba45 100644 --- a/dsptoolbox/room_acoustics/room_acoustics.py +++ b/dsptoolbox/room_acoustics/room_acoustics.py @@ -21,6 +21,7 @@ ) from .._general_helpers import _find_nearest, _normalize, _pad_trim from ..standard_functions import pad_trim +from ..tools import to_db def reverb_time( @@ -189,7 +190,7 @@ def find_modes( dist_samp = 1 if dist_samp < 1 else dist_samp id_cmif, _ = find_peaks( - 10 * np.log10(cmif), + to_db(cmif, False), distance=dist_samp, # width=dist_samp, # Is width here a good idea? prominence=prominence_db, @@ -252,13 +253,13 @@ def convolve_rir_on_signal( for n in range(signal.number_of_channels): if keep_peak_level: - old_peak = 20 * np.log10(np.max(np.abs(signal.time_data[:, n]))) + old_peak = to_db(np.max(np.abs(signal.time_data[:, n])), True) new_time_data[:, n] = convolve( signal.time_data[:, n], rir.time_data[:, 0], mode="full" )[:total_length_samples] if keep_peak_level: new_time_data[:, n] = _normalize( - new_time_data[:, n], old_peak, mode="peak" + new_time_data[:, n], old_peak, mode="peak", per_channel=True ) new_sig = signal.copy() diff --git a/dsptoolbox/standard_functions.py b/dsptoolbox/standard_functions.py index 8a82514..8ce19e3 100644 --- a/dsptoolbox/standard_functions.py +++ b/dsptoolbox/standard_functions.py @@ -25,7 +25,6 @@ _latency, _indices_above_threshold_dbfs, _detrend, - _rms, _fractional_delay_filter, ) from ._general_helpers import ( @@ -36,7 +35,9 @@ _get_smoothing_factor_ema, _fractional_latency, _get_correlation_of_latencies, + _rms, ) +from .tools import from_db def latency( @@ -378,43 +379,51 @@ def resample(sig: Signal, desired_sampling_rate_hz: int) -> Signal: def normalize( sig: Signal | MultiBandSignal, - peak_dbfs: float = -6, + norm_dbfs: float = -6, + mode: str = "peak", each_channel: bool = False, ) -> Signal | MultiBandSignal: - """Normalizes a signal to a given peak value. It either normalizes each + """Normalizes a signal to a given dBFS value. It either normalizes each channel or the signal as a whole. Parameters ---------- sig : `Signal` or `MultiBandSignal` Signal to be normalized. - peak_dbfs : float, optional - dBFS to which to normalize peak. Default: -6. + norm_dbfs : float, optional + Value in dBFS to reach after normalization. Default: -6. + mode : str, {"peak", "rms"}, optional + Normalization mode. Either normalize peak or RMS value. See notes. + Default: "peak". each_channel : bool, optional When `True`, each channel on its own is normalized. When `False`, - the peak value for all channels is regarded. Default: `False`. + the peak or rms value across all channels is regarded. + Default: `False`. Returns ------- new_sig : `Signal` or `MultiBandSignal` Normalized signal. + Notes + ----- + - Normalization can be done for peak or RMS. The latter might generate a + signal with samples above 0 dBFS if `signal.constrain_amplitude=False`. + """ if isinstance(sig, Signal): + mode = mode.lower() + assert mode in ("peak", "rms"), "Normalization mode not supported" new_sig = sig.copy() - new_time_data = np.empty_like(sig.time_data) - if each_channel: - for n in range(sig.number_of_channels): - new_time_data[:, n] = _normalize( - sig.time_data[:, n], peak_dbfs - ) - else: - new_time_data = _normalize(sig.time_data, peak_dbfs) - new_sig.time_data = new_time_data + new_sig.time_data = _normalize( + new_sig.time_data, norm_dbfs, mode, each_channel + ) elif isinstance(sig, MultiBandSignal): new_sig = sig.copy() for ind in range(sig.number_of_bands): - new_sig.bands[ind] = normalize(sig.bands[ind], peak_dbfs) + new_sig.bands[ind] = normalize( + sig.bands[ind], norm_dbfs, mode, each_channel + ) else: raise TypeError( "Type of signal is not valid. Use either Signal or MultiBandSignal" @@ -1222,3 +1231,46 @@ def dither( else: new_s.time_data = new_s.time_data + noise return new_s + + +def apply_gain( + signal: Signal | MultiBandSignal, gain_db: float | NDArray[np.float64] +) -> Signal | MultiBandSignal: + """Apply some gain to a signal. It can be done to the signal as a whole + or per channel. + + Parameters + ---------- + signal : Signal, MultiBandSignal + Signal to apply gain to. + gain_db : float, NDArray[np.float64] + Gain in dB to be applied. If it is an array, it should have as many + elements as there are channels in the signal. + + Returns + ------- + Signal, MultiBandSignal + Signal with new gains. + + Notes + ----- + If `constrain_amplitude=True` in the signal, the resulting time data might + get rescaled after applying the gain. + + """ + if isinstance(signal, Signal): + gain_linear = from_db(gain_db, True) + new_sig = signal.copy() + new_sig.time_data = new_sig.time_data * gain_linear + if new_sig.time_data_imaginary is not None: + new_sig.time_data_imaginary = ( + new_sig.time_data_imaginary * gain_linear + ) + return new_sig + elif isinstance(signal, MultiBandSignal): + new_mb = signal.copy() + for ind in range(new_mb.number_of_bands): + new_mb.bands[ind] = apply_gain(new_mb.bands[ind], gain_db) + return new_mb + else: + raise TypeError("No valid type was passed") diff --git a/dsptoolbox/tools.py b/dsptoolbox/tools.py index f341822..38b6ae7 100644 --- a/dsptoolbox/tools.py +++ b/dsptoolbox/tools.py @@ -18,6 +18,8 @@ _interpolate_fr as interpolate_fr, _time_smoothing as time_smoothing, _scale_spectrum as scale_spectrum, + to_db, + from_db, ) from ._standard import ( @@ -54,72 +56,6 @@ def log_frequency_vector( ) -def to_db( - x: NDArray[np.float64], - amplitude_input: bool, - dynamic_range_db: float | None = None, - min_value: float | None = float(np.finfo(np.float64).smallest_normal), -) -> NDArray[np.float64]: - """Convert to dB from amplitude or power representation. Clipping small - values can be activated in order to avoid -inf dB outcomes. - - Parameters - ---------- - x : NDArray[np.float64] - Array to convert to dB. - amplitude_input : bool - Set to True if the values in x are in their linear form. False means - they have been already squared, i.e., in their power form. - dynamic_range_db : float, None, optional - If specified, a dynamic range in dB for the vector is applied by - finding its largest value and clipping to `max - dynamic_range_db`. - This will always overwrite `min_value` if specified. Pass None to - ignore. Default: None. - min_value : float, None, optional - Minimum value to clip `x` before converting into dB in order to avoid - `np.nan` or `-np.inf` in the output. Pass None to ignore. Default: - `np.finfo(np.float64).smallest_normal`. - - Returns - ------- - NDArray[np.float64] - New array or float in dB. - - """ - factor = 20.0 if amplitude_input else 10.0 - - if min_value is None and dynamic_range_db is None: - return factor * np.log10(np.abs(x)) - - x_abs = np.abs(x) - - if dynamic_range_db is not None: - min_value = np.max(x_abs) * 10.0 ** (-abs(dynamic_range_db) / factor) - - return factor * np.log10(np.clip(x_abs, a_min=min_value, a_max=None)) - - -def from_db(x: float | NDArray[np.float64], amplitude_output: bool): - """Get the values in their amplitude or power form from dB. - - Parameters - ---------- - x : float, NDArray[np.float64] - Values in dB. - amplitude_output : bool - When True, the values are returned in their linear form. Otherwise, - the squared (power) form is returned. - - Returns - ------- - float NDArray[np.float64] - Converted values - - """ - factor = 20.0 if amplitude_output else 10.0 - return 10 ** (x / factor) - - def get_exact_value_at_frequency( freqs_hz: NDArray[np.float64], y: NDArray[Any], f: float = 1e3 ): diff --git a/dsptoolbox/transfer_functions/_transfer_functions.py b/dsptoolbox/transfer_functions/_transfer_functions.py index a54b53c..0a87c26 100644 --- a/dsptoolbox/transfer_functions/_transfer_functions.py +++ b/dsptoolbox/transfer_functions/_transfer_functions.py @@ -8,13 +8,14 @@ from scipy.stats import pearsonr from warnings import warn from numpy.typing import NDArray + from .._general_helpers import ( _find_nearest, _calculate_window, _pad_trim, _get_chirp_rate, - _get_smoothing_factor_ema, ) +from ..tools import to_db, time_smoothing def _spectral_deconvolve( @@ -339,25 +340,18 @@ def _trim_ir( impulse_index -= start_index # ETC (from impulse until end) - - etc = 20 * np.log10( - np.clip( - np.abs( - hilbert( - time_data[start_index + impulse_index :], - N=next_fast_len( - len(time_data) - start_index - impulse_index, False - ), - ) + etc = to_db( + hilbert( + time_data[start_index + impulse_index :], + N=next_fast_len( + len(time_data) - start_index - impulse_index, False ), - a_min=1e-50, - a_max=None, - ) + ), + True, ) # Smoothing of ETC - smoothing_factor = _get_smoothing_factor_ema(20e-3, fs_hz) - envelope = lfilter([smoothing_factor], [1, -(1 - smoothing_factor)], etc) + envelope = time_smoothing(etc, fs_hz, 20e-3, None) # Ensure that energy is always decaying by checking it in non-overlapping # windows. When the energy of a window is larger than the previous one, @@ -369,7 +363,7 @@ def _trim_ir( # with the highest weight. If all are above -0.7, method failed -> no # trimming - window_lengths = (np.array([10, 30, 50, 80, 100]) * 1e-3 * fs_hz).astype( + window_lengths = (np.array([10, 30, 50, 80]) * 1e-3 * fs_hz + 0.5).astype( int ) end = np.zeros(len(window_lengths)) diff --git a/dsptoolbox/transfer_functions/transfer_functions.py b/dsptoolbox/transfer_functions/transfer_functions.py index 0135aaa..716a2d6 100644 --- a/dsptoolbox/transfer_functions/transfer_functions.py +++ b/dsptoolbox/transfer_functions/transfer_functions.py @@ -25,7 +25,6 @@ _find_frequencies_above_threshold, _fractional_octave_smoothing, _correct_for_real_phase_spectrum, - _wrap_phase, ) from .._standard import ( _welch, @@ -42,6 +41,7 @@ from ..generators import dirac from ..filterbanks import linkwitz_riley_crossovers from ..room_acoustics._room_acoustics import _find_ir_start +from ..tools import to_db def spectral_deconvolve( @@ -716,7 +716,7 @@ def lin_phase_from_mag( phase = -2 * np.pi * f_vec * gd_ms if spectrum_has_nyquist: - phase = _correct_for_real_phase_spectrum(_wrap_phase(phase)) + phase = _correct_for_real_phase_spectrum(phase) lin_spectrum[:, n] = spectrum[:, n] * np.exp(1j * phase) time_data = np.fft.irfft(lin_spectrum, axis=0, n=original_length_time_data) sig_lin_phase = ImpulseResponse( @@ -1710,7 +1710,7 @@ def harmonic_distortion_analysis( # Make plot if generate_plot: - ax.plot(f, 10 * np.log10(sp_power)) + ax.plot(f, to_db(sp_power, False)) # Accumulate time samples for THD+N thd[pos_thd - len(harm[i]) : pos_thd] = harm[i].time_data.squeeze() @@ -1732,7 +1732,7 @@ def harmonic_distortion_analysis( freqs_thd = freqs[:ind_end] if generate_plot: sp_thd[sp_thd == 0] = np.nan - ax.plot(freqs_thd, 10 * np.log10(sp_thd), label="THD") + ax.plot(freqs_thd, to_db(sp_thd, False), label="THD") np.nan_to_num(sp_thd, False, 0) # THD+N @@ -1745,7 +1745,7 @@ def harmonic_distortion_analysis( if generate_plot: ax.plot( f_thd_n, - 10 * np.log10(sp_thd_n), + to_db(sp_thd_n, False), label="THD+N", ) ax.legend( diff --git a/dsptoolbox/transforms/transforms.py b/dsptoolbox/transforms/transforms.py index 7f00e4d..52aebaf 100644 --- a/dsptoolbox/transforms/transforms.py +++ b/dsptoolbox/transforms/transforms.py @@ -15,6 +15,7 @@ _squeeze_scalogram, _get_kernels_vqt, ) +from ..tools import to_db import numpy as np from numpy.typing import NDArray @@ -142,9 +143,12 @@ def log_mel_spectrogram( if stft_parameters is not None: s.set_spectrogram_parameters(**stft_parameters) time_s, f_hz, sp = s.get_spectrogram() + mfilt, f_mel = mel_filterbank(f_hz, range_hz, n_bands, normalize=True) - log_mel_sp = np.tensordot(mfilt, np.abs(sp), axes=(-1, 0)) - log_mel_sp = 20 * np.log10(np.clip(log_mel_sp, a_min=1e-20, a_max=None)) + log_mel_sp = np.tensordot(mfilt, np.abs(sp) ** 2.0, axes=(-1, 0)) + + log_mel_sp = to_db(log_mel_sp, False) + if generate_plot: fig, ax = general_matrix_plot( log_mel_sp[..., channel], @@ -189,7 +193,8 @@ def mel_filterbank( Returns ------- mel_filters : NDArray[np.float64] - Mel filters matrix with shape (bands, frequency). + Mel filters matrix with shape (bands, frequency). These are to be + applied to a power response (squared spectrum). mel_center_freqs : NDArray[np.float64] Vector containing mel center frequencies. @@ -280,20 +285,22 @@ def plot_waterfall( sig.set_spectrogram_parameters(**stft_parameters) t, f, stft = sig.get_spectrogram() - stft = np.abs(stft[..., 0]) - z_label_extra = "" - if dynamic_range_db is not None: - stft /= np.max(stft) - clip_val = 10 ** (-dynamic_range_db / 20) - stft = np.clip(stft, a_min=clip_val, a_max=None) - z_label_extra = "FS (normalized @ peak)" + if sig._spectrum_parameters["scaling"] is None: + amplitude_scaling = True + else: + amplitude_scaling = "amplitude" in sig._spectrum_parameters["scaling"] fig, ax = plt.subplots(figsize=(10, 8), subplot_kw=dict(projection="3d")) tt, ff = np.meshgrid(t, f) - ax.plot_surface(tt, ff, 20 * np.log10(stft), cmap="magma") + ax.plot_surface( + tt, + ff, + to_db(stft[..., channel], amplitude_scaling, dynamic_range_db), + cmap="magma", + ) ax.set_xlabel("Time / s") ax.set_ylabel("Frequency / Hz") - ax.set_zlabel("dB" + z_label_extra) + ax.set_zlabel("dB") fig.tight_layout() return fig, ax @@ -372,21 +379,21 @@ def mfcc( signal.set_spectrogram_parameters(**stft_parameters) time_s, f, sp = signal.get_spectrogram() - # Get Log power spectrum - log_sp = 2 * np.log(np.abs(sp)) - # Mel filters if mel_filters is None: mel_filters, f_mel = mel_filterbank(f, None, n_bands=40) else: - assert mel_filters.shape[1] == log_sp.shape[0], ( + assert mel_filters.shape[1] == sp.shape[0], ( f"Shape of the mel filter matrix {mel_filters.shape} does " - + f"not match the STFT {log_sp.shape}" + + f"not match the STFT {sp.shape}" ) f_mel = np.array([0, mel_filters.shape[0]]) # Convert from Hz to Mel - log_sp = np.tensordot(mel_filters, log_sp, axes=(-1, 0)) + sp = np.tensordot(mel_filters, np.abs(sp) ** 2.0, axes=(-1, 0)) + + # Get Log power spectrum + log_sp = to_db(sp, False) # Discrete cosine transform mfcc = np.abs(dct(log_sp, type=2, axis=0)) diff --git a/examples/standard_module.ipynb b/examples/standard_module.ipynb index 7a342c9..e084554 100644 --- a/examples/standard_module.ipynb +++ b/examples/standard_module.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -32,15 +32,16 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "RMS of speech: [-19.50131172]\n", - "RMS of speech (normalized): [-22.49229458]\n", + "RMS of speech: [-19.501312]\n", + "RMS of speech (normalized): [-35.]\n", + "RMS of speech (normalized): [-22.49229486]\n", "Length of speech [samples]: 189056\n", "Length of speech (normalized) [samples]: 96000\n", "Number of channels in merged signal: 2\n" @@ -48,7 +49,7 @@ }, { "data": { - "image/png": "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tVoNpZLXvoiIpMREgYiIysTLy0vzf3t7e9SrV6/Y47y8PADA1atXsXv3bqxfv17zfH5+PsLDw3Ue19Cwo/DwcPj4+KBfv35o3rw5unXrhldeeQXW1vw6IyKSGv+yEhFRmZSsfqTvir5KpcLo0aPRv3//Ytvt7e117h8ZGYnhw4frfM7BwQEbNmzAiRMncPDgQWzevBnr1q3D5s2b4eHhYfyHICIivXifloiIZNW4cWMkJiaiYcOGmn/r16/H4cOHtfa9d+8esrOz0ahRI53HOnPmDFauXIl27dph0qRJ2LNnD3JzcxEVFSXzpyAiqnp4R4GIiGQ1cuRIvP766wgMDESXLl3w559/4scff8RPP/2ktW9kZCTatWun91j29vZYtmwZatasifbt2+PkyZPIysqCr6+vnB+BiKhKYqJARESyCg4OxoIFC7BkyRIsWLAADRo0wBdffIE2bdpo7Xvs2DGEhYXpPZa/vz9mz56N5cuX4/PPP0fdunWxcOFCNGnSRM6PQERUJXFlZiIiIiIi0sI5CkREREREpIWJAhERERERaWGiQEREREREWpgoEBERERGRFiYKRERERESkhYkCERERERFpYaJARERERERamCgQEREREZEWJgpERERERKSFiQIREREREWlhokBERERERFqYKBARERERkZb/B+4qRelioUXkAAAAAElFTkSuQmCC", + "image/png": "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tVoNpZLXvoiIpMREgYiIysTLy0vzf3t7e9SrV6/Y47y8PADA1atXsXv3bqxfv17zfH5+PsLDw3Ue19Cwo/DwcPj4+KBfv35o3rw5unXrhldeeQXW1vw6IyKSGv+yEhFRmZSsfqTvir5KpcLo0aPRv3//Ytvt7e117h8ZGYnhw4frfM7BwQEbNmzAiRMncPDgQWzevBnr1q3D5s2b4eHhYfyHICIivXifloiIZNW4cWMkJiaiYcOGmn/r16/H4cOHtfa9d+8esrOz0ahRI53HOnPmDFauXIl27dph0qRJ2LNnD3JzcxEVFSXzpyAiqnp4R4GIiGQ1cuRIvP766wgMDESXLl3w559/4scff8RPP/2ktW9kZCTatWun91j29vZYtmwZatasifbt2+PkyZPIysqCr6+vnB+BiKhKYqJARESyCg4OxoIFC7BkyRIsWLAADRo0wBdffIE2bdpo7Xvs2DGEhYXpPZa/vz9mz56N5cuX4/PPP0fdunWxcOFCNGnSRM6PQERUJXFlZiIiIiIi0sI5CkREREREpIWJAhERERERaWGiQEREREREWpgoEBERERGRFiYKRERERESkhYkCERERERFpYaJARERERERamCgQEREREZEWJgpERERERKSFiQIREREREWlhokBERERERFqYKBARERERkZb/B+4qRelioUXkAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -58,7 +59,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -74,7 +75,10 @@ "print('RMS of speech: ', dsp.rms(speech))\n", "\n", "# Normalize signal\n", - "speech_norm = dsp.normalize(speech, peak_dbfs=-3, each_channel=False)\n", + "speech_norm = dsp.normalize(speech, norm_dbfs=-35, mode=\"rms\", each_channel=False)\n", + "print('RMS of speech (normalized): ', dsp.rms(speech_norm))\n", + "\n", + "speech_norm = dsp.normalize(speech, norm_dbfs=-3, each_channel=False)\n", "print('RMS of speech (normalized): ', dsp.rms(speech_norm))\n", "\n", "# Pad or trim a signal\n", @@ -108,17 +112,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/neumanndev/opt/anaconda3/envs/dsp-dev12/lib/python3.12/site-packages/dsptoolbox/_standard.py:864: RuntimeWarning: divide by zero encountered in log10\n", - " momentary_gain = 10 * np.log10(momentary_gain)\n" - ] - }, { "data": { "text/plain": [ @@ -126,13 +122,13 @@ " [])" ] }, - "execution_count": 4, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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RKRPTBSIiKhR/Pz8VP+2tbVF27Zt1f6uqqoCAFy7dg179+7FDz/8oLq/uroa/fv3r3e/DQ076t+/P4KDgzF+/Hh06tQJw4YNwwMPPACplIczIiJ94y8rERE1yp3Vj+52RV+hUGDOnDmYNGmS2u22trb1bn/8+HHMnDmz3vvs7Oywfft2xMTE4ODBg9i5cye2bNmCnTt3wsvLS/cXQUREd8V+WiIiMqj27dsjPT0d7dq1U/33ww8/4PDhwxrb5uTkoKKiAgEBAfXu6+zZs/j888/Ru3dvLFmyBPv27YNMJkNsbKyBXwURUcvDHgUiIjKo2bNn45FHHkF4eDgGDx6MAwcO4Ouvv8Y333yjse3x48fRu3fvu+7L1tYW69evh4eHB/r06YNTp06hvLwcISEhhnwJREQtEhMFIiIyqMjISKxduxYfffQR1q5dC39/f/z3v/9Fz549NbY9ceIEoqOj77qvsLAwrF69Gp988gnefPNN+Pj44N1330VQUJAhXwIRUYvElZmJiIiIiEgD5ygQEREREZEGJgpERERERKSBiQIREREREWlgokBERERERBqYKBARERERkQYmCkREREREpIGJAhERERERaWCiQEREREREGpgoEBERERGRBiYKRERERESkgYkCERERERFpYKJAREREREQa/h/ffHEgkDP4zAAAAABJRU5ErkJggg==", + "image/png": "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", "text/plain": [ "
" ] @@ -166,7 +162,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -180,7 +176,7 @@ "source": [ "aud1 = dsp.Signal(join('data', 'chirp.wav'))\n", "aud2 = dsp.Signal(join('data', 'chirp_mono.wav'))\n", - "print('Latency [s]: ', dsp.latency(aud2, aud1) / aud1.sampling_rate_hz)" + "print('Latency [s]: ', dsp.latency(aud2, aud1)[0] / aud1.sampling_rate_hz)" ] }, { @@ -194,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -213,13 +209,13 @@ " [])" ] }, - "execution_count": 6, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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tVoNpZLXvoiIpMREgYiIysTLy0vzf3t7e9SrV6/Y47y8PADA1atXsXv3bqxfv17zfH5+PsLDw3Ue19Cwo/DwcPj4+KBfv35o3rw5unXrhldeeQXW1vw6IyKSGv+yEhFRmZSsfqTvir5KpcLo0aPRv3//Ytvt7e117h8ZGYnhw4frfM7BwQEbNmzAiRMncPDgQWzevBnr1q3D5s2b4eHhYfyHICIivXifloiIZNW4cWMkJiaiYcOGmn/r16/H4cOHtfa9d+8esrOz0ahRI53HOnPmDFauXIl27dph0qRJ2LNnD3JzcxEVFSXzpyAiqnp4R4GIiGQ1cuRIvP766wgMDESXLl3w559/4scff8RPP/2ktW9kZCTatWun91j29vZYtmwZatasifbt2+PkyZPIysqCr6+vnB+BiKhKYqJARESyCg4OxoIFC7BkyRIsWLAADRo0wBdffIE2bdpo7Xvs2DGEhYXpPZa/vz9mz56N5cuX4/PPP0fdunWxcOFCNGnSRM6PQERUJXFlZiIiIiIi0sI5CkREREREpIWJAhERERERaWGiQEREREREWpgoEBERERGRFiYKRERERESkhYkCERERERFpYaJARERERERamCgQEREREZEWJgpERERERKSFiQIREREREWlhokBERERERFqYKBARERERkZb/B+4qRelioUXkAAAAAElFTkSuQmCC", + "image/png": "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tVoNpZLXvoiIpMREgYiIysTLy0vzf3t7e9SrV6/Y47y8PADA1atXsXv3bqxfv17zfH5+PsLDw3Ue19Cwo/DwcPj4+KBfv35o3rw5unXrhldeeQXW1vw6IyKSGv+yEhFRmZSsfqTvir5KpcLo0aPRv3//Ytvt7e117h8ZGYnhw4frfM7BwQEbNmzAiRMncPDgQWzevBnr1q3D5s2b4eHhYfyHICIivXifloiIZNW4cWMkJiaiYcOGmn/r16/H4cOHtfa9d+8esrOz0ahRI53HOnPmDFauXIl27dph0qRJ2LNnD3JzcxEVFSXzpyAiqnp4R4GIiGQ1cuRIvP766wgMDESXLl3w559/4scff8RPP/2ktW9kZCTatWun91j29vZYtmwZatasifbt2+PkyZPIysqCr6+vnB+BiKhKYqJARESyCg4OxoIFC7BkyRIsWLAADRo0wBdffIE2bdpo7Xvs2DGEhYXpPZa/vz9mz56N5cuX4/PPP0fdunWxcOFCNGnSRM6PQERUJXFlZiIiIiIi0sI5CkREREREpIWJAhERERERaWGiQEREREREWpgoEBERERGRFiYKRERERESkhYkCERERERFpYaJARERERERamCgQEREREZEWJgpERERERKSFiQIREREREWlhokBERERERFqYKBARERERkZb/B+4qRelioUXkAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -253,7 +249,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.1" + "version": "3.12.4" }, "orig_nbformat": 4 }, diff --git a/tests/test_filterbanks.py b/tests/test_filterbanks.py index d48bed8..9b31d30 100644 --- a/tests/test_filterbanks.py +++ b/tests/test_filterbanks.py @@ -149,12 +149,9 @@ def test_phase_linearizer(self): np.angle(sp[:, 0]), len(ir), fs_hz ) with pytest.raises(AssertionError): - pl.set_parameters(-10, 2) + pl.set_parameters(-10) pl.get_filter_as_ir() pl.get_filter() - - # Parameters - pl.set_parameters(80, 0.8) pl.set_parameters() # Phase linearizer – with interpolation @@ -167,17 +164,26 @@ def test_phase_linearizer(self): pl.get_filter_as_ir() pl.get_filter() + def test_group_delay_designer(self): + fs_hz = 48_000 + fb = dsp.filterbanks.linkwitz_riley_crossovers( + [570, 2000], order=[2, 2], sampling_rate_hz=fs_hz + ) + ir = fb.get_ir(length_samples=2**14).collapse() + # Group delay-based correction ir = fb.get_ir(length_samples=2**14).collapse() - _, gd = dsp.transfer_functions.group_delay(ir) + _, gd = dsp.transfer_functions.group_delay(ir, method="matlab") gd = np.max(gd) * 2 - gd - gd *= ir.sampling_rate_hz - pl = dsp.filterbanks.PhaseLinearizer( - np.ones(len(gd)), len(ir), fs_hz, gd.squeeze() - ) - pl.get_filter_as_ir() + pl = dsp.filterbanks.GroupDelayDesigner(gd.squeeze(), len(ir), fs_hz) + pl.set_parameters(200) pl.get_filter() + # ir = dsp.pad_trim(pl.get_filter_as_ir(), 2**15) + # ir.plot_time() + # ir.plot_magnitude() + # dsp.plots.show() + def test_SVFilter(self): fs_hz = 10_000 f = dsp.filterbanks.StateVariableFilter(500, np.sqrt(2), fs_hz) diff --git a/tests/test_generators.py b/tests/test_generators.py index 811790d..a14aa7d 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -73,6 +73,16 @@ def test_noise(self): padding_end_seconds=0, ) + dsp.generators.noise( + type_of_noise=-0.5, + length_seconds=2, + sampling_rate_hz=5_000, + peak_level_dbfs=-20, + number_of_channels=1, + fade="log", + padding_end_seconds=0, + ) + # Peak level over 0 dBFS with pytest.raises(AssertionError): dsp.generators.noise( diff --git a/tests/test_standard.py b/tests/test_standard.py index 2af7d1e..773ff15 100644 --- a/tests/test_standard.py +++ b/tests/test_standard.py @@ -8,6 +8,10 @@ class TestStandardModule: fs = 44100 audio_multi = dsp.generators.noise("white", 2, fs, number_of_channels=3) + def get_multiband_signal(self): + fb = dsp.filterbanks.linkwitz_riley_crossovers([1e3], [4], self.fs) + return fb.filter_signal(self.audio_multi) + def test_latency(self): # Create delayed version of signal td = self.audio_multi.time_data @@ -157,13 +161,32 @@ def test_resample(self): dsp.resample(self.audio_multi, desired_sampling_rate_hz=22050) def test_normalize(self): + # Check peak normalization td = self.audio_multi.time_data - n = dsp.normalize(self.audio_multi, peak_dbfs=-20) + n = dsp.normalize(self.audio_multi, norm_dbfs=-20) td /= np.max(np.abs(td)) factor = 10 ** (-20 / 20) td *= factor assert np.isclose(np.max(np.abs(n.time_data)), np.max(np.abs(td))) + # Check rms + channel = self.audio_multi.get_channels(0) + rms_previous = dsp.rms(channel)[0] + n = dsp.normalize(channel, norm_dbfs=rms_previous - 10, mode="rms") + rms = dsp.rms(n)[0] + assert np.isclose(rms_previous - 10, rms) + + # Check rest of api + dsp.normalize( + self.audio_multi, norm_dbfs=-20, mode="rms", each_channel=False + ) + dsp.normalize( + self.audio_multi, norm_dbfs=-20, mode="rms", each_channel=True + ) + dsp.normalize( + self.audio_multi, norm_dbfs=-20, mode="peak", each_channel=True + ) + def test_fade(self): # Functionality – result only tested for linear fade dsp.fade(self.audio_multi, type_fade="lin") @@ -350,3 +373,41 @@ def test_dither(self): ) dsp.dither(self.audio_multi, noise_shaping_filterbank=fb) dsp.dither(self.audio_multi, truncate=False) + + def test_apply_gain(self): + # Signal + audio_multi = dsp.apply_gain(self.audio_multi, 5) + np.testing.assert_array_equal( + audio_multi.time_data, + self.audio_multi.time_data * dsp.tools.from_db(5, True), + ) + + gains = np.linspace(1, 5, self.audio_multi.number_of_channels) + audio_multi = dsp.apply_gain(self.audio_multi, gains) + np.testing.assert_array_equal( + audio_multi.time_data, + self.audio_multi.time_data * dsp.tools.from_db(gains, True), + ) + + audio_multi = dsp.apply_gain(self.audio_multi, gains) + np.testing.assert_array_equal( + audio_multi.time_data, + self.audio_multi.time_data * dsp.tools.from_db(gains, True), + ) + + # MultiBandSignal + audio_multi_mb = self.get_multiband_signal() + previous = audio_multi_mb.get_all_time_data()[0] + audio_multi_mb = dsp.apply_gain(audio_multi_mb, 5) + np.testing.assert_array_equal( + previous * dsp.tools.from_db(5, True), + audio_multi_mb.get_all_time_data()[0], + ) + + previous = audio_multi_mb.get_all_time_data()[0] + gains = np.linspace(1, 5, self.audio_multi.number_of_channels) + audio_multi_mb = dsp.apply_gain(audio_multi_mb, gains) + np.testing.assert_array_equal( + previous * dsp.tools.from_db(gains, True), + audio_multi_mb.get_all_time_data()[0], + )