Transfer functions (dsptoolbox.transfer_functions)¶
Transfer functions¶
In this module there are functions used to obtain, modify or analyze transfer functions (TF)/impulse responses (IR).
Acquire TF/IR from signals:
spectral_deconvolve() (direct deconvolution)
compute_transfer_function() (using welch’s method for estimating auto- and cross correlation spectra from measurements of stochastic signals)
Modify TF/IR:
window_ir() (Windows a TF in time domain)
apply_tukey_like_window() (Windows a TF in time domain)
min_phase_ir() (returns a minimum-phase version of the IR)
combine_ir_with_dirac() (combines an IR with a time-aligned dirac impulse)
average_irs() (averages all channels into a single IR)
trim_ir() (trims the IR pruning it from noise samples before and after the impulse)
Generate TF/IR from magnitude spectrum:
min_phase_from_mag() (generate an IR with minimum phase from a magnitude spectrum using the distcrete hilbert transform)
lin_phase_from_mag() (generate an IR with linear phase from a magnitude spectrum)
Analyze TF/IR:
group_delay()
minimum_group_delay()
excess_group_delay()
minimum_phase()
window_frequency_dependent() (obtain a spectrum with a frequency-dependent window)
find_ir_latency()
harmonics_from_chirp_ir()
harmonic_distortion_analysis()
complex_smoothing()
- class dsptoolbox.transfer_functions.SmoothingDomain(*values)¶
Bases:
EnumThese are the different domains to realize smoothing:
RealImaginary: smoothing directly on spectrum (real and imaginary).
PowerPhase: Smoothing on power and phase separately.
MagnitudePhase: Smoothing on magnitude and phase separately.
Power: smoothing on power response, phase response is maintained.
Magnitude: smoothing on magnitude response, phase response is maintained.
EquivalentComplex: smoothing on power response, phase is obtained from the smoothed RealImaginary variant. This is the scheme proposed as equivalent complex smoothing by [1].
References
[1]: GENERALIZED FRACTIONAL OCTAVE SMOOTHING OF AUDIO / ACOUSTIC RESPONSES. PANAGIOTIS D. HATZIANTONIOU AND JOHN N. MOURJOPOULOS.
- EquivalentComplex = 6¶
- Magnitude = 5¶
- MagnitudePhase = 3¶
- Power = 4¶
- PowerPhase = 2¶
- RealImaginary = 1¶
- class dsptoolbox.transfer_functions.TransferFunctionType(*values)¶
Bases:
EnumTypes of transfer functions for stochastic signals:
H1: for noise in the output signal. Gxy/Gxx.
H2: for noise in the input signal. Gyy/Gyx.
H3: for noise in both signals. G_xy / abs(G_xy) * (G_yy/G_xx)**0.5.
- H1 = 1¶
- H2 = 2¶
- H3 = 3¶
- dsptoolbox.transfer_functions.average_irs(signal: ImpulseResponse, time_average: bool = True, normalize_energy: bool = True) ImpulseResponse¶
Averages all channels of a given IR. It can either use a time domain average while time-aligning all channels to the one with the longest latency, or average directly their magnitude and phase responses.
- Parameters:
- signalImpulseResponse
Signal with channels to be averaged over.
- time_averagebool, optional
When True, the IRs are time-aligned to the channel with the largest (minimum-phase) latency and then averaged in the time domain. False averages directly the magnitude and phase of each IR. Default: True.
- normalize_energybool, optional
When True, the energy of all spectra is normalized to the first channel’s energy and then averaged. Beware that normalization factors might be clipped if the impulses are already at or close to 0 dBFS. Default: True.
- Returns:
- avg_sigImpulseResponse
Averaged impulse response.
- dsptoolbox.transfer_functions.combine_ir_with_dirac(ir: ImpulseResponse, crossover_frequency: float, take_lower_band: bool, order: int = 8, normalization: str | float | None = None) ImpulseResponse¶
Combine an IR with a perfect impulse at a given crossover frequency using a linkwitz-riley crossover. Forward-Backward filtering is done so that no phase distortion occurs. They can optionally be energy matched using RMS or peak value.
- Parameters:
- irdsp.Signal
Impulse Response.
- crossover_frequencyfloat
Frequency at which to combine the impulse response with the perfect impulse.
- take_lower_bandbool
When True, the part below the crossover frequency corresponds to the passed impulse response and above corresponds to the perfect impulse. False delivers the opposite result.
- orderint, optional
Crossover order. Default: 8.
- normalizationstr, float, optional
‘energy’ means that the band of the perfect dirac impulse is normalized so that it matches the energy contained in the band of the impulse response. ‘peak’ means that peak value is matched for both bands. None avoids any normalization (Impulse response is always normalized prior to computation). Alternatively, a value in dB can be passed in order to scale the dirac part of the resulting impulse. Default: None.
- Returns:
- combined_irdsp.Signal
New IR.
Notes
The algorithm checks for the fractional delay of the IR and adds a fractional delayed dirac. For ensuring good results, it is recommended that the IR has some delay, so that the first part of the added dirac impulse has time to grow smoothly.
- dsptoolbox.transfer_functions.complex_smoothing(ir: ImpulseResponse, octave_fraction: float, smoothing_domain: SmoothingDomain, window: Window = Window.Hann) Spectrum¶
Complex smoothing of an impulse response using logarithmic spacing given in octaves. This is done according to [1].
- Parameters:
- irImpulseResponse
Impulse response to apply smoothing to.
- octave_fractionfloat
Width of smoothing range in fraction of octaves.
- smoothing_domainSmoothingDomain
Domain to use during the smoothing step.
- windowWindow
Type of window to use.
- Returns:
- Spectrum
References
[1]: GENERALIZED FRACTIONAL OCTAVE SMOOTHING OF AUDIO / ACOUSTIC RESPONSES. PANAGIOTIS D. HATZIANTONIOU AND JOHN N. MOURJOPOULOS.
- dsptoolbox.transfer_functions.compute_transfer_function(output: Signal, input: Signal, window_length_samples: int, mode: TransferFunctionType = TransferFunctionType.H2) Spectrum¶
Gets transfer function H1, H2 or H3 (for stochastic signals). If the input signal only has one channel, it is assumed to be the input for all of the channels of the output.
The spectrum parameters for the input will be used for the computation.
- Parameters:
- outputSignal
Signal with output channels.
- inputSignal
Signal with input channels.
- window_length_samplesint
Window length for the IR. Spectrum has the length.
- modeTransferFunction, optional
Type of transfer function. Default: H2.
- Returns:
- specSpectrum
Transfer functions as Spectrum. Coherences are also computed and saved as coherence attribute.
Notes
SNR can be gained from the coherence: snr = coherence / (1 - coherence)
- dsptoolbox.transfer_functions.excess_group_delay(signal: ImpulseResponse, smoothing: int = 0, remove_ir_latency: bool = False, analytic_computation: bool = False) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]¶
Computes excess group delay of an IR.
- Parameters:
- signalImpulseResponse
IR for which to compute minimal group delay.
- smoothingint, optional
Octave fraction by which to apply smoothing. 0 avoids any smoothing of the group delay. Default: 0.
- remove_ir_latencybool, optional
When True, the impulse delay will be removed by checking the peak latency. Default: False.
- analytic_computationbool, optional
When True, the analytic computation of group delay is performed instead of the numerical one. This is significantly slower. Default: False.
- Returns:
- fNDArray[np.float64]
Frequency vector.
- ex_gdNDArray[np.float64]
Excess group delays in seconds with shape (excess_gd, channel).
References
https://www.roomeqwizard.com/help/help_en-GB/html/minimumphase.html
No zero-padding is performed when computing the minimum-phase equivalent
- dsptoolbox.transfer_functions.filter_to_ir(fir: Filter | FilterBank) ImpulseResponse¶
Takes in an FIR filter or multiple filters in a filter bank and converts them into an IR by taking its b coefficients.
- Parameters:
- firFilter or FilterBank
Filter containing an FIR filter. In case of a FilterBank, all filters should be FIR.
- Returns:
- new_sigImpulseResponse
New IR. If the input was a FilterBank, the ImpulseResponse has multiple channels. Its length always corresponds to the longest filter.
- dsptoolbox.transfer_functions.find_ir_latency(ir: ImpulseResponse, compare_to_min_phase_ir: bool = True) ndarray[tuple[Any, ...], dtype[float64]]¶
Find the subsample maximum of each channel of the IR.
- Parameters:
- irImpulseResponse
Impulse response to find the maximum.
- compare_to_min_phase_irbool, optional
When True, the latency is found by comparing the latency of the IR in relation to its minimum phase equivalent. When False, the peak in the time data is searched. Both cases are done with subsample accuracy. For the former, the padding factor 8 is used. Default: True.
- Returns:
- latency_samplesNDArray[np.float64]
Array with the position of each channel’s latency in samples.
- dsptoolbox.transfer_functions.group_delay(signal: Signal, analytic_computation: bool = True, smoothing: int = 0, remove_ir_latency: bool = False) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]¶
Computes and returns group delay.
- Parameters:
- signalSignal
Signal for which to compute group delay.
- analytic_computationbool, optional
When True, this implementation is used: https://www.dsprelated.com/freebooks/filters/Phase_Group_Delay.html. Otherwise, the numerical gradient of the unwrapped phase response is used. Default: True.
- smoothingint, optional
Octave fraction by which to apply smoothing. 0 avoids any smoothing of the group delay. Default: 0.
- remove_ir_latencybool, optional
If the signal is of type “ir” or “rir”, the impulse delay can be removed by analyzing the minimum phase equivalent. This uses the padding factor 8 by default. Default: False.
- Returns:
- freqsNDArray[np.float64]
Frequency vector in Hz.
- group_delaysNDArray[np.float64]
Matrix containing group delays in seconds with shape (gd, channel).
- dsptoolbox.transfer_functions.harmonic_distortion_analysis(ir: ImpulseResponse | list[ImpulseResponse], chirp_range_hz: list | None = None, chirp_length_s: float | None = None, n_harmonics: int | None = 8, smoothing: int = 12, generate_plot: bool = True) dict¶
Analyze non-linear distortion coming from an IR measured with an exponential chirp. The range of the chirp and its length must be known. The distortion spectra of each harmonic, as well as THD+N and THD, are returned. Optionally, a plot can be generated.
- Parameters:
- irImpulseResponse or list[ImpulseResponse]
Impulse response. It should only have one channel. Alternatively, a list containing the fundamental IR and all harmonics can be passed, in which case chirp_range_hz, chirp_length_s and n_harmonics will be ignored or inferred. In the second case, no windowing or trimming will be applied to either the fundamental or the harmonics.
- chirp_range_hzlist
List with length 2 containing the lowest and highest frequency of the exponential chirp.
- chirp_length_sfloat
Length of the chirp (time from lowest to highest frequency) in seconds.
- n_harmonicsint, optional
Number of harmonics to analyze. Default: 8.
- smoothingint, optional
Smoothing as fraction of an octave band to apply to all spectra. Default: 12.
- generate_plotbool, optional
When True, a plot with all the distortion spectra is generated. Default: True.
- Returns:
- dict
A dictionary containing each spectrum is returned. Each item is of type Spectrum. Its keys are:
“1”: spectrum of the fundamental.
“2”: spectrum of the second harmonic.
“3”: …
“thd”: Total harmonic distortion. The spectrum is shifted to the frequency that caused the distortion.
“thd_percent”: Total harmonic distortion normalized by the linear response. It is shifted as thd and returned in percent.
“thd_n”: Total harmonic distortion + noise. This spectrum is not shifted to the frequency that caused the distortion.
“plot”: a list with matplotlib’s [figure, axes]. This is only returned if the plot was generated.
Notes
The scaling of the spectrum is always done as set with set_spectrum_parameters() of the original IR.
THD in percent is usually defined in audio by the amplitude ratios instead of the power ratios, as is common for other fields. See https://de.wikipedia.org/wiki/Total_Harmonic_Distortion.
Passing chirp_range_hz with a list of IRs will still have an effect on the upper limit frequency of each harmonic.
- dsptoolbox.transfer_functions.harmonics_from_chirp_ir(ir: ImpulseResponse, chirp_range_hz: list, chirp_length_s: float, n_harmonics: int = 5, offset_percentage: float = 0.05) list[ImpulseResponse]¶
Get the individual harmonics (distortion) IRs of an IR computed with an exponential chirp.
- Parameters:
- irImpulseResponse
Impulse response obtained through deconvolution with an exponential chirp.
- chirp_range_hzlist of length 2
The frequency range of the chirp.
- chirp_length_sfloat
Length of chirp in seconds (without zero-padding).
- n_harmonicsint, optional
Number of harmonics to analyze. Default: 5.
- offset_percentagefloat, optional
When this is larger than zero, each IR will also contain some samples prior to the impulse. Their amount corresponds to a percentage of the time length between that harmonic and their adjacent ones. All samples are gathered in a mutually exclusive manner, such they are never passed to two different harmonics. Default: 0.05.
- Returns:
- harmonicslist[ImpulseResponse]
List containing the IRs of each harmonic in ascending order. The fundamental is not in the list.
Notes
This will only work if the IR was gained utilizing an exponential chirp that has also been zero padded during the deconvolution. This will not be checked in this function.
- dsptoolbox.transfer_functions.ir_to_filter(signal: ImpulseResponse, channel: int | None = 0, phase_mode: str = 'direct') Filter | FilterBank¶
This function takes in an impulse response and turns the selected channel into an FIR filter. With phase_mode it is possible to use minimum phase or minimum linear phase.
- Parameters:
- signalSignal
Signal to be converted into a filter.
- channelint, optional
Channel of the signal to be used. If None, all channels are used and the return is a FilterBank with each channel as an FIR filter. This also applies for a signal with a single channel. Default: 0.
- phase_mode{“direct”, “min”, “lin”} str, optional
Phase of the FIR filter. Choose from “direct” (no changes to phase), “min” (minimum phase) or “lin” (minimum linear phase). Default: “direct”.
- Returns:
- filtFilter or FilterBank
(FIR) Filter from a single channel or FilterBank with FIR filters from each channel.
- dsptoolbox.transfer_functions.lin_phase_from_mag(spectrum: Spectrum, sampling_rate_hz: int, group_delay_ms: float | None = None, check_causality: bool = True, minimum_group_delay_factor: float = 1.0) ImpulseResponse¶
Returns a linear phase signal from a magnitude spectrum. It is possible to return the smallest causal group delay by checking the minimum phase version of the signal and choosing a constant group delay that is never lower than minimum group delay (for each channel). A value for the group delay can be also passed directly and applied to all channels. If check causility is activated, it is assessed that the given group delay is not less than each minimum group delay. If deactivated, the generated phase could lead to a non-causal system!
- Parameters:
- spectrumSpectrum
Spectrum with only positive frequencies and 0.
- sampling_rate_hzint
Sampling rate in Hz for the output impulse response.
- group_delay_msfloat, None, optional
Constant group delay that the phase should have for all channels (in ms). Pass None to create a signal with the minimum linear phase possible by regarding the minimum-phase response (it is different for each channel). Default: None.
- check_causalitybool, optional
When True, it is assessed for each channel that the given group delay is not lower than the minimum group delay. Default: True.
- minimum_group_delay_factorfloat, optional
When computing from the group delay from the minimum group delay, the magnitude response can be distorted for low frequencies. Increase this factor to add delay and correct this distortion. Default: 1.
- Returns:
- ImpulseResponse
Impulse response with same magnitude spectrum but linear phase. Its length is always twice the delay.
- dsptoolbox.transfer_functions.min_phase_from_mag(spectrum: Spectrum, sampling_rate_hz: int, ir_length_samples: int | None = None) ImpulseResponse¶
Returns a minimum-phase signal from a magnitude spectrum using the discrete hilbert transform.
- Parameters:
- spectrumSpectrum
Spectrum with only positive frequencies.
- sampling_rate_hzint
Sampling rate in Hz for output impulse response.
- ir_length_samplesint, None, optional
Pass to define the frequency resolution during computation and the final length of the impulse response. Pass None to use some estimate which might suffice for most cases. Default: None.
- Returns:
- ImpulseResponse
Signal with same magnitude spectrum but minimum phase.
References
- dsptoolbox.transfer_functions.min_phase_ir(sig: ImpulseResponse, use_real_cepstrum: bool = True, padding_factor: int = 8, alpha: float = 1.0) ImpulseResponse¶
Returns same IR with minimum phase. Two methods are available for computing the minimum phase version of the IR: ‘real cepstrum’ (using filtering the real-cepstral domain) and ‘equiripple’ (for symmetric IR, uses scipy.signal.minimum_phase).
- Parameters:
- sigImpulseResponse
IR for which to compute minimum phase IR.
- use_real_cepstrumbool, optional
Set to True for general cases. If the IR is symmetric (like a linear-phase filter), False is recommended. Default: True.
- padding_factorint, optional
Zero-padding to a length corresponding to current_length * padding_factor can be done, in order to avoid time aliasing errors. Default: 8.
- alphafloat, optional
This value can be used to premultiply the IR with alpha**n, where n is the index of the time sample. This is done such that the zeroes of the transfer function are pushed towards the origin of the z-plane, thus ensuring minimum phase outputs. This value should be very close to 1. Useful values are around 1-1e-4 and 1-1e-8. See [1] and [2] for details. Default: 1. (No scaling is used).
- Returns:
- ImpulseResponse
Minimum-phase IR as time signal.
References
[1]: Adrian D. Smith, Robert J. Ferguson. Minimum-phase signal calculation using the real cepstrum.
[2]: Soo-Chang Pei, Huei-Shan Lin. MINIMUM-PHASE FIR FILTER DESIGN USING REAL CEPSTRUM.
- dsptoolbox.transfer_functions.minimum_group_delay(signal: ImpulseResponse, smoothing: int = 0, padding_factor: int = 8) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]¶
Computes minimum group delay of given IR using the real cepstrum method.
- Parameters:
- signalImpulseResponse
IR for which to compute minimal group delay.
- smoothingint, optional
Octave fraction by which to apply smoothing. 0 avoids any smoothing of the group delay. Default: 0.
- padding_factorint, optional
Zero-padding to a length corresponding to at least current_length * padding_factor can be done in order to avoid time aliasing errors. Default: 8.
- Returns:
- fNDArray[np.float64]
Frequency vector.
- min_gdNDArray[np.float64]
Minimum group delays in seconds as matrix with shape (gd, channel).
References
- dsptoolbox.transfer_functions.minimum_phase(signal: ImpulseResponse, use_real_cepstrum: bool = True, padding_factor: int = 8) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]¶
Gives back a matrix containing the minimum phase signal for each channel. Two methods are available for computing the minimum phase of a system: ‘real cepstrum’ (windowing in the cepstral domain) or ‘equiripple’ (for symmetric IR’s, uses scipy.signal.minimum_phase).
- Parameters:
- signalSignal
IR for which to compute the minimum phase.
- use_real_cepstrumbool, optional
Set to True for general cases. If the IR is symmetric (like a linear-phase filter), False is recommended. Default: True.
- padding_factorint, optional
Zero-padding to a length corresponding to at least current_length * padding_factor can be done in order to avoid time aliasing errors. Default: 8.
- Returns:
- fNDArray[np.float64]
Frequency vector.
- min_phasesNDArray[np.float64]
Minimum phases as matrix with shape (phase, channel).
- dsptoolbox.transfer_functions.spectral_deconvolve(output: Signal, input: Signal, apply_regularization: bool = True, start_stop_hz=None, threshold_db: float = -30.0, padding: bool = False, keep_original_length: bool = False) ImpulseResponse¶
Deconvolution by spectral division of two signals. If the denominator signal only has one channel, the deconvolution is done using that channel for all channels of the numerator.
- Parameters:
- outputSignal
Numerator during deconvolution. It corresponds to the output in the measurement of a linear system.
- inputSignal
Denominator during deconvolution. This corresponds to the input in a linear system measurement.
- apply_regularizationbool, optional
When True, a regularization window is applied for avoiding noise outside the excitation frequency region. Default: True.
- start_stop_hzarray-like or None, optional
This is a vector of length 2 or 4 with frequency values that define the frequency region of the input (denominator) that has some energy during the deconvolution, i.e., this is the regularization range. If length is 2, the outer bounds are computed with half an octave distance. Pass None to use an automatic mode that recognizes the start and stop of the denominator (it assumes a pink-like spectrum). Default: None.
- threshold_dbfloat, optional
Threshold in dBFS for the automatic creation of the frequency window for the regularization during deconvolution. Default: -30.
- paddingbool, optional
Pads the time data with 2 length. Done for separating distortion in negative time bins when deconvolving sweep measurements. Default: False.
- keep_original_lengthbool, optional
Only regarded when padding is True. It trims the newly deconvolved data to its original length. Default: False.
- Returns:
- new_sigSignal
Deconvolved signal.
Notes
The deconvolution delivers an impulse response for the linear system that is not constrained in amplitude since some linear systems might amplify an input significantly and the true peak value should be preserved. This is also highly dependent on the phase response.
- dsptoolbox.transfer_functions.trim_ir(ir: ImpulseResponse, channel: int | None = None, start_offset_s: float | None = 0.02) tuple[ImpulseResponse, int, int]¶
Trim an IR in the beginning and end. This method acts only on one channel and returns it trimmed. For defining the ending, a smooth envelope of the energy time curve (ETC) is used, as well as the assumption that the energy should decay monotonically after the impulse arrives. See notes for details.
- Parameters:
- irImpulseResponse
Impulse response to trim.
- channelint, None, optional
Channel to take from rir. Pass None to apply to all channels and return a multichannel signal that has the largest time boundaries found across all channels. Default: None.
- start_offset_sfloat, None, optional
This is the time prior to the peak value that is left after trimming. Pass 0 to start the IR one sample prior to peak value or a very big offset (or None) to avoid any trimming at the beginning. Default: 20e-3 (20 milliseconds).
- Returns:
- trimmed_irImpulseResponse
IR with the new length.
- startint
Start index of the trimmed IR in the original vector.
- stopint
Stop index of the trimmed IR in the original vector.
Notes
- The method employed for finding the ending of the IR works as follows:
A (hilbert) envelope is computed in dB (energy time curve). This is smoothed by exponential averaging with 20 ms.
Non-overlapping windows with lengths 10, 30, 50 and 80 ms are checked starting from the impulse and going forwards. The first window to contain more energy than the previous one is regarded as the end of the IR.
Pearson correlation coefficients (cc) of the energy decay for the segments obtained with each window size are computed. The final end point is selected following criteria:
If a good linear fit is obtained (cc < -0.95), it is used as the final point.
Else, if there are acceptable fits (cc < -0.9), the ending point is the averaged from these.
Else, if there are any fits with cc < -0.7, they are all averaged but the best one is weighted significantly stronger.
If no fit has cc < -0.7, all are averaged together with the total length of the IR weighted stronger than the other values.
- dsptoolbox.transfer_functions.window_centered_ir(signal: ImpulseResponse, total_length_samples: int, window_type: Window = Window.Hann) tuple[ImpulseResponse, ndarray[tuple[Any, ...], dtype[_ScalarT]]]¶
This function windows an IR placing its peak in the middle. It trims it to the total length of the window or pads it to the desired length (padding in the end, window has total_length).
- Parameters:
- signal: `ImpulseResponse`
Signal to window
- total_length_samples: int
Total window length in samples.
- window_type: Window, optional
Window function to be used. Default: Hann.
- Returns:
- new_sigImpulseResponse
Windowed signal. The used window is also saved under new_sig.window.
- start_positions_samplesNDArray
This array contains the position index of the start of the IR in each channel of the original IR.
Notes
If the window seems truncated, it is because the length and peak position were longer than the IR, so that it had to be zero-padded to match the given length.
- dsptoolbox.transfer_functions.window_frequency_dependent(ir: ImpulseResponse, cycles: int, end_window_value_db: float = -50.0) Spectrum¶
A spectrum with frequency-dependent windowing defined by cycles is returned. To this end, a variable gaussian window is applied.
A width of 5 cycles means that there are 5 periods of each frequency before the window values hit end_window_value_db.
The output spectrum can be converted to a time series with a IRFFT. Its frequency vector has linear resolution.
- Parameters:
- irImpulseResponse
Impulse response from which to extract the spectrum.
- cyclesint
Number of cycles to include for each frequency bin. It defines the window lengths.
- end_window_value_dbfloat, optional
This is the value that the gaussian window should have at its given width in dB. It must be below 0 dB. Default: -50.
- Returns:
- Spectrum
Complex spectrum.
Notes
It is recommended that the impulse response has been already left- and right-windowed using, for instance, a tukey window. However, its length should be somewhat larger than the longest window (this depends on the number of cycles and lowest frequency).
The length of the IR should be as short as possible for a fast computation. This implementation will use numba, if available, for parallelizing the computation.
The implemented method is a straight-forward windowing in the time domain for each respective frequency bin. Warping the IR is another valid approach, but its frequency resolution will not be linear.
- dsptoolbox.transfer_functions.window_ir(signal: ImpulseResponse, total_length_samples: int, adaptive: bool = True, constant_percentage: float = 0.75, window_type: Window | list[Window] = Window.Hann, at_start: bool = True, offset_samples: int = 0, left_to_right_flank_length_ratio: float = 1.0) tuple[ImpulseResponse, ndarray[tuple[Any, ...], dtype[_ScalarT]]]¶
Windows an IR with trimming and selection of constant valued length. This is equivalent to a tukey window whose flanks can be selected to be any type. The peak of the impulse response is aligned to correspond to the first value with amplitude 1 of the window.
BEWARE: This function moves the starting point for each channel, thus losing timing information between channels.
- Parameters:
- signalImpulseResponse
Signal to window
- total_length_samplesint
Total window length in samples.
- adaptivebool, optional
When True, some design parameters will modified in case that the IR does not have enough samples to accomodate them. See Notes for more details. Default: True.
- constant_percentagefloat, optional
Percentage (between 0 and 1) of the window’s length that should be constant value. Default: 0.75.
- window_typeWindow, list[Window], optional
Window function to be used for the flanks. Pass a list containing two windows to use different windows for the left and right flanks respectively. Default: Hann.
- at_startbool, optional
Windows the start with a rising window as well as the end. Default: True.
- offset_samplesint, optional
Passing an offset in samples delays the impulse w.r.t. the first window value with amplitude 1. The offset must be inside the constant region of the window. Default: 0.
- left_to_right_flank_length_ratiofloat, optional
This is the length ratio between left and right flanks. For instance, 2 leads to a length of the left flank twice as long as the right one, while 0.1 would be a tenth of the length. Default: 1 (equal length).
- Returns:
- new_sigImpulseResponse
Windowed signal. The used window is also saved under new_sig.window.
- start_positions_samplesNDArray
This array contains the position index of the start of the IR in each channel of the original IR (relative to the possibly padded windowed IR).
Notes
- With adaptive=True, following modifications are allowed:
Left flank length is variable to fit the first part of the IR. The offset is always maintained.
Constant amplitude part of the window is modified in order to fit the right flank into the IR. If the IR is too short, there might be only a couple samples with constant amplitude.
With adaptive=False, the desired window might not fit the given IR. In that case, the window values that will be multiplied with zero-padded parts of the window are set to 0 in order to make them visible.
- dsptoolbox.transfer_functions.window_ir_tukey(ir: ImpulseResponse, left_flank_s: float | None, right_flank_s: float | None, window_flank_type: Window = Window.Hann) ImpulseResponse¶
This function applies a Tukey-like window to all channels of an ImpulseResponse. This preserves timing information across channels in contrast to window_ir.
- Parameters:
- irImpulseResponse
Impulse response to apply window to.
- left_flank_sfloat, None
Duration of the left flank of the windw in seconds. Pass None to avoid applying a window to the left flank altogether.
- right_flank_sfloat, None
Duration of the right flank of the windw in seconds. Pass None to avoid applying a window to the right flank altogether.
- window_flank_typeWindow, optional
Window type to compute the flanks from. See Notes for details. Default: Hann.
- Returns:
- ImpulseResponse
New impulse response with applied window.
Notes
The usual Tukey window applies flanks that correspond to a Hann window. This function offers the possibility of applying any type of from the supported Window types.