The audiomath.Signal
sub-module
This semi-independent submodule provides various basic
signal-processing tools that can be used with or without
the audiomath.Sound
container.
- audiomath.Signal.ApplyWindow(s, func=<function hanning>, axis=0, **kwargs)
If
s
is anumpy.ndarray
, return a windowed copy of the array. Ifs
is anaudiomath.Sound
object (for example, if this is being used a method of that class), then its internal arrays.y
will be replaced by a windowed copy.Windowing means multiplication by the specified window function, along the specified time
axis
.func
should take a single positional argument: length in samples. Additional**kwargs
, if any, are passed through. Suitable examples includenumpy.blackman
,numpy.kaiser
, and friends.
- audiomath.Signal.Click(milliseconds, positivePulseWidth=0.5, negativePulseWidth='symmetric')
A signal function that can be passed as the
waveform
argument toGenerateWaveform
, to generate periodic clicks. Each click is a positive pulse optionally followed by a negative pulse. IfnegativePulseWidth
isNone
or the string'symmetric'
, then the width of the negative pulse is made the same aspositivePulseWidth
. Otherwise, input arguments are all expressed in milliseconds.
- audiomath.Signal.GenerateWaveform(container=None, freq_hz=1.0, phase_rad=None, phase_deg=None, amplitude=1.0, dc=0.0, samplingfreq_hz=None, duration_msec=None, duration_samples=None, axis=None, waveform=<ufunc 'cos'>, waveform_domain='auto', **kwargs)
Create a signal (or multiple signals, if the input arguments are arrays) which is a function of time (time being defined along the specified
axis
).If this is being used as a method of an
audiomath.Sound
instance, then thecontainer
argument is automatically set to that instance. Otherwise (if used as a global function), thecontainer
argument is optional—if supplied, it should be aaudiomath.Sound
object. With acontainer
, theaxis
argument is set to 0, and the container object’s sampling frequency number of channels and duration (if non-zero) are used as fallback values in case these are not specified elsewhere. The resulting signal is put intocontainer.y
and a reference to thecontainer
is returned.Default phase is 0, but may be changed by either
phase_deg
orphase_rad
(or both, as long as the values are consistent).Default duration is 1000 msec, but may be changed by either
duration_samples
orduration_msec
(or both, as long as the values are consistent).If
duration_samples
is specified andsamplingfreq_hz
is not, then the sampling frequency is chosen such that the duration is 1 second—so thenfreq_hz
can be interpreted as cycles per signal.The default
waveform
function isnumpy.cos
which means that amplitude, phase and frequency arguments can be taken straight from the kind of dictionary returned byfft2ap()
for an accurate reconstruction. Awaveform
function is assumed by default to take an input expressed in radians, unless the first argument in its signature is namedcycles
,samples
,seconds
ormilliseconds
, in which case the input argument is adjusted accordingly to achieve the named units. (To specify the units explicitly as one of these options, pass one of these words as thewaveform_domain
argument.)In this module,
SineWave()
,SquareWave()
,TriangleWave()
andSawtoothWave()
are all functions of cycles (i.e. the product of time and frequency), whereasClick()
is a function of milliseconds. Any of these can be passed as thewaveform
argument.
- audiomath.Signal.Hilbert(x, N=None, axis=0, band=(), samplingfreq_hz=None, return_dict=False)
Compute the analytic signal, just like
scipy.signal.hilbert
but with the differences that (a) the computation can be performed along any axis and (b) a limited band of the signal may be considered. Theband
argument can be a two-, three- or four-element tuple suitable for passing toShoulder()
, specifying the edges of the passband (expressed in Hz ifsamplingfreq_hz
is explicitly supplied, or relative to Nyquist if not).If
return_dict
is True, do not return just the complex analytic signal but rather a dict containing its amplitude, phase, and unwrapped phase difference.
- audiomath.Signal.InverseSpectrum(ap, real=True)
Inverse of
Spectrum()
. Takes thedict
output ofSpectrum()
(or of the underlyingfft2ap()
) and runsap2fft()
followed byifft()
on it to return a signal. Ifreal
is true, which it is by default, discard the imaginary part of the result.
- audiomath.Signal.ModulateAmplitude(s, freq_hz=1.0, phase_rad=None, phase_deg=None, amplitude=0.5, dc=0.5, samplingfreq_hz=None, duration_msec=None, duration_samples=None, axis=None, waveform=<ufunc 'sin'>, **kwargs)
If
s
is anumpy.ndarray
, return a modulated copy of the array. Ifs
is anaudiomath.Sound
object (for example, if this is being used a method of that class), then its internal arrays.y
will be replaced by a modulated copy.Modulation means multiplication by the specified
waveform
, along the specified timeaxis
.Default phase is such that amplitude is 0 at time 0, which corresponds to phase_deg=-90 if
waveform
follows sine phase (remember: by default the modulator is a raised waveform, becausedc=0.5
by default). To change phase, specify eitherphase_rad
orphase_deg
.Uses
GenerateWaveform()
- audiomath.Signal.Noise(cycles, distribution='uniform', **kwargs)
This function can be passed as the
waveform
argument toGenerateWaveform
. Thedistribution
argument should be a function, or the name of a function withinnumpy.random
, that takes asize
keyword argument dictating the shape of its output array. Additional**kwargs
are passed through to the function.If the function is
numpy.random.uniform
, then thelow
argument is set to -1.0 by default instead of the usual 0.0.If the function is
numpy.random.normal
, then thescale
argument is set to 0.2 by default instead of the usual 1.0.
- audiomath.Signal.PlotSignal(x, samplingfreq_hz=None, axis=None, **kwargs)
Plot
x
(an array with time running along the specifiedaxis
, or anaudiomath.Sound
instance) against the appropriateTimebase()
.
- audiomath.Signal.PlotSpectrum(x, samplingfreq_hz=None, axis=None, dB=False, baseValue=None, **kwargs)
Input argument
x
may be anumpy.array
oraudiomath.Sound
, in which caseSpectrum()
will be called on it. Or it may be thedict
output of a previousSpectrum()
orfft2ap()
call.
- audiomath.Signal.Reconstruct(ap, **kwargs)
Check the accuracy of
fft2ap()
andGenerateWaveform()
by reconstructing a signal as the sum of cosine waves with amplitudes and phases specified in dictap
, which is of the form output byfft2ap()
and hence also bySpectrum()
.NB: this is for small toy/debugging examples only. Its space complexity is number-of-samples squared. For real applications, use
InverseSpectrum()
.
- audiomath.Signal.ReweightSpectrum(s, func, *pargs, **kwargs)
Brutally filter the sound
s
by transforming into the Fourier domain, weighting the amplitude spectrum, and transforming back. The filtering is non-causal and (TODO) will have wrap-around artifacts whereby the two ends of the signal may bleed into each other, so use with caution—it is most suitable for noise or for periodic signals. No group delay is introduced.- Args:
- s (numpy.ndarray or audiomath.Sound):
The input sound data. If
s
is an array, a new array will be returned. If it is aSound
instance,s
will get changed in-place (the arrays.y
will be replaced by a new array) and returned.- func (callable):
A function that takes a numeric array of frequencies, in Hz, as its first (and only required) argument, and outputs a corresponding array of weights.
- samplingfreq_hz (float):
Sampling frequencym in Hz. Not needed if
s
is aSound
instance.- axis (int):
Axis along which time runs. Not needed if
s
is aSound
instance.
Additional
*pargs
and**kwargs
are passed straight through tofunc()
.
- audiomath.Signal.SawtoothWave(cycles, phase_deg=0, maxharm=None, rescale=False)
A sawtooth wave with its polarity and zero-crossings in sine phase. If
maxharm
is an integer, then an anti-aliased approximation to the sawtooth wave (containing no components of higher frequency thanmaxharm
times the fundamental) is returned instead. In this case, therescale
flag can be set to ensure that the waveform does not exceed +/- 1.0This function can be passed as the
waveform
argument toGenerateWaveform
.
- audiomath.Signal.Shoulder(x, s, complement=False, cosine=True)
Return a (possibly asymmetric) Tukey window function of
x
.s
may have 1, 2, 3 or 4 elements:raised cosine between
x=s[0]-0.5
andx=s[0]+0.5
raised cosine between
x=s[0]
andx=s[1]
raised cosine rise from
s[0]
tos[1]
, and fall froms[1]
tos[2]
raised cosine rise from
s[0]
tos[1]
, plateau froms[1]
tos[2]
, and fall froms[2]
tos[3]
- audiomath.Signal.SineWave(cycles, phase_deg=0, maxharm=None, rescale=False)
A sine wave, but with the input expressed in cycles (0 to 1) instead of radians (0 to 2*pi). Otherwise no different from
numpy.sin
, except that the function signature hasmaxharm
andrescale
arguments (which are ignored) for compatibility withSquareWave()
,TriangleWave()
andSawtoothWave()
.This function can be passed as the
waveform
argument toGenerateWaveform
.
- audiomath.Signal.Spectrum(x, samplingfreq_hz=None, axis=None)
Runs
fft
on a signal followed byfft2ap
, to return spectral information in “human-readable” format with the annoying corner cases handled.The inverse operation is
InverseSpectrum()
.
- audiomath.Signal.SquareWave(cycles, phase_deg=0, maxharm=None, rescale=False, duty=0.5, ramp=0, tol=1e-08)
A square wave with its peaks and troughs in sine phase. If
maxharm
is an integer, then an anti-aliased approximation to the square wave (containing no components of higher frequency thanmaxharm
times the fundamental) is returned instead. In this case, therescale
flag can be set to ensure that the sampled waveform does not exceed +/- 1.0This function can be passed as the
waveform
argument toGenerateWaveform
.
- audiomath.Signal.Timebase(x, samplingfreq_hz=None, axis=None)
Return a discrete time axis in seconds, against which signal
x
can be plotted.x
may be anaudiomath.Sound
instance, or you may supplysamplingfreq_hz
explicitly.
- audiomath.Signal.Toy(nSamples=11, nCycles=None, amplitude=(1.0, 0.1), phase_deg=0)
Toy sinusoidal signals for testing
fft2ap()
andap2fft()
. Check both odd and evennSamples
.
- audiomath.Signal.TriangleWave(cycles, phase_deg=0, maxharm=None, rescale=False)
A triangle wave with its peaks and troughs in sine phase. If
maxharm
is an integer, then an anti-aliased approximation to the triangle wave (containing no components of higher frequency thanmaxharm
times the fundamental) is returned instead. Therescale
flag, included for compatibility withSawtoothWave()
andSquareWave()
, has no effect.This function can be passed as the
waveform
argument toGenerateWaveform
.
- audiomath.Signal.UnwrapDiff(x, base=6.283185307179586, axis=None, startval=None, dtype=None)
Assume
X
is a wrapped version of an underlying valueY
we’re interested in. For example, it’s a 16-bit value that wraps around at 65536, or it’s an angle which wraps back to 0 at 2*pi.base
is the value (65536 or 2*pi in the above examples) such thatX = Y % base
. The default value ofbase
is 2*pi.Let
dY
be the numeric diff ofY
in dimensionaxis
, computed fromX
by unwrapping in order to avoid jumps larger thanbase/2
. Thus, withbase=65536
, a jump from 65535 to 1 is considered as a step of +2. Withbase=360
, a jump from 10 to 350 is considered as a step of -20.Y
is then reconstructed based ondY
andstartval
(which defaults to the actual initial value(s) ofX
).Return value is
(dY,Y)
.
- audiomath.Signal.ap2fft(amplitude, phase_rad=None, phase_deg=None, samplingfreq_hz=2.0, axis=0, freq_hz=None, fullfreq_hz=None, nSamples=None)
Keyword arguments match the fields of the
dict
output byfft2ap()
.The inverse of
d = fft2ap(X)
isX = ap2fft(**d)
- audiomath.Signal.fft2ap(X, samplingfreq_hz=2.0, axis=0)
Given discrete Fourier transform(s)
X
(with frequency along the specifiedaxis
), return a dict containing a properly scaled amplitude spectrum, a phase spectrum in degrees and in radians, and a frequency axis (coping with all the fiddly edge conditions).The inverse of
d = fft2ap(X)
isX = ap2fft(**d)
- audiomath.Signal.fftfreqs(nSamples, samplingfreq_hz=1.0)
Return a 1-D numpy.array of length
nSamples
containing the positive and negative frequency values corresponding to the elements of annSamples
-point FFT. Ifsamplingfreq_hz
is not supplied, 1.0 is assumed, so the result has 0.5 as its Nyquist frequency.
- audiomath.Signal.msec2samples(msec, samplingfreq_hz)
Converts milliseconds to the nearest integer number of samples given the specified sampling frequency.
- audiomath.Signal.samples2msec(samples, samplingfreq_hz)
Converts samples to milliseconds given the specified sampling frequency.