pyfar.signals#

This module contains functions for generating common deterministic and stochastic audio signals such as impulses, sine sweeps, and noise signals.

All signal lengths are given in samples. The value for the length is casted to an integer number in all cases. This makes it possible to pass float numbers. For example:

n_samples = .015 * sampling_rate.

Functions:

exponential_sweep_freq(n_samples, ...[, ...])

Generate sine sweep with exponentially increasing frequency in the frequency domain.

exponential_sweep_time(n_samples, ...[, ...])

Generate sine sweep with exponentially increasing frequency in the time domain.

impulse(n_samples[, delay, amplitude, ...])

Generate a single or multi channel impulse signal, also known as the Dirac delta function.

linear_perfect_sweep(n_samples[, ...])

Generate a perfect linear sweep in the frequency domain.

linear_sweep_freq(n_samples, ...[, ...])

Generate sine sweep with linearly increasing frequency in the frequency domain.

linear_sweep_time(n_samples, frequency_range)

Generate sine sweep with linearly increasing frequency in the time domain.

magnitude_spectrum_weighted_sweep(n_samples, ...)

Generate sine sweep with arbitrary magnitude spectrum in the frequency domain.

noise(n_samples[, spectrum, rms, ...])

Generate single or multi channel normally distributed white or pink noise.

pulsed_noise(n_pulse, n_pause[, n_fade, ...])

Generate single channel normally distributed pulsed white or pink noise.

sine(frequency, n_samples[, amplitude, ...])

Generate a single or multi channel sine signal.

pyfar.signals.exponential_sweep_freq(n_samples, frequency_range, start_margin, stop_margin, n_fade_in=0, n_fade_out=0, bandpass_order=8, sampling_rate=44100, return_group_delay=False)[source]#

Generate sine sweep with exponentially increasing frequency in the frequency domain.

Sweep synthesis according to [1].

The exponential sweep can also be generated in the time domain (exponential_sweep_time). Frequency domain synthesis exhibits smooth magnitude spectra at the cost of a slightly irregular temporal envelope. Time domain synthesis exhibits a constant temporal envelope at the cost of slight ripples in the magnitude response.

Note

The envelope of the sweep time signal should be constant, apart from slight overshoots at the beginning and end. If this is not the case, try to increase n_samples, start_margin, stop_margin, n_fade_in or n_fade_out.

Parameters:
  • n_samples (int) – The length of the sweep in samples.

  • frequency_range (array like) – Frequency range of the sweep given by the lower and upper cut-off frequency in Hz. The restriction of the frequency range is realized by applying a Butterworth high-pass if frequency_range[0] > 0 and/or by a low-pass if frequency_range[1] < sampling_rate / 2. Note that the exponential sweep can not start at 0 Hz, because its magnitude is defined by 1/frequency.

  • start_margin (int, float) – The time in samples, at which the sweep starts. The start margin is required because the frequency domain sweep synthesis has pre-ringing in the time domain.

  • stop_margin (int, float) – Time in samples, at which the sweep stops. This is relative to n_samples, e.g., a stop margin of 100 samples means that the sweep ends at sample n_samples-100. This is required, because the frequency domain sweep synthesis has post-ringing in the time domain.

  • n_fade_in (int, optional) – Duration of a squared sine fade-in in samples. The fade starts at the first sample of the sweep that is closer than 60 dB to the absolute maximum of the sweep time signal. The default 0 does not apply a fade-in.

  • n_fade_out (int, optional) – Duration of a squared cosine fade-out in samples. The fade ends at the last sample of the sweep that is closer than 60 dB to the absolute maximum of the sweep time signal. The default 0 does not apply a fade-out.

  • bandpass_order (int, optional) – The order of the Butterworth filters that are applied to limit the frequency range (see above). The default is 8.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • return_group_delay (boolean, optional) – Return the analytical group delay of the sweep. This can be used to compute the times at which distortion products appear. The default is False.

Returns:

  • sweep (Signal) – The sweep signal. The Signal is in the time domain, has a maximum absolute amplitude of 1 and the none FFT normalization (see normalization).

  • group_delay_sweep (FrequencyData) – The analytical group delay of the sweep in seconds as a single sided spectrum. Only returned if return_group_delay is True.

References

Examples

Exponential sweep between 50 and 22050 Hz

>>> import pyfar as pf
>>> sweep = pf.signals.exponential_sweep_freq(
...     2**16, [50, 22050], 5000, 1000)
>>> pf.plot.time_freq(sweep)

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-1.png
pyfar.signals.exponential_sweep_time(n_samples, frequency_range, n_fade_out=90, amplitude=1, sweep_rate=None, sampling_rate=44100)[source]#

Generate sine sweep with exponentially increasing frequency in the time domain.

Time domain sweep generation according to [2]:

\[s(t) = \sin(2\pi f_\mathrm{low} L \left( e^{t/L} - 1 \right))\]

with

\[L = T / \log(f_\mathrm{high}/f_\mathrm{low}),\]

\(T\) the duration in seconds, \(t\) the sampling points in seconds, and the frequency limits \(f_\mathrm{low}\) and \(f_\mathrm{high}\).

The exponential sweep can also be generated in the frequency domain (see see exponential_sweep_freq). Time domain synthesis exhibits a constant temporal envelope at the cost of slight ripples in the magnitude response. Frequency domain synthesis exhibits smooth magnitude spectra at the cost of a slightly irregular temporal envelope.

Parameters:
  • n_samples (int) – The length of the sweep in samples

  • frequency_range (array like) – Frequency range of the sweep given by the lower and upper cut-off frequency in Hz.

  • n_fade_out (int, optional) – The length of the squared cosine fade-out in samples. This is done to avoid discontinuities at the end of the sweep. The default is 90, which equals approximately 2 ms at sampling rates of 44.1 and 48 kHz.

  • amplitude (double, optional) – The amplitude of the signal. The default is 1.

  • sweep_rate (double, optional) – Rate at which the sine frequency increases over time in octaves per second. If this is given, n_samples is calculated according to the sweep_rate and frequency_range. The default is None, which uses n_samples without modifications.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

Returns:

sweep – The sweep signal. The Signal is in the time domain and has the none FFT normalization (see normalization). The sweep type, frequency range, and length of the fade our are written to comment.

Return type:

Signal

References

Examples

Exponential sweep between 50 and 22050 Hz

>>> import pyfar as pf
>>> sweep = pf.signals.exponential_sweep_time(2**16, [50, 22050])
>>> pf.plot.time_freq(sweep)

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-2.png
pyfar.signals.impulse(n_samples, delay=0, amplitude=1, sampling_rate=44100)[source]#

Generate a single or multi channel impulse signal, also known as the Dirac delta function.

\[\begin{split}s(n) = \begin{cases} \text{amplitude}, & \text{if $n$ = delay}\\ 0, & \text{else} \end{cases}\end{split}\]
Parameters:
  • n_samples (int) – Length of the impulse in samples

  • delay (double, array like, optional) – Delay in samples. The default is 0.

  • amplitude (double, array like, optional) – The peak amplitude of the impulse. The default is 1.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

Returns:

signal – The impulse signal. The Signal is in the time domain and has the none FFT normalization (see normalization). The delay and amplitude are written to comment.

Return type:

Signal

Notes

The parameters delay and amplitude are broadcasted using the numpy rules. For example delay could be of shape (2, 4), amplitude of shape (2, 1) or a scalar. In this case all parameters would be broadcasted to a shape of (2, 4).

pyfar.signals.linear_perfect_sweep(n_samples, sampling_rate=44100, return_group_delay=False)[source]#

Generate a perfect linear sweep in the frequency domain.

The perfect sweep is generated according to [3] and is used for adaptive system identification. It is orthogonal to delayed versions of itself.

Parameters:
  • n_samples (int) – The length of the sweep in samples.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • return_group_delay (boolean, optional) – Return the analytical group delay of the sweep. This can be used to compute the times at which distortion products appear. The default is False.

Returns:

  • sweep (Signal) – The sweep signal. The Signal is in the time domain, has a maximum absolute amplitude of 1 and the none FFT normalization (see normalization).

  • group_delay_sweep (FrequencyData) – The analytical group delay of the sweep in seconds as a single sided spectrum. Only returned if return_group_delay is True.

References

Examples

Plot a shifted perfect sweep to show that it can be looped

>>> import pyfar as pf
>>> sweep = pf.signals.linear_perfect_sweep(2**8)
>>> sweep_shifted = pf.dsp.time_shift(sweep, 2**7)
>>> ax = pf.plot.time_freq(sweep_shifted, unit='samples')
>>> ax[0].axvline(2**7, ls='--', c='r', label='start/end')
>>> ax[0].legend(loc=4)

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-3.png

Show that the sweep is orthogonal to all shifted version of itself. This property is important for adaptive system identification.

>>> import pyfar as pf
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>>
>>> sweep = pf.signals.linear_perfect_sweep(2**8)
>>>
>>> # compute auto-correlation
>>> auto_correlation = np.empty(2**8)
>>> for idx, shift in enumerate(range(-2**7, 2**7)):
>>>     auto_correlation[idx] = np.dot(
...         sweep.time.flatten(),
...         np.roll(sweep.time.flatten(), shift))
>>>
>>> auto_correlation /= pf.dsp.energy(sweep)
>>>
>>> # plot auto-correlation
>>> with pf.plot.context():
>>>     plt.plot(np.arange(-2**7, 2**7), auto_correlation)
>>>     plt.gca().set_xlim(-2**7, 2**7)
>>>     plt.gca().set_xlabel('time lag in samples')
>>>     plt.gca().set_ylabel('auto correlation')

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-4.png
pyfar.signals.linear_sweep_freq(n_samples, frequency_range, start_margin, stop_margin, n_fade_in=0, n_fade_out=0, bandpass_order=8, sampling_rate=44100, return_group_delay=False)[source]#

Generate sine sweep with linearly increasing frequency in the frequency domain.

Sine sweep synthesis according to [4].

The linear sweep can also be generated in the time domain (linear_sweep_time). Frequency domain synthesis exhibits smooth magnitude spectra at the cost of a slightly irregular temporal envelope. Time domain synthesis exhibits a constant temporal envelope in trade of slight ripples in the magnitude response.

Note

The envelope of the sweep time signal should be constant, apart from slight overshoots at the beginning and end. If this is not the case, try to increase n_samples, start_margin, stop_margin, n_fade_in or n_fade_out.

Parameters:
  • n_samples (int) – The length of the sweep in samples.

  • frequency_range (array like) – Frequency range of the sweep given by the lower and upper cut-off frequency in Hz. The restriction of the frequency range is realized by applying a Butterworth high-pass if frequency_range[0] > 0 and/or by a low-pass if frequency_range[1] < sampling_rate / 2.

  • start_margin (int, float) – The time in samples, at which the sweep starts. The start margin is required because the frequency domain sweep synthesis has pre-ringing in the time domain.

  • stop_margin (int, float) – Time in samples, at which the sweep stops. This is relative to n_samples, e.g., a stop margin of 100 samples means that the sweep ends at sample n_samples-100. This is required, because the frequency domain sweep synthesis has post-ringing in the time domain.

  • n_fade_in (int, optional) – Duration of a squared sine fade-in in samples. The fade starts at the first sample of the sweep that is closer than 60 dB to the absolute maximum of the sweep time signal. The default 0 does not apply a fade-in.

  • n_fade_out (int, optional) – Duration of a squared cosine fade-out in samples. The fade ends at the last sample of the sweep that is closer than 60 dB to the absolute maximum of the sweep time signal. The default 0 does not apply a fade-out.

  • bandpass_order (int, optional) – The order of the Butterworth filters that are applied to limit the frequency range (see above). The default is 8.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • return_group_delay (boolean, optional) – Return the analytical group delay of the sweep. This can be used to compute the times at which distortion products appear. The default is False.

Returns:

  • sweep (Signal) – The sweep signal. The Signal is in the time domain, has a maximum absolute amplitude of 1 and the none FFT normalization (see normalization).

  • group_delay_sweep (FrequencyData) – The analytical group delay of the sweep in seconds as a single sided spectrum. Only returned if return_group_delay is True.

References

Examples

Linear sweep between 50 and 22050 Hz

>>> import pyfar as pf
>>> sweep = pf.signals.linear_sweep_freq(
...     2**16, [50, 22050], 1000, 1000)
>>> pf.plot.time_freq(sweep)

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-5.png
pyfar.signals.linear_sweep_time(n_samples, frequency_range, n_fade_out=90, amplitude=1, sampling_rate=44100)[source]#

Generate sine sweep with linearly increasing frequency in the time domain.

Time domain sweep generation according to [5]:

\[s(t) = \sin(2\pi f_\mathrm{low} t + 2\pi (f_\mathrm{high}- f_\mathrm{low}) / T \cdot t^2 / 2),\]

with \(T\) the duration in seconds, \(t\) the sampling points in seconds, and the frequency limits \(f_\mathrm{low}\) and \(f_\mathrm{high}\).

The linear sweep can also be generated in the frequency domain (see linear_sweep_freq). Time domain synthesis exhibits a constant temporal envelope at the cost of slight ripples in the magnitude response. Frequency domain synthesis exhibits smooth magnitude spectra at the cost of a slightly irregular temporal envelope.

Parameters:
  • n_samples (int) – The length of the sweep in samples

  • frequency_range (array like) – Frequency range of the sweep given by the lower and upper cut-off frequency in Hz.

  • n_fade_out (int, optional) – The length of the squared cosine fade-out in samples. This is done to avoid discontinuities at the end of the sweep. The default is 90, which equals approximately 2 ms at sampling rates of 44.1 and 48 kHz.

  • amplitude (double, optional) – The amplitude of the signal. The default is 1.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

Returns:

sweep – The sweep signal. The Signal is in the time domain and has the none FFT normalization (see normalization). The sweep type, frequency range, and length of the fade our are written to comment.

Return type:

Signal

References

Examples

Linear sweep between 0 and 22050 Hz

>>> import pyfar as pf
>>> sweep = pf.signals.linear_sweep_time(2**16, [0, 22050])
>>> pf.plot.time_freq(sweep)

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-6.png
pyfar.signals.magnitude_spectrum_weighted_sweep(n_samples, magnitude_spectrum, start_margin, stop_margin, n_fade_in=0, n_fade_out=0, sampling_rate=44100, return_group_delay=False)[source]#

Generate sine sweep with arbitrary magnitude spectrum in the frequency domain.

Frequency domain sine sweep synthesis according to [6]. There is currently no method to design sine sweeps with arbitrary magnitude response in the time domain.

Note

The envelope of the sweep time signal should be constant, apart from slight overshoots at the beginning and end. If this is not the case, try to increase n_samples, start_margin, stop_margin, n_fade_in or n_fade_out, or provide a more smooth magnitude spectrum.

Parameters:
  • n_samples (int) – The length of the sweep in samples.

  • magnitude_spectrum (Signal) – The magnitude spectrum as a Signal object. Must be at least n_samples long and is zero-padded to n_samples otherwise.

  • start_margin (int, float) – The time in samples, at which the sweep starts. The start margin is required because the frequency domain sweep synthesis has pre-ringing in the time domain.

  • stop_margin (int, float) – Time in samples, at which the sweep stops. This is relative to n_samples, e.g., a stop margin of 100 samples means that the sweep ends at sample n_samples-100. This is required, because the frequency domain sweep synthesis has post-ringing in the time domain.

  • n_fade_in (int, optional) – Duration of a squared sine fade-in in samples. The fade starts at the first sample of the sweep that is closer than 60 dB to the absolute maximum of the sweep time signal. The default 0 does not apply a fade-in.

  • n_fade_out (int, optional) – Duration of a squared cosine fade-out in samples. The fade ends at the last sample of the sweep that is closer than 60 dB to the absolute maximum of the sweep time signal. The default 0 does not apply a fade-out.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • return_group_delay (boolean, optional) – Return the analytical group delay of the sweep. This can be used to compute the times at which distortion products appear. The default is False.

Returns:

  • sweep (Signal) – The sweep signal. The Signal is in the time domain, has a maximum absolute amplitude of 1 and the none FFT normalization (see normalization).

  • group_delay_sweep (FrequencyData) – The analytical group delay of the sweep in seconds as a single sided spectrum. Only returned if return_group_delay is True.

References

Examples

>>> import pyfar as pf
>>> magnitude = pf.dsp.filter.low_shelf(
...     pf.signals.impulse(2**16), 500, 20, 2)
>>> magnitude = pf.dsp.filter.butterworth(magnitude, 8, 50, 'highpass')
>>> sweep = pf.signals.magnitude_spectrum_weighted_sweep(
...     2**16, magnitude, 5000, 1000)
>>> pf.plot.time_freq(sweep)

(Source code, png, hires.png, pdf)

../_images/pyfar-signals-7.png
pyfar.signals.noise(n_samples, spectrum='white', rms=1, sampling_rate=44100, seed=None)[source]#

Generate single or multi channel normally distributed white or pink noise.

The pink noise is generated by applying a sqrt(1/f) filter to the spectrum.

Parameters:
  • n_samples (int) – The length of the signal in samples

  • spectrum (str, optional) – white to generate noise with constant energy across frequency. pink to generate noise with constant energy across filters with constant relative bandwidth. The default is white.

  • rms (double, array like, optional) – The root mean square (RMS) value of the noise signal. A multi channel noise signal is generated if an array of RMS values is passed. The default is 1.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • seed (int, None, optional) – The seed for the random generator. Pass a seed to obtain identical results for multiple calls. The default is None, which will yield different results with every call.

Returns:

signal – The noise signal. The signal is in the time domain and has the rms FFT normalization (see normalization). The type of the spectrum (white, pink) and the RMS amplitude are written to comment.

Return type:

Signal

pyfar.signals.pulsed_noise(n_pulse, n_pause, n_fade=90, repetitions=5, rms=1, spectrum='pink', frozen=True, sampling_rate=44100, seed=None)[source]#

Generate single channel normally distributed pulsed white or pink noise.

The pink noise is generated by applying a sqrt(1/f) filter to the spectrum.

Parameters:
  • n_pulse (int) – The length of the pulses in samples

  • n_pause (int) – The length of the pauses between the pulses in samples.

  • n_fade (int, optional) – The length of the squared sine/cosine fade-in and fade outs in samples. The default is 90, which equals approximately 2 ms at sampling rates of 44.1 and 48 kHz.

  • repetitions (int, optional) – Specifies the number of noise pulses. The default is 5.

  • rms (double, array like, optional) – The RMS amplitude of the white signal. The default is 1.

  • spectrum (string, optional) – The noise spectrum, which can be pink or white. The default is pink.

  • frozen (boolean, optional) – If True, all noise pulses are identical. If False each noise pulse is a separate stochastic process. The default is True.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • seed (int, None, optional) – The seed for the random generator. Pass a seed to obtain identical results for multiple calls. The default is None, which will yield different results with every call.

Returns:

signal – The noise signal. The Signal is in the time domain and has the rms FFT normalization (see normalization). comment contains information about the selected parameters.

Return type:

Signal

pyfar.signals.sine(frequency, n_samples, amplitude=1, phase=0, sampling_rate=44100, full_period=False)[source]#

Generate a single or multi channel sine signal.

Parameters:
  • frequency (double, array like) – Frequency of the sine in Hz (0 <= frequency <= sampling_rate/2).

  • n_samples (int) – Length of the signal in samples.

  • amplitude (double, array like, optional) – The amplitude. The default is 1.

  • phase (double, array like, optional) – The phase in radians. The default is 0.

  • sampling_rate (int, optional) – The sampling rate in Hz. The default is 44100.

  • full_period (boolean, optional) – Make sure that the returned signal contains an integer number of periods resulting in a periodic signal. This is done by adjusting the frequency of the sine. The default is False.

Returns:

signal – The sine signal. The Signal is in the time domain and has the rms FFT normalization (see normalization). The exact frequency, amplitude and phase are written to comment.

Return type:

Signal

Notes

The parameters frequency, amplitude, and phase are broadcasted using the numpy rules. For example frequency could be of shape (2, 4), amplitude of shape (2, 1), and phase could be a scalar. In this case all parameters would be broadcasted to a shape of (2, 4).