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_dbfloat

The mixer gain in decibels.

gainfloat

Gain as a linear value.

gain_intint

Gain as an integer value.

process_channels(sample_list: list[float]) 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:
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]) 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_dbfloat

The 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_dbfloat

The mixer gain in decibels.

gainfloat

Gain as a linear value.

gain_intint

Gain as an integer value.

process_channels(sample_list: list[float]) 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:
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.

Public Members

int32_t target_gain#

Target linear gain

int32_t gain#

Current linear gain

int32_t slew_shift#

Slew shift

int32_t saved_gain#

Saved linear gain

uint8_t mute_state#

Mute state: 0: unmuted, 1 muted

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_dbfloat

The 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.

Public Members

float fs#

Sampling frequency

uint32_t delay#

Current delay in samples

uint32_t max_delay#

Maximum delay in samples

uint32_t buffer_idx#

Current buffer index

int32_t *buffer#

Buffer

int32_t adsp_delay(delay_t *delay, int32_t samp)#

Process a new sample through a delay object.

Note

The minimum delay provided by this block is 1 sample. Setting the delay to 0 will still yield a 1 sample delay.

Parameters:
  • delay – Delay object

  • samp – New sample

Returns:

int32_t Oldest sample

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.

delayint

The delay in samples.

buffernp.ndarray

The delay line buffer.

buffer_idxint

The current index of the buffer.

process_channels(sample: list[float]) list[float]

Put the new sample in the buffer and return the oldest sample.

Parameters:
samplelist

List of input samples

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’.