Skip to content
Back to top

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

C API

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

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    `gain_db` float

      The mixer gain in decibels.

    gain float

      Gain as a linear value.

    gain_int int

      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_list list

        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.

C API

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

Python API

class audio_dsp.dsp.signal_chain.subtractor(fs: float, Q_sig: int = 27)

  Subtractor class for subtracting two signals.

  Parameters:
    fs int

      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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      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_list list[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

C API

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

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    gain_db float

      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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    `gain_db` float

      The mixer gain in decibels.

    gain float

      Gain as a linear value.

    gain_int int

      Gain as an integer value.

  process(sample: float, channel: int = 0) → float

    Multiply the input sample by the gain, using floating point maths.

    Parameters:
      sample float

        The input sample to be processed.

      channel int

        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.

C API

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

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    gain_db float

      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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    `gain_db` float

      The mixer gain in decibels.

    gain float

      Gain as a linear value.

    gain_int int

      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_list list

        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.

  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

C API

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

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    gain_db float, optional

      The initial gain in decibels

    slew_shift int, optional

      The shift value used in the exponential slew.

    mute_state int, 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.

  Attributes:
    fs int

      Sampling frequency in Hz.

    n_chans int

      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` float

      The target gain in decibels.

    target_gain float

      The target gain as a linear value.

    target_gain_int int

      The target gain as a fixed-point integer value.

    gain_db float

      The current gain in decibels.

    gain float

      The current gain as a linear value.

    gain_int int

      The current gain as a fixed-point integer value.

    slew_shift int

      The shift value used in the exponential slew.

    mute_state int

      The mute state of the Volume Control: 0: unmuted, 1: muted

  Raises:
    ValueError

      If the gain_db parameter is greater than 24 dB.

  process(sample: float, channel: int = 0) → float

    Update the current gain, then multiply the input sample by it, using floating point maths.

    Parameters:
      sample float

        The input sample to be processed.

      channel int, 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_db float

        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

C API

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

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    max_delay float

      The maximum delay in specified units.

    starting_delay float

      The starting delay in specified units.

    units str, optional

      The units of the delay, can be ‘samples’, ‘ms’ or ‘s’. Default is ‘samples’.

  Attributes:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    max_delay int

      The maximum delay in samples.

    `delay` int

      The delay in samples.

    buffer np.ndarray

      The delay line buffer.

    buffer_idx int

      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_list list[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:
      delay float

        The delay length in specified units.

      units str, 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.

  Public Members

  bool switching

    If slewing, switching is True until slewing is over.

  int32_t position

    Current switch pole position.

  int32_t last_position

    Last switch pole position.

  int32_t counter

    Counter for timing slew length.

  int32_t step

    Step increment of counter.

C API

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.

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    switch_position int

      The current position of the switch.

    switching bool

      True if the switch is in the process of moving.

    step int

      Step size used for cosine calculation.

    counter int

      Counter used dor cosine calculation.

    p_coef list[float]

      Polynomial cosine approximation coefficients as floats.

    p_coef_int list[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_list list

        A list of samples for each of the switch inputs.

    Returns:
      y float

        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:
      position int

        The position to move the switch to.

## Crossfader

The crossfader mixes between two sets of inputs.

C API

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

Python API

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.

  Public Members

  gain_slew_t gain_1

    Slewing gain struct for first crossfader input.

  gain_slew_t gain_2

    Slewing gain struct for second crossfader input.

  float mix

    Mix of the inputs.

C API

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

Python API

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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    mix float

      The channel mix, must be set between [0, 1]

    slew_shift int, 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:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    n_outs int

      Number of outputs, half the number of inputs.

    gains list[float]

      Floating point gains for each input for a given mix value.

    gains_int list[int]

      Fixed point gains for each input for a given mix value.

    slew_shift int

      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_list list

        List of input samples

    Returns:
      list[float]

        Output sample.

## Router 4to1

The 4:1 Router allows the selection of any combination of up to 4 inputs to be mixed to a single output.

C API

int32_t adsp_router_4to1(int32_t *router_states, int32_t *samples)

  Process samples through the 4:1 router.

  Takes an array of 4 input samples and routes active channels to a single output according to the router_states array values. Active channels (set to 1 in router_states) are summed together.

  Parameters:

    - router_states – Pointer to a 4 long array of channel states (0 = disabled, 1 = enabled)

    - samples – Array of 4 input samples

  Returns:

    int32_t Mixed output sample

Python API

class audio_dsp.dsp.signal_chain.router_4to1(

  fs,
  n_chans=4,
  channel_states=[True, False, False, False],
  Q_sig: int = 27,

)

  A class representing a 4:1 router in a signal chain.

  This sums a combination of the input channels as specified by the channel_states attribute.

  Parameters:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    channel_states list[bool]

      Boolean list indicating which channels are active (True) or inactive (False).

    Q_sig: int, optional

      Q format of the signal, number of bits after the decimal point. Defaults to Q4.27.

  Attributes:
    fs int

      Sampling frequency in Hz.

    n_chans int

      Number of channels the block runs on.

    Q_sig: int

      Q format of the signal, number of bits after the decimal point.

    channel_states list[bool]

      Boolean list indicating which channels are active (True) or inactive (False).

  process_channels(sample_list: list[float]) → list[float]

    Mix the active input channels together.

    This method takes a list of samples and sums the samples from channels that are set to active in the channel_states list.

    Parameters:
      sample_list list

        A list of samples for each of the router inputs.

    Returns:
      y list[float]

        The mixed output from active channels.

  set_channel_states(channel_states: list[bool]) → None

    Set which channels are active or inactive.

    Parameters:
      channel_states list[bool]

        A list of 4 boolean values indicating which channels should be active (True) or inactive (False).