signals#
Implements signal generators for the simulation of acoustic sources.
ABC for a simple one-channel signal generator. |
|
Abstract base class for periodic signal generators. |
|
Abstract base class for noise signal generators. |
|
White noise signal generator. |
|
Generate pink noise signal. |
|
Generate filtered white noise using an AR, MA, or ARMA process. |
|
Generate a sine signal. |
|
Generate signals from a |
- class acoular.signals.SignalGenerator#
Bases:
ABCHasStrictTraitsABC for a simple one-channel signal generator.
This ABC defines the common interface and attributes for all signal generator implementations. It provides a template for generating one-channel signals with specified amplitude, sampling frequency, and duration. Subclasses should implement the core functionality, including signal generation and computation of the internal identifier.
See also
scipy.signal.resample()Used for resampling signals in the
usignal()method.
Notes
This class should not be instantiated directly. Instead, use a subclass that implements the required methods for signal generation.
- sample_freq = Float(1.0, desc='sampling frequency')#
Sampling frequency of the signal in Hz. Default is
1.0.
- num_samples = CInt#
The number of samples to generate for the signal.
- digest = Property(depends_on=['sample_freq', 'num_samples'])#
A unique checksum identifier based on the object properties. (read-only)
- abstractmethod signal()#
Generate and return the signal.
This method must be implemented by subclasses to provide the generated signal as a 1D array of samples.
- usignal(factor)#
Resample the signal at a higher sampling frequency.
This method uses Fourier transform-based resampling to deliver the signal at a sampling frequency that is a multiple of the original
sample_freq. The resampled signal has a length offactor * num_samples.- Parameters:
- factorint
The resampling factor. Defines how many times larger the new sampling frequency is compared to the original
sample_freq.
- Returns:
numpy.ndarrayThe resampled signal as a 1D array of floats.
Notes
This method relies on the
scipy.signal.resample()function for resampling.Examples
Resample a signal by a factor of 4:
>>> from acoular import SineGenerator # Class extending SignalGenerator >>> sg = SineGenerator(sample_freq=100.0, num_samples=1000) >>> resampled_signal = sg.usignal(4) >>> len(resampled_signal) 4000
- class acoular.signals.PeriodicSignalGenerator#
Bases:
SignalGeneratorAbstract base class for periodic signal generators.
The
PeriodicSignalGeneratorclass defines the common interface for allSignalGenerator-derived classes with periodic signals. This class may be used as a base for class handling periodic signals that can be characterized by their frequency, phase and amplitude.It should not be used directly as it contains no real functionality.
See also
SineGeneratorGenerate a sine signal.
- freq = Float(1000.0, desc='Frequency')#
The frequency of the signal. Default is
1000.0.
- phase = Float(0.0, desc='Phase')#
The phase of the signal (in radians). Default is
0.0.
- amplitude = Float(1.0)#
The amplitude of the signal. Default is
1.0.
- digest = Property(depends_on=['amplitude', 'num_samples', 'sample_freq', 'freq', 'phase'])#
Internal identifier based on generator properties. (read-only)
- abstractmethod signal()#
Deliver the signal.
- class acoular.signals.NoiseGenerator#
Bases:
SignalGeneratorAbstract base class for noise signal generators.
The
NoiseGeneratorclass defines the common interface for allSignalGeneratorclasses with noise signals. This class may be used as a base for class handling noise signals that can be characterized by their RMS amplitude.It should not be used directly as it contains no real functionality.
See also
PNoiseGeneratorFor pink noise generation.
WNoiseGeneratorFor pink white generation.
UncorrelatedNoiseSourceFor per-channel noise generation.
- rms = Float(1.0, desc='rms amplitude')#
Root mean square (RMS) amplitude of the signal. For a point source, this corresponds to the RMS amplitude at a distance of 1 meter. Default is
1.0.
- seed = Int(0, desc='random seed value')#
Seed for random number generator. Default is
0. This parameter should be set differently for different instances to guarantee statistically independent (non-correlated) outputs.
- digest = Property(depends_on=['rms', 'seed', 'sample_freq', 'num_samples'])#
Internal identifier based on generator properties. (read-only)
- abstractmethod signal()#
Generate and deliver the periodic signal.
- class acoular.signals.WNoiseGenerator#
Bases:
NoiseGeneratorWhite noise signal generator.
This class generates white noise signals with a specified
root mean square (RMS)amplitude,number of samples, andsampling frequency. The white noise is generated using arandom number generatorinitialized with auser-defined seedfor reproducibility.See also
numpy.random.RandomState.standard_normalUsed here to generate normally distributed noise.
PNoiseGeneratorFor pink noise generation.
UncorrelatedNoiseSourceFor per-channel noise generation.
Examples
Generate white noise with an RMS amplitude of 1.0 and 0.5:
>>> from acoular import WNoiseGenerator >>> from numpy import mean >>> >>> # White noise with RMS of 1.0 >>> gen1 = WNoiseGenerator(rms=1.0, num_samples=1000, seed=42) >>> signal1 = gen1.signal() >>> >>> # White noise with RMS of 0.5 >>> gen2 = WNoiseGenerator(rms=0.5, num_samples=1000, seed=24) >>> signal2 = gen2.signal() >>> >>> mean(signal1) > mean(signal2) np.True_
Ensure different outputs with different seeds:
>>> gen1 = WNoiseGenerator(num_samples=3, seed=42) >>> gen2 = WNoiseGenerator(num_samples=3, seed=73) >>> gen1.signal() == gen2.signal() array([False, False, False])
- signal()#
Generate and deliver the white noise signal.
The signal is created using a Gaussian distribution with mean 0 and variance 1, scaled by the
RMSamplitude of the object.- Returns:
numpy.ndarrayA 1D array of floats containing the generated white noise signal. The length of the array is equal to
num_samples.
- class acoular.signals.PNoiseGenerator#
Bases:
NoiseGeneratorGenerate pink noise signal.
The
PNoiseGeneratorclass generates pink noise signals, which exhibit a \(1/f\) power spectral density. Pink noise is characterized by equal energy per octave, making it useful in various applications such as audio testing, sound synthesis, and environmental noise simulations.The pink noise simulation is based on the Voss-McCartney algorithm, which iteratively adds noise with increasing wavelength to achieve the desired \(1/f\) characteristic.
See also
WNoiseGeneratorFor white noise generation.
UncorrelatedNoiseSourceFor per-channel noise generation.
References
S.J. Orfanidis: Signal Processing (2010), pp. 729-733 [17]
Online discussion: http://www.firstpr.com.au/dsp/pink-noise/
- depth = Int(16, desc='octave depth')#
“Octave depth” of the pink noise generation. Higher values result in a better approximation of the \(1/f\) spectrum at low frequencies but increase computation time. The maximum allowable value depends on the
number of samples. Default is16.
- digest = Property(depends_on=['rms', 'seed', 'sample_freq', 'num_samples', 'depth'])#
A unique checksum identifier based on the object properties. (read-only)
- signal()#
Generate and deliver the pink noise signal.
The signal is computed using the Voss-McCartney algorithm, which generates noise with a \(1/f\) power spectral density. The method ensures that the output has the desired
RMSamplitude and spectrum.- Returns:
numpy.ndarrayA 1D array of floats containing the generated pink noise signal. The length of the array is equal to
num_samples.
Notes
The “depth” parameter controls the number of octaves included in the pink noise simulation. If the specified depth exceeds the maximum possible value based on the number of samples, it is automatically adjusted, and a warning is printed.
The output signal is scaled to have the same overall level as white noise by dividing the result by
np.sqrt(depth + 1.5).
- class acoular.signals.FiltWNoiseGenerator#
Bases:
WNoiseGeneratorGenerate filtered white noise using an AR, MA, or ARMA process.
This class extends the
WNoiseGeneratorclass to apply a digital filter to white noise, producing a signal with specific characteristics based on the provided filter coefficients. The desired filter is defined using the autoregressive coefficients (ar) and moving-average coefficients (ma).The filter is implemented as a series of second-order sections (sos) for numerical stability, especially at high filter orders.
See also
WNoiseGeneratorFor white noise generation.
Notes
The output signal is adjusted for the group delay introduced by the filter, ensuring proper alignment of the filtered signal.
The RMS value specified in the
rmsattribute corresponds to the original white noise signal and not the filtered output.
Examples
Generate filtered white noise using
ARandMAcoefficients:>>> import acoular as ac >>> import numpy as np >>> >>> # Define AR and MA coefficients >>> ar = np.array([1.0, -0.5]) >>> ma = np.array([0.5, 0.5]) >>> >>> # Create generator >>> gen = ac.FiltWNoiseGenerator( ... rms=1.0, ... seed=42, ... sample_freq=1000, ... num_samples=10000, ... ar=ar, ... ma=ma, ... ) >>> >>> # Generate signal >>> signal = gen.signal() >>> print(signal[:10]) # Print the first 10 samples [0.24835708 0.30340346 0.40641385 1.28856612 1.2887213 0.41021549 0.87764567 1.61214661 0.95505348 0.51406957]
- ar = CArray(value=np.array([]), dtype=float, desc='autoregressive coefficients (coefficients of the denominator)')#
A
numpy.ndarrayof autoregressive coefficients (denominator). Default is[], which results in no AR filtering (i.e., all-pole filter is[1.0]).
- ma = CArray(value=np.array([]), dtype=float, desc='moving-average coefficients (coefficients of the numerator)')#
A
numpy.ndarrayof moving-average coefficients (numerator). Default is[], which results in no MA filtering (i.e., all-zero filter is[1.0]).
- digest = Property(depends_on=['rms', 'seed', 'sample_freq', 'num_samples', 'ar', 'ma'])#
A unique checksum identifier based on the object properties. (read-only)
- handle_empty_coefficients(coefficients)#
Handle empty filter coefficient arrays by returning a default value.
This method ensures that both the autoregressive (
ar) and moving-average (ma) coefficients are non-empty before filtering. If a coefficient array is empty, it is replaced with a default array containing a single value of1.0.- Parameters:
- coefficients
numpy.ndarray Array of filter coefficients to check.
- coefficients
- Returns:
numpy.ndarrayThe original array if it is non-empty, or a default array containing
[1.0]if the input array is empty.
- signal()#
Generate and return the filtered white noise signal.
This method creates a white noise signal with the specified
RMS valueandseed, then filters it using the autoregressive (ar) and moving-average (ma) coefficients. The filtering process compensates for group delay introduced by the filter.- Returns:
numpy.ndarrayoffloatsAn array representing the filtered white noise signal. The length of the returned array is equal to
the number of samples.
- class acoular.signals.SineGenerator#
Bases:
PeriodicSignalGeneratorGenerate a sine signal.
The
SineGeneratorclass extends thePeriodicSignalGeneratorclass and generates a sinusoidal signal based on specifiedamplitude,frequency, andphase.This generator is commonly used for creating test signals in signal processing, acoustics, and control systems.
The signal is defined as
\[s(t) = A \sin(2 \pi f t + \phi)\]- where:
\(A\) is the amplitude,
\(f\) is the frequency,
\(\phi\) is the phase,
\(t\) is the time (computed from the
sampling frequencyand thenumber of samples).
See also
PeriodicSignalGeneratorBase class for periodic signal generators.
Examples
Generate a sine wave signal:
>>> import acoular as ac >>> >>> gen = ac.SineGenerator( ... amplitude=2.0, ... freq=50.0, ... phase=0.0, ... num_samples=1000, ... sample_freq=1000, ... ) >>> signal = gen.signal() >>> signal[:5] # The first 5 samples array([0. , 0.61803399, 1.1755705 , 1.61803399, 1.90211303])
Generate a sine wave with a phase shift (arguably a cosine wave):
>>> import numpy as np >>> >>> gen = ac.SineGenerator( ... amplitude=1.0, ... freq=100.0, ... phase=np.pi / 2, ... num_samples=500, ... sample_freq=2000, ... ) >>> signal = gen.signal() >>> signal[:5] # The first 5 samples array([1. , 0.95105652, 0.80901699, 0.58778525, 0.30901699])
- digest = Property(depends_on=['num_samples', 'sample_freq', 'amplitude', 'freq', 'phase'])#
A unique checksum identifier based on the object properties. (read-only)
- signal()#
Generate and return the sine wave signal.
The method computes the sine wave based on the specified
amplitude,frequency, andphase. The time values are determined by thesampling frequencyand thenumber of samples.- Returns:
numpy.ndarrayoffloatsA 1D array representing the sine wave signal. The length of the array is equal to
num_samples.
Notes
The generator supports high-frequency and high-resolution signals, limited by the Nyquist criterion.
- class acoular.signals.GenericSignalGenerator#
Bases:
SignalGeneratorGenerate signals from a
SamplesGeneratoror derived object.The
GenericSignalGeneratorclass enables the integration of arbitrary signals into Acoular processing chains. The signal is fetched from a specified data source and optionally scaled by an amplitude factor. It supports looping the signal to match the desired number of samples and can handle signals with multiple channels (only the first channel is used).- Common use cases include:
Injecting custom or pre-recorded signals from HDF5 files.
Creating signals using the
TimeSamplesclass.Generating a continuous or repeated signal for simulations.
Notes
If the signal source has more than one channel, only channel 0 is used.
Examples
Inject a random signal into a processing chain:
>>> import acoular as ac >>> import numpy as np >>> >>> data = np.random.rand(1000, 1) >>> ts = ac.TimeSamples(data=data, sample_freq=51200) >>> sig = ac.GenericSignalGenerator(source=ts) >>> output_signal = sig.signal()
- source = Instance(SamplesGenerator)#
The data source from which the signal is fetched. This can be any object derived from
SamplesGenerator.
- amplitude = Float(1.0)#
Scaling factor applied to the generated signal. Defaults to
1.0.
- sample_freq = Delegate('source')#
Sampling frequency of the output signal, as provided by the
sourceobject.
- num_samples = Property()#
The number of samples to generate. Default is the number of samples available in the
source(source.num_samples). If set explicitly, it can exceed the source length, in which case the signal will loop ifloop_signalisTrue.
- loop_signal = Bool(True)#
If
True(default), the signal is repeated to meet the requestednum_samples. IfFalse, the signal stops once the source data is exhausted.
- digest = Property( …#
A unique checksum identifier based on the object properties. (read-only)
- signal()#
Deliver the signal from the specified source.
- Returns:
numpy.arrayoffloatsThe resulting signal, scaled by the
amplitudeattribute, with a length matchingnum_samples.
Warning
A warning is raised if the source has more than one channel.