Signal Chain Components#
Signal chain components includes DSP modules for: * combining signals, such as subtracting, adding, and mixing * forks for splitting signals * basic gain components, such as fixed gain, volume control, and mute * basic delay buffers.
Adder#
The adder will add samples from N inputs together. It will round and saturate the result to the Q0.31 range.
-
int32_t adsp_adder(int32_t *input, unsigned n_ch)#
Saturating addition of an array of samples.
Note
Will work for any q format
- Parameters:
input – Array of samples
n_ch – Number of channels
- Returns:
int32_t Sum of samples
- class audio_dsp.dsp.signal_chain.adder(fs: float, n_chans: int, Q_sig: int = 27)
A class representing an adder in a signal chain.
This class inherits from the mixer class and provides an adder with no attenuation.
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
gain_db
floatThe mixer gain in decibels.
- gainfloat
Gain as a linear value.
- gain_intint
Gain as an integer value.
- process_channels(sample_list: list[float]) list[float]
Process a single sample. Apply the gain to all the input samples then sum them using floating point maths.
- Parameters:
- sample_listlist
List of input samples
- Returns:
- list[float]
Output sample.
Subtractor#
The subtractor will subtract one sample from another, then round and saturate the difference to Q0.31 range.
-
int32_t adsp_subtractor(int32_t x, int32_t y)#
Saturating subtraction of two samples, this returns
x - y
.Note
Will work for any q format
- Parameters:
x – Minuend
y – Subtrahend
- Returns:
int32_t Difference
- class audio_dsp.dsp.signal_chain.subtractor(fs: float, Q_sig: int = 27)
Subtractor class for subtracting two signals.
- Parameters:
- fsint
Sampling frequency in Hz.
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
- process_channels(sample_list: list[float]) list[float]
Subtract the second input sample from the first using floating point maths.
- Parameters:
- sample_listlist[float]
List of input samples.
- Returns:
- float
Result of the subtraction.
Fixed Gain#
This module applies a fixed gain to a sample, with rounding and saturation to Q0.31 range.
The gain must be in Q_GAIN
format.
-
Q_GAIN#
Gain format to be used in the gain APIs
-
int32_t adsp_fixed_gain(int32_t input, int32_t gain)#
Fixed-point gain.
Note
One of the inputs has to be in Q_GAIN format
- Parameters:
input – Input sample
gain – Gain
- Returns:
int32_t Output sample
- class audio_dsp.dsp.signal_chain.fixed_gain(fs: float, n_chans: int, gain_db: float, Q_sig: int = 27)
Multiply every sample by a fixed gain value.
In the current implementation, the maximum boost is +24 dB.
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- gain_dbfloat
The gain in decibels. Maximum fixed gain is +24 dB.
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
gain_db
floatThe mixer gain in decibels.
- gainfloat
Gain as a linear value.
- gain_intint
Gain as an integer value.
- process(sample: float, channel: int = 0) float
Multiply the input sample by the gain, using floating point maths.
- Parameters:
- samplefloat
The input sample to be processed.
- channelint
The channel index to process the sample on, not used by this module.
- Returns:
- float
The processed output sample.
Mixer#
The mixer applies a gain to all N channels of input samples and adds them together.
The sum is rounded and saturated to Q0.31 range. The gain must be in Q_GAIN
format.
-
int32_t adsp_mixer(int32_t *input, unsigned n_ch, int32_t gain)#
Mixer. Will add signals with gain applied to each signal before mixing.
Note
Inputs or gain have to be in Q_GAIN format
- Parameters:
input – Array of samples
n_ch – Number of channels
gain – Gain
- Returns:
int32_t Mixed sample
An alternative way to implement a mixer is to multiply-accumulate the input samples into a 64-bit word, then saturate it to a 32-bit word using:
-
int32_t adsp_saturate_32b(int64_t acc)#
Saturating 64-bit accumulator. Will saturate to 32-bit, so that the output value is in the range of int32_t.
- Parameters:
acc – Accumulator
- Returns:
int32_t Saturated value
- class audio_dsp.dsp.signal_chain.mixer(fs: float, n_chans: int, gain_db: float = -6, Q_sig: int = 27)
Mixer class for adding signals with attenuation to maintain headroom.
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- gain_dbfloat
Gain in decibels (default is -6 dB).
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
gain_db
floatThe mixer gain in decibels.
- gainfloat
Gain as a linear value.
- gain_intint
Gain as an integer value.
- process_channels(sample_list: list[float]) list[float]
Process a single sample. Apply the gain to all the input samples then sum them using floating point maths.
- Parameters:
- sample_listlist
List of input samples
- Returns:
- list[float]
Output sample.
Volume Control#
The volume control allows safe real-time gain adjustments with minimal artifacts. When the target gain is changed, a slew is used to move from the current gain to the target gain. This allows smooth gain change and no clicks in the output signal.
The mute API allows the user to safely mute the signal by setting the
target gain to 0
, with the slew ensuring no pops or clicks.
Unmuting will restore the pre-mute target gain.
The new gain can be set while muted, but will not take effect until
unmute is called.
There are separate APIs for process, setting the gain, muting and
unmuting so that volume control can easily be implemented into the
control system.
The slew is applied as an exponential of the difference between the
target and current gain.
For run-time efficiency, instead of an EMA-style alpha, the difference
is right shifted by the slew_shift
parameter. The relation between
slew_shift
and time is further discussed in the Python class
documentation.
-
struct volume_control_t#
Volume control state structure.
-
int32_t adsp_volume_control(volume_control_t *vol_ctl, int32_t samp)#
Process a new sample with a volume control.
- Parameters:
vol_ctl – Volume control object
samp – New sample
- Returns:
int32_t Processed sample
-
void adsp_volume_control_set_gain(volume_control_t *vol_ctl, int32_t new_gain)#
Set the target gain of a volume control.
- Parameters:
vol_ctl – Volume control object
new_gain – New target linear gain
-
void adsp_volume_control_mute(volume_control_t *vol_ctl)#
Mute a volume control. Will save the current target gain and set the target gain to 0.
- Parameters:
vol_ctl – Volume control object
-
void adsp_volume_control_unmute(volume_control_t *vol_ctl)#
Unmute a volume control. Will restore the saved target gain.
- Parameters:
vol_ctl – Volume control object
- class audio_dsp.dsp.signal_chain.volume_control(fs: float, n_chans: int, gain_db: float = -6, slew_shift: int = 7, mute_state: int = 0, Q_sig: int = 27)
A volume control class that allows setting the gain in decibels. When the gain is updated, an exponential slew is applied to reduce artifacts.
The slew is implemented as a shift operation. The slew rate can be converted to a time constant using the formula: time_constant = -1/ln(1 - 2^-slew_shift) * (1/fs)
A table of the first 10 slew shifts is shown below:
slew_shift
Time constant (ms)
1
0.03
2
0.07
3
0.16
4
0.32
5
0.66
6
1.32
7
2.66
8
5.32
9
10.66
10
21.32
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- gain_dbfloat, optional
The initial gain in decibels
- slew_shiftint, optional
The shift value used in the exponential slew.
- mute_stateint, optional
The mute state of the Volume Control: 0: unmuted, 1: muted.
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Raises:
- ValueError
If the gain_db parameter is greater than 24 dB.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
target_gain_db
floatThe target gain in decibels.
- target_gainfloat
The target gain as a linear value.
- target_gain_intint
The target gain as a fixed-point integer value.
- gain_dbfloat
The current gain in decibels.
- gainfloat
The current gain as a linear value.
- gain_intint
The current gain as a fixed-point integer value.
- slew_shiftint
The shift value used in the exponential slew.
- mute_stateint
The mute state of the Volume Control: 0: unmuted, 1: muted
- process(sample: float, channel: int = 0) float
Update the current gain, then multiply the input sample by it, using floating point maths.
- Parameters:
- samplefloat
The input sample to be processed.
- channelint, optional
The channel index to process the sample on. Not used by this module.
- Returns:
- float
The processed output sample.
- set_gain(gain_db: float) None
Deprecated since version 1.0.0: set_gain will be removed in 2.0.0. Replace volume_control.set_gain(x) with volume_control.target_gain_db = x
Set the gain of the volume control.
- Parameters:
- gain_dbfloat
The gain in decibels. Must be less than or equal to 24 dB.
- Raises:
- ValueError
If the gain_db parameter is greater than 24 dB.
- mute() None
Mute the volume control.
- unmute() None
Unmute the volume control.
Delay#
The delay module uses a memory buffer to return a sample after a specified
time period.
The returned samples will be delayed by a specified value.
The max_delay
is set at initialisation, and sets the amount of
memory used by the buffers. It cannot be changed at runtime.
The current delay
value can be changed at runtime within the range
[0, max_delay]
-
struct delay_t#
Delay state structure.
- class audio_dsp.dsp.signal_chain.delay(fs, n_chans, max_delay: float, starting_delay: float, units: str = 'samples')
A simple delay line class.
Note the minimum delay provided by this block is 1 sample. Setting the delay to 0 will still yield a 1 sample delay.
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- max_delayfloat
The maximum delay in specified units.
- starting_delayfloat
The starting delay in specified units.
- unitsstr, optional
The units of the delay, can be ‘samples’, ‘ms’ or ‘s’. Default is ‘samples’.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
- max_delayint
The maximum delay in samples.
delay
intThe delay in samples.
- buffernp.ndarray
The delay line buffer.
- buffer_idxint
The current index of the buffer.
- process_channels(sample_list: list[float]) list[float]
Put the new sample in the buffer and return the oldest sample.
- Parameters:
- sample_listlist[float]
The input samples to be processed. Each sample represents a different channel
- Returns:
- float
List of delayed samples.
- reset_state() None
Reset all the delay line values to zero.
- set_delay(delay: float, units: str = 'samples') None
Set the length of the delay line, will saturate at max_delay.
- Parameters:
- delayfloat
The delay length in specified units.
- unitsstr, optional
The units of the delay, can be ‘samples’, ‘ms’ or ‘s’. Default is ‘samples’.
Switch with slew#
The slewing switch module uses a cosine crossfade when moving switch position in order to avoid clicks.
-
struct switch_slew_t#
Slewing switch state structure.
-
int32_t adsp_switch_slew(switch_slew_t *switch_slew, int32_t *samples)#
Process a sample through a slewing switch. If the switch position has recently changed, this will slew between the desired input channel and previous channel.
- Parameters:
switch_slew – Slewing switch state object.
samples – An array of input samples for each input channel.
- Returns:
int32_t The output of the switch.
- class audio_dsp.dsp.signal_chain.switch_slew(fs, n_chans, Q_sig: int = 27)
A class representing a switch in a signal chain. When the switch is moved, a cosine crossfade is used to slew between the positions.
The cosine crossfade is implemented as a polynomial, with coefficients derived from a Chebyshev polynomial fit.
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
- switch_positionint
The current position of the switch.
- switchingbool
True if the switch is in the process of moving.
- stepint
Step size used for cosine calculation.
- counterint
Counter used dor cosine calculation.
- p_coeflist[float]
Polynomial cosine approximation coefficients as floats.
- p_coef_intlist[int]
Polynomial cosine approximation coefficients as ints.
- process_channels(sample_list: list[float]) list[float]
Return the sample at the current switch position.
This method takes a list of samples and returns the sample at the current switch position. If the switch position has recently changed, it will slew between the inputs.
- Parameters:
- sample_listlist
A list of samples for each of the switch inputs.
- Returns:
- yfloat
The sample at the current switch position.
- move_switch(position: int) None
Move the switch to the specified position. This will cause the channel in sample_list[position] to be output.
- Parameters:
- positionint
The position to move the switch to.
Crossfader#
The crossfader mixes between two sets of inputs.
-
static inline int32_t adsp_crossfader(int32_t in1, int32_t in2, int32_t gain1, int32_t gain2, int32_t q_gain)#
Crossfade between two channels using their gains. Will do: (in1 * gain1) + (in2 * gain2).
- Parameters:
in1 – First signal
in2 – Second signal
gain1 – First gain
gain2 – Second gain
q_gain – Q factor of the gain
- Returns:
int32_t Mixed signal
Only a slewing crossfader Python API is provided.
Crossfader with slew#
The crossfader mixes between two sets of inputs, with slew applied to the gains when they are changed.
-
struct crossfader_slew_t#
Slewing crossfader state structure.
-
int32_t adsp_crossfader_slew(crossfader_slew_t *crossfader, int32_t in1, int32_t in2)#
Crossfade between two channels with slew applied to the gains. Will do: (in1 * crossfader->gain1.gain) + (in2 * crossfader->gain2.gain).
- Parameters:
crossfader – Slewing crossfader state object.
in1 – First signal
in2 – Second signal
- Returns:
int32_t Mixed signal
- class audio_dsp.dsp.signal_chain.crossfader(fs: float, n_chans: int, mix: float = 0.5, slew_shift: int = 7, Q_sig: int = 27)
The crossfader mixes between two sets of inputs. The mix control sets the respective levels of each input. When the mix is updated, an exponential slew is applied to reduce artifacts.
The slew is implemented as a shift operation. The slew rate can be converted to a time constant using the formula: time_constant = -1/ln(1 - 2^-slew_shift) * (1/fs)
- Parameters:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- mixfloat
The channel mix, must be set between [0, 1]
- slew_shiftint, optional
The shift value used in the exponential slew.
- Q_sig: int, optional
Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.
- Attributes:
- fsint
Sampling frequency in Hz.
- n_chansint
Number of channels the block runs on.
- Q_sig: int
Q format of the signal, number of bits after the decimal point.
- n_outsint
Number of outputs, half the number of inputs.
- gainslist[float]
Floating point gains for each input for a given mix value.
- gains_intlist[int]
Fixed point gains for each input for a given mix value.
- slew_shiftint
The shift value used in the exponential slew.
- process_channels(sample_list: list[float]) list[float]
Process a single sample. Apply the crossfader gain to all the input samples using floating point maths.
- Parameters:
- sample_listlist
List of input samples
- Returns:
- list[float]
Output sample.