bw_reverb

Stereo reverb.

Essentially an implementation of the structure described in

J. Dattorro, "Effect Design, Part 1: Reverberator and Other Filters", J. Audio Eng. Soc., vol. 45, no. 9, pp. 660-684, September 1997.

Examples

Here you can download one or more example VST3 plugins for Windows, macOS and Linux. Source code of the audio engine(s) is included in the archive(s).

DescriptionLink
Algorithmic reverb Download
VST® is a trademark of Steinberg Media Technologies GmbH, registered in Europe and other countries.

API

Module type: DSP

bw_reverb_coeffs

typedef struct bw_reverb_coeffs bw_reverb_coeffs;

Coefficients and related.

bw_reverb_state

typedef struct bw_reverb_state bw_reverb_state;

Internal state and related.

bw_reverb_init()

static inline void bw_reverb_init(
	bw_reverb_coeffs * BW_RESTRICT coeffs);

Initializes input parameter values in coeffs.

bw_reverb_set_sample_rate()

static inline void bw_reverb_set_sample_rate(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	float                          sample_rate);

Sets the sample_rate (Hz) value in coeffs.

bw_reverb_mem_req()

static inline size_t bw_reverb_mem_req(
	const bw_reverb_coeffs * BW_RESTRICT coeffs);

Returns the size, in bytes, of contiguous memory to be supplied to bw_reverb_mem_set() using coeffs.

bw_reverb_mem_set()

static inline void bw_reverb_mem_set(
	const bw_reverb_coeffs * BW_RESTRICT coeffs,
	bw_reverb_state * BW_RESTRICT        state,
	void * BW_RESTRICT                   mem);

Associates the contiguous memory block mem to the given state using coeffs.

bw_reverb_reset_coeffs()

static inline void bw_reverb_reset_coeffs(
	bw_reverb_coeffs * BW_RESTRICT coeffs);

Resets coefficients in coeffs to assume their target values.

bw_reverb_reset_state()

static inline void bw_reverb_reset_state(
	const bw_reverb_coeffs * BW_RESTRICT coeffs,
	bw_reverb_state * BW_RESTRICT        state,
	float                                x_l_0,
	float                                x_r_0,
	float * BW_RESTRICT                  y_l_0,
	float * BW_RESTRICT                  y_r_0);

Resets the given state to its initial values using the given coeffs and the initial input values x_l_0 (left) and x_r_0 (right).

The corresponding initial output values are put into y_l_0 (left) and y_r_0 (right).

bw_reverb_reset_state_multi()

static inline void bw_reverb_reset_state_multi(
	const bw_reverb_coeffs * BW_RESTRICT              coeffs,
	bw_reverb_state * BW_RESTRICT const * BW_RESTRICT state,
	const float *                                     x_l_0,
	const float *                                     x_r_0,
	float *                                           y_l_0,
	float *                                           y_r_0,
	size_t                                            n_channels);

Resets each of the n_channels states to its initial values using the given coeffs and the corresponding initial input values in the x_l_0 (left) and x_r_0 (right) arrays.

The corresponding initial output values are written into the y_l_0 (left) and y_r_0 arrays, if each is not BW_NULL.

bw_reverb_update_coeffs_ctrl()

static inline void bw_reverb_update_coeffs_ctrl(
	bw_reverb_coeffs * BW_RESTRICT coeffs);

Triggers control-rate update of coefficients in coeffs.

bw_reverb_update_coeffs_audio()

static inline void bw_reverb_update_coeffs_audio(
	bw_reverb_coeffs * BW_RESTRICT coeffs);

Triggers audio-rate update of coefficients in coeffs.

bw_reverb_process1()

static inline void bw_reverb_process1(
	const bw_reverb_coeffs * BW_RESTRICT coeffs,
	bw_reverb_state * BW_RESTRICT        state,
	float                                x_l,
	float                                x_r,
	float * BW_RESTRICT                  y_l,
	float * BW_RESTRICT                  y_r);

Processes one set of input samples x_l (left) and x_r (right) using coeffs, while using and updating state. The left and right output samples are put into y_l (left) and y_r (right) respectively.

bw_reverb_process()

static inline void bw_reverb_process(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	bw_reverb_state * BW_RESTRICT  state,
	const float *                  x_l,
	const float *                  x_r,
	float *                        y_l,
	float *                        y_r,
	size_t                         n_samples);

Processes the first n_samples of the input buffers x_l (left) and x_r (right) and fills the first n_samples of the output buffers y_l (left) and y_r (right), while using and updating both coeffs and state (control and audio rate).

bw_reverb_process_multi()

static inline void bw_reverb_process_multi(
	bw_reverb_coeffs * BW_RESTRICT                    coeffs,
	bw_reverb_state * BW_RESTRICT const * BW_RESTRICT state,
	const float * const *                             x_l,
	const float * const *                             x_r,
	float * const *                                   y_l,
	float * const *                                   y_r,
	size_t                                            n_channels,
	size_t                                            n_samples);

Processes the first n_samples of the n_channels input buffers x_l (left) and x_r (right) and fills the first n_samples of the n_channels output buffers y_l (left) and y_r (right), while using and updating both the common coeffs and each of the n_channels states (control and audio rate).

bw_reverb_set_predelay()

static inline void bw_reverb_set_predelay(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	float                          value);

Sets the predelay time value (s) in coeffs.

Valid input range: [0.f, 0.1f].

Default value: 0.f.

bw_reverb_set_bandwidth()

static inline void bw_reverb_set_bandwidth(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	float                          value);

Sets the input high-frequency attenuation cutoff value (Hz) in coeffs.

Valid range: [20.f, 20e3f].

Default value: 20e3f.

bw_reverb_set_damping()

static inline void bw_reverb_set_damping(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	float                          value);

Sets the high-frequency damping cutoff value (Hz) in coeffs.

Valid range: [20.f, 20e3f].

Default value: 20e3f.

bw_reverb_set_decay()

static inline void bw_reverb_set_decay(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	float                          value);

Sets the decay rate value in coeffs.

Valid input range: [0.f, 1.f).

Default value: 0.5f.

bw_reverb_set_wet()

static inline void bw_reverb_set_wet(
	bw_reverb_coeffs * BW_RESTRICT coeffs,
	float                          value);

Sets the output wet mixing value (linear gain) in coeffs.

Valid range: [0.f, 1.f].

Default value: 0.5f.

bw_reverb_coeffs_is_valid()

static inline char bw_reverb_coeffs_is_valid(
	const bw_reverb_coeffs * BW_RESTRICT coeffs);

Tries to determine whether coeffs is valid and returns non-0 if it seems to be the case and 0 if it is certainly not. False positives are possible, false negatives are not.

coeffs must at least point to a readable memory block of size greater than or equal to that of bw_reverb_coeffs.

bw_reverb_state_is_valid()

static inline char bw_reverb_state_is_valid(
	const bw_reverb_coeffs * BW_RESTRICT coeffs,
	const bw_reverb_state * BW_RESTRICT  state);

Tries to determine whether state is valid and returns non-0 if it seems to be the case and 0 if it is certainly not. False positives are possible, false negatives are not.

If coeffs is not BW_NULL extra cross-checks might be performed (state is supposed to be associated to coeffs).

state must at least point to a readable memory block of size greater than or equal to that of bw_reverb_state.

C++ wrapper

Brickworks::Reverb
template<size_t N_CHANNELS>
class Reverb {
public:
	Reverb();

	~Reverb();

	void setSampleRate(
		float sampleRate);

	void reset(
		float               xL0 = 0.f,
		float               xR0 = 0.f,
		float * BW_RESTRICT yL0 = nullptr,
		float * BW_RESTRICT yR0 = nullptr);

# ifndef BW_CXX_NO_ARRAY
	void reset(
		float                                       xL0,
		float                                       xR0,
		std::array<float, N_CHANNELS> * BW_RESTRICT yL0,
		std::array<float, N_CHANNELS> * BW_RESTRICT yR0);
# endif

	void reset(
		const float * xL0,
		const float * xR0,
		float *       yL0 = nullptr,
		float *       yR0 = nullptr);

# ifndef BW_CXX_NO_ARRAY
	void reset(
		std::array<float, N_CHANNELS>               xL0,
		std::array<float, N_CHANNELS>               xR0,
		std::array<float, N_CHANNELS> * BW_RESTRICT yL0 = nullptr,
		std::array<float, N_CHANNELS> * BW_RESTRICT yR0 = nullptr);
# endif

	void process(
		const float * const * xL,
		const float * const * xR,
		float * const *       yL,
		float * const *       yR,
		size_t                nSamples);

# ifndef BW_CXX_NO_ARRAY
	void process(
		std::array<const float *, N_CHANNELS> xL,
		std::array<const float *, N_CHANNELS> xR,
		std::array<float *, N_CHANNELS>       yL,
		std::array<float *, N_CHANNELS>       yR,
		size_t                                nSamples);
# endif

	void setPredelay(
		float value);

	void setBandwidth(
		float value);

	void setDamping(
		float value);

	void setDecay(
		float value);

	void setWet(
		float value);
...
}

Changelog

  • Version 1.2.0:
    • Added support for BW_INCLUDE_WITH_QUOTES, BW_NO_CXX, and BW_CXX_NO_EXTERN_C.
    • Added missing BW_RESTRICT to arguments of bw_reverb_process1().
    • Added debugging checks from bw_reverb_process() to bw_reverb_process_multi().
    • Added debugging checks in bw_reverb_process_multi() to ensure that buffers used for both input and output appear at the same channel indices.
    • Removed wrong sentence from the documentation of bw_reverb_reset_state().
  • Version 1.1.0:
    • Fixed smoothing of decay parameter in bw_reverb_update_coeffs_audio().
    • Now using BW_NULL and BW_CXX_NO_ARRAY.
  • Version 1.0.0:
    • Added initial value arguments in bw_reverb_reset_state().
    • Added bw_reverb_reset_state_multi() and updated C++ API in this regard.
    • Now bw_reverb_reset_state() returns the initial output values.
    • Added overloaded C++ reset() functions taking arrays as arguments.
    • Now using size_t instead of BW_SIZE_T.
    • bw_reverb_process() and bw_reverb_process_multi() now use size_t to count samples and channels.
    • Added more const and BW_RESTRICT specifiers to input arguments and implementation.
    • Moved C++ code to C header.
    • Added overloaded C++ process() function taking C-style arrays as arguments.
    • Removed usage of reserved identifiers.
    • Clearly specified parameter validity ranges.
    • Added debugging code.
  • Version 0.6.0:
    • Removed dependency on bw_config.
  • Version 0.5.0:
    • First release.