diff --git a/examples/fx_reverb/daisy-seed/Makefile b/examples/fx_reverb/daisy-seed/Makefile
new file mode 100644
index 0000000..39f6e7a
--- /dev/null
+++ b/examples/fx_reverb/daisy-seed/Makefile
@@ -0,0 +1,7 @@
+ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
+
+TARGET = bw_example_fx_delay
+
+C_SOURCES += ${ROOT_DIR}/../src/bw_example_fx_delay.c
+
+include ${ROOT_DIR}/../../common/daisy-seed/daisy-seed.mk
diff --git a/examples/fx_reverb/daisy-seed/config_daisy_seed.h b/examples/fx_reverb/daisy-seed/config_daisy_seed.h
new file mode 100644
index 0000000..466205b
--- /dev/null
+++ b/examples/fx_reverb/daisy-seed/config_daisy_seed.h
@@ -0,0 +1,35 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File authors: Stefano D'Angelo
+ */
+
+#ifndef _CONFIG_DAISY_SEED_H
+#define _CONFIG_DAISY_SEED_H
+
+struct config_pin {
+ int param_index;
+ int pin;
+};
+
+#define NUM_PINS 1
+
+static struct config_pin config_pins[NUM_PINS] = {
+ { 0, 15 }
+};
+
+#endif
diff --git a/examples/fx_reverb/src/bw_example_fx_reverb.c b/examples/fx_reverb/src/bw_example_fx_reverb.c
new file mode 100644
index 0000000..f517e94
--- /dev/null
+++ b/examples/fx_reverb/src/bw_example_fx_reverb.c
@@ -0,0 +1,71 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File author: Stefano D'Angelo
+ */
+
+#include "bw_example_fx_reverb.h"
+
+void bw_example_fx_reverb_init(bw_example_fx_reverb *instance) {
+ bw_reverb_init(&instance->reverb_coeffs);
+}
+
+void bw_example_fx_reverb_set_sample_rate(bw_example_fx_reverb *instance, float sample_rate) {
+ bw_reverb_set_sample_rate(&instance->reverb_coeffs, sample_rate);
+}
+
+BW_SIZE_T bw_example_fx_reverb_mem_req(bw_example_fx_reverb *instance) {
+ return bw_reverb_mem_req(&instance->reverb_coeffs);
+}
+
+void bw_example_fx_reverb_mem_set(bw_example_fx_reverb *instance, void *mem) {
+ bw_reverb_mem_set(&instance->reverb_state, mem);
+}
+
+void bw_example_fx_reverb_reset(bw_example_fx_reverb *instance) {
+ bw_reverb_reset_coeffs(&instance->reverb_coeffs);
+ bw_reverb_reset_state(&instance->reverb_coeffs, &instance->reverb_state);
+}
+
+void bw_example_fx_reverb_process(bw_example_fx_reverb *instance, const float** x, float** y, int n_samples) {
+ bw_reverb_process(&instance->reverb_coeffs, &instance->reverb_state, x[0], x[1], y[0], y[1], n_samples);
+}
+
+void bw_example_fx_reverb_set_parameter(bw_example_fx_reverb *instance, int index, float value) {
+ instance->params[index] = value;
+ switch (index) {
+ case p_predelay:
+ bw_reverb_set_predelay(&instance->reverb_coeffs, 0.1f * value);
+ break;
+ case p_bandwidth:
+ bw_reverb_set_bandwidth(&instance->reverb_coeffs, 20.f + (20e3f - 20.f) * value * value * value);
+ break;
+ case p_damping:
+ bw_reverb_set_damping(&instance->reverb_coeffs, 20.f + (20e3f - 20.f) * value * value * value);
+ break;
+ case p_decay:
+ bw_reverb_set_decay(&instance->reverb_coeffs, bw_minf(value, 0.999f));
+ break;
+ case p_drywet:
+ bw_reverb_set_wet(&instance->reverb_coeffs, value);
+ break;
+ }
+}
+
+float bw_example_fx_reverb_get_parameter(bw_example_fx_reverb *instance, int index) {
+ return instance->params[index];
+}
diff --git a/examples/fx_reverb/src/bw_example_fx_reverb.h b/examples/fx_reverb/src/bw_example_fx_reverb.h
new file mode 100644
index 0000000..fa65eee
--- /dev/null
+++ b/examples/fx_reverb/src/bw_example_fx_reverb.h
@@ -0,0 +1,62 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File author: Stefano D'Angelo
+ */
+
+#ifndef _BW_EXAMPLE_FX_REVERB_H
+#define _BW_EXAMPLE_FX_REVERB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+enum {
+ p_predelay,
+ p_bandwidth,
+ p_damping,
+ p_decay,
+ p_drywet,
+ p_n
+};
+
+struct _bw_example_fx_reverb {
+ // Sub-components
+ bw_reverb_coeffs reverb_coeffs;
+ bw_reverb_state reverb_state;
+
+ // Parameters
+ float params[p_n];
+};
+typedef struct _bw_example_fx_reverb bw_example_fx_reverb;
+
+void bw_example_fx_reverb_init(bw_example_fx_reverb *instance);
+void bw_example_fx_reverb_set_sample_rate(bw_example_fx_reverb *instance, float sample_rate);
+BW_SIZE_T bw_example_fx_reverb_mem_req(bw_example_fx_reverb *instance);
+void bw_example_fx_reverb_mem_set(bw_example_fx_reverb *instance, void *mem);
+void bw_example_fx_reverb_reset(bw_example_fx_reverb *instance);
+void bw_example_fx_reverb_process(bw_example_fx_reverb *instance, const float** x, float** y, int n_samples);
+void bw_example_fx_reverb_set_parameter(bw_example_fx_reverb *instance, int index, float value);
+float bw_example_fx_reverb_get_parameter(bw_example_fx_reverb *instance, int index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/examples/fx_reverb/src/config.h b/examples/fx_reverb/src/config.h
new file mode 100644
index 0000000..9c9592d
--- /dev/null
+++ b/examples/fx_reverb/src/config.h
@@ -0,0 +1,93 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File authors: Stefano D'Angelo
+ */
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+// Definitions
+
+#define IO_MONO 1
+#define IO_STEREO (1<<1)
+
+struct config_io_bus {
+ const char *name;
+ char out;
+ char aux;
+ char cv;
+ char configs;
+};
+
+struct config_parameter {
+ const char *name;
+ const char *shortName;
+ const char *units;
+ char out;
+ char bypass;
+ int steps;
+ float defaultValueUnmapped;
+};
+
+// Data
+
+#define COMPANY_NAME "Orastron"
+#define COMPANY_WEBSITE "https://www.orastron.com/"
+#define COMPANY_MAILTO "mailto:info@orastron.com"
+
+#define PLUGIN_NAME "bw_example_fx_reverb"
+#define PLUGIN_VERSION "0.5.0"
+
+#define NUM_BUSES_IN 1
+#define NUM_BUSES_OUT 1
+#define NUM_CHANNELS_IN 1
+#define NUM_CHANNELS_OUT 1
+
+static struct config_io_bus config_buses_in[NUM_BUSES_IN] = {
+ { "Audio in", 0, 0, 0, IO_STEREO }
+};
+
+static struct config_io_bus config_buses_out[NUM_BUSES_OUT] = {
+ { "Audio out", 1, 0, 0, IO_STEREO }
+};
+
+#define NUM_PARAMETERS 5
+
+static struct config_parameter config_parameters[NUM_PARAMETERS] = {
+ { "Predelay", "Predelay", "", 0, 0, 0, 0.f },
+ { "Bandwidth", "Bandwidth", "", 0, 0, 0, 1.f },
+ { "Damping", "Damping", "", 0, 0, 0, 1.f },
+ { "Decay rate", "Decay", "", 0, 0, 0, 0.5f },
+ { "Dry/wet", "Dry/wet", "", 0, 0, 0, 0.5f }
+};
+
+// Internal API
+
+#include "bw_example_fx_reverb.h"
+
+#define P_TYPE bw_example_fx_reverb
+#define P_INIT bw_example_fx_reverb_init
+#define P_SET_SAMPLE_RATE bw_example_fx_reverb_set_sample_rate
+#define P_MEM_REQ bw_example_fx_reverb_mem_req
+#define P_MEM_SET bw_example_fx_reverb_mem_set
+#define P_RESET bw_example_fx_reverb_reset
+#define P_PROCESS bw_example_fx_reverb_process
+#define P_SET_PARAMETER bw_example_fx_reverb_set_parameter
+#define P_GET_PARAMETER bw_example_fx_reverb_get_parameter
+
+#endif
diff --git a/examples/fx_reverb/vst3/Makefile b/examples/fx_reverb/vst3/Makefile
new file mode 100644
index 0000000..20c0ccf
--- /dev/null
+++ b/examples/fx_reverb/vst3/Makefile
@@ -0,0 +1,6 @@
+ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
+
+NAME := bw_example_fx_delay
+SOURCES = ${SOURCES_COMMON} ${ROOT_DIR}/../src/bw_example_fx_delay.c
+
+include ${ROOT_DIR}/../../common/vst3/vst3.mk
diff --git a/examples/fx_reverb/vst3/config_vst3.h b/examples/fx_reverb/vst3/config_vst3.h
new file mode 100644
index 0000000..358be00
--- /dev/null
+++ b/examples/fx_reverb/vst3/config_vst3.h
@@ -0,0 +1,36 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File authors: Stefano D'Angelo, Paolo Marrone
+ */
+
+#ifndef _VST3_CONFIG_H
+#define _VST3_CONFIG_H
+
+#define PLUGIN_SUBCATEGORY "Fx|Delay"
+
+#define PLUGIN_GUID_1 0x30a47806
+#define PLUGIN_GUID_2 0x850f445c
+#define PLUGIN_GUID_3 0x9f13660d
+#define PLUGIN_GUID_4 0x0e26f2dc
+
+#define CTRL_GUID_1 0xfd1e3d99
+#define CTRL_GUID_2 0xd2cb4d57
+#define CTRL_GUID_3 0x82e54aaf
+#define CTRL_GUID_4 0x5e1a5bd5
+
+#endif
diff --git a/examples/fx_reverb/web/Makefile b/examples/fx_reverb/web/Makefile
new file mode 100644
index 0000000..e9486d5
--- /dev/null
+++ b/examples/fx_reverb/web/Makefile
@@ -0,0 +1,5 @@
+ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
+SOURCES = ${SOURCES_COMMON} ${ROOT_DIR}/../src/bw_example_fx_reverb.c
+NEEDS_MEMSET := yes
+
+include ${ROOT_DIR}/../../common/web/web.mk
diff --git a/examples/fx_reverb/web/config.js b/examples/fx_reverb/web/config.js
new file mode 100644
index 0000000..631467d
--- /dev/null
+++ b/examples/fx_reverb/web/config.js
@@ -0,0 +1,58 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File author: Stefano D'Angelo
+ */
+
+var buses = [
+ {
+ stereo: false,
+ output: false
+ },
+ {
+ stereo: false,
+ output: true
+ }
+];
+
+var parameters = [
+ {
+ name: "Predelay",
+ output: false,
+ defaultValue: 0.0
+ },
+ {
+ name: "Bandwidth",
+ output: false,
+ defaultValue: 1.0
+ },
+ {
+ name: "Damping",
+ output: false,
+ defaultValue: 1.0
+ },
+ {
+ name: "Decay rate",
+ output: false,
+ defaultValue: 0.5
+ },
+ {
+ name: "Dry/wet",
+ output: false,
+ defaultValue: 0.5
+ }
+];
diff --git a/include/bw_drywet.h b/include/bw_drywet.h
index 987f13f..084dd07 100644
--- a/include/bw_drywet.h
+++ b/include/bw_drywet.h
@@ -97,22 +97,14 @@ static inline void bw_drywet_process(bw_drywet_coeffs *BW_RESTRICT coeffs, const
* wet input buffer `x_wet` and fills the first `n_samples` of the output
* buffer `y`, while using and updating `coeffs` (control and audio rate).
*
- * #### bw_drywet_set_wet_lin()
+ * #### bw_drywet_set_wet()
* ```>>> */
-static inline void bw_drywet_set_wet_lin(bw_drywet_coeffs *BW_RESTRICT coeffs, float value);
+static inline void bw_drywet_set_wet(bw_drywet_coeffs *BW_RESTRICT coeffs, float value);
/*! <<<```
* Sets the wet gain parameter to the given `value` (linear gain) in `coeffs`.
*
* Default value: `1.f`.
*
- * #### bw_drywet_set_wet_dB()
- * ```>>> */
-static inline void bw_drywet_set_wet_dB(bw_drywet_coeffs *BW_RESTRICT coeffs, float value);
-/*! <<<```
- * Sets the wet gain parameter to the given `value` (dB) in `coeffs`.
- *
- * Default value: `0.f`.
- *
* #### bw_drywet_set_smooth_tau()
* ```>>> */
static inline void bw_drywet_set_smooth_tau(bw_drywet_coeffs *BW_RESTRICT coeffs, float value);
@@ -131,7 +123,7 @@ static inline void bw_drywet_set_smooth_tau(bw_drywet_coeffs *BW_RESTRICT coeffs
struct _bw_drywet_coeffs {
// Sub-components
- bw_gain gain_coeffs;
+ bw_gain_coeffs gain_coeffs;
};
static inline void bw_drywet_init(bw_drywet_coeffs *BW_RESTRICT coeffs) {
@@ -139,7 +131,7 @@ static inline void bw_drywet_init(bw_drywet_coeffs *BW_RESTRICT coeffs) {
}
static inline void bw_drywet_set_sample_rate(bw_drywet_coeffs *BW_RESTRICT coeffs, float sample_rate) {
- bw_gain_sample_rate(&coeffs->smooth_coeffs, sample_rate);
+ bw_gain_set_sample_rate(&coeffs->gain_coeffs, sample_rate);
}
static inline void bw_drywet_reset_coeffs(bw_drywet_coeffs *BW_RESTRICT coeffs) {
@@ -155,7 +147,7 @@ static inline void bw_drywet_update_coeffs_audio(bw_drywet_coeffs *BW_RESTRICT c
}
static inline float bw_drywet_process1(const bw_drywet_coeffs *BW_RESTRICT coeffs, float x_dry, float x_wet) {
- return bw_gain_get_gain(coeffs->gain_coeffs) * (x_wet - x_dry) + x_dry;
+ return bw_gain_get_gain(&coeffs->gain_coeffs) * (x_wet - x_dry) + x_dry;
}
static inline void bw_drywet_process(bw_drywet_coeffs *BW_RESTRICT coeffs, const float *x_dry, const float *x_wet, float *y, int n_samples) {
@@ -166,14 +158,10 @@ static inline void bw_drywet_process(bw_drywet_coeffs *BW_RESTRICT coeffs, const
}
}
-static inline void bw_drywet_set_drywet_lin(bw_drywet_coeffs *BW_RESTRICT coeffs, float value) {
+static inline void bw_drywet_set_wet(bw_drywet_coeffs *BW_RESTRICT coeffs, float value) {
bw_gain_set_gain_lin(&coeffs->gain_coeffs, value);
}
-static inline void bw_drywet_set_drywet_dB(bw_drywet_coeffs *BW_RESTRICT coeffs, float value) {
- bw_gain_set_gain_dB(&coeffs->gain_coeffs, value);
-}
-
static inline void bw_drywet_set_smooth_tau(bw_drywet_coeffs *BW_RESTRICT coeffs, float value) {
bw_gain_set_smooth_tau(&coeffs->gain_coeffs, value);
}
diff --git a/include/bw_reverb.h b/include/bw_reverb.h
new file mode 100644
index 0000000..2b4349e
--- /dev/null
+++ b/include/bw_reverb.h
@@ -0,0 +1,269 @@
+/*
+ * Brickworks
+ *
+ * Copyright (C) 2023 Orastron Srl unipersonale
+ *
+ * Brickworks is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * Brickworks is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Brickworks. If not, see .
+ *
+ * File author: Stefano D'Angelo
+ */
+
+/*!
+ * module_type {{{ dsp }}}
+ * version {{{ 0.5.0 }}}
+ * requires {{{
+ * bw_buf bw_common bw_config bw_delay bw_drywet bw_gain bw_math bw_one_pole
+ * }}}
+ * description {{{
+ * 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.
+ * }}}
+ * changelog {{{
+ *
+ * - Version 0.5.0:
+ *
+ *
+ *
+ * }}}
+ */
+
+#ifndef _BW_REVERB_H
+#define _BW_REVERB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+/*! api {{{
+ * #### 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 BW_SIZE_T bw_reverb_mem_req(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(bw_reverb_state *BW_RESTRICT state, void *mem);
+/*! <<<```
+ * Associates the contiguous memory block `mem` to the given `state`.
+ *
+ * #### 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);
+/*! <<<```
+ * Resets the given `state` to its initial values using the given `coeffs`.
+ *
+ * #### 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 xl, float xr, float *yl, float *yr);
+/*! <<<```
+ * Processes two input samples `xl` and `xr` using `coeffs`, while using and
+ * updating `state`. Writes the corresponding output samples `yl` and `yr`.
+ *
+ * #### bw_reverb_process()
+ * ```>>> */
+static inline void bw_reverb_process(bw_reverb_coeffs *BW_RESTRICT coeffs, bw_reverb_state *BW_RESTRICT state, const float *xl, const float *xr, float *yl, float *yr, int n_samples);
+/*! <<<```
+ * Processes the first `n_samples` of the input buffers `xl` and `xr` and
+ * fills the first `n_samples` of the output buffers `yl` and `yr`, while
+ * using and updating both `coeffs` and `state` (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 `value` (Hz) in `coeffs`.
+ *
+ * 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 `value` (Hz) in `coeffs`.
+ *
+ * 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`.
+ *
+ * Default value: `0.5f`.
+ * }}} */
+
+/*** Implementation ***/
+
+/* WARNING: This part of the file is not part of the public API. Its content may
+ * change at any time in future versions. Please, do not use it directly. */
+
+#include
+#include
+
+struct _bw_reverb_coeffs {
+ // Sub-components
+ bw_delay_coeffs predelay_coeffs;
+ bw_drywet_coeffs drywet_coeffs;
+};
+
+struct _bw_reverb_state {
+ bw_delay_state predelay_state;
+};
+
+static inline void bw_reverb_init(bw_reverb_coeffs *BW_RESTRICT coeffs) {
+ bw_delay_init(&coeffs->predelay_coeffs, 0.1f);
+ bw_drywet_init(&coeffs->drywet_coeffs);
+ bw_drywet_set_wet(&coeffs->drywet_coeffs, 0.5f);
+}
+
+static inline void bw_reverb_set_sample_rate(bw_reverb_coeffs *BW_RESTRICT coeffs, float sample_rate) {
+ bw_delay_set_sample_rate(&coeffs->predelay_coeffs, sample_rate);
+ bw_drywet_set_sample_rate(&coeffs->drywet_coeffs, sample_rate);
+}
+
+static inline BW_SIZE_T bw_reverb_mem_req(bw_reverb_coeffs *BW_RESTRICT coeffs) {
+ return bw_delay_mem_req(&coeffs->predelay_coeffs);
+}
+
+static inline void bw_reverb_mem_set(bw_reverb_state *BW_RESTRICT state, void *mem) {
+ bw_delay_mem_set(&state->predelay_state, mem);
+}
+
+static inline void bw_reverb_reset_coeffs(bw_reverb_coeffs *BW_RESTRICT coeffs) {
+ bw_delay_reset_coeffs(&coeffs->predelay_coeffs);
+ bw_drywet_reset_coeffs(&coeffs->drywet_coeffs);
+}
+
+static inline void bw_reverb_reset_state(const bw_reverb_coeffs *BW_RESTRICT coeffs, bw_reverb_state *BW_RESTRICT state) {
+ bw_delay_reset_state(&coeffs->predelay_coeffs, &state->predelay_state);
+}
+
+static inline void bw_reverb_update_coeffs_ctrl(bw_reverb_coeffs *BW_RESTRICT coeffs) {
+ bw_delay_update_coeffs_ctrl(&coeffs->predelay_coeffs);
+ bw_drywet_update_coeffs_ctrl(&coeffs->drywet_coeffs);
+}
+
+static inline void bw_reverb_update_coeffs_audio(bw_reverb_coeffs *BW_RESTRICT coeffs) {
+ bw_delay_update_coeffs_audio(&coeffs->predelay_coeffs);
+ bw_drywet_update_coeffs_audio(&coeffs->drywet_coeffs);
+}
+
+static inline void bw_reverb_process1(const bw_reverb_coeffs *BW_RESTRICT coeffs, bw_reverb_state *BW_RESTRICT state, float xl, float xr, float *yl, float *yr) {
+ const float i = 0.5f * (xl + xr);
+ const float pd = bw_delay_process1(&coeffs->predelay_coeffs, &state->predelay_state, i);
+ *yl = bw_drywet_process1(&coeffs->drywet_coeffs, xl, pd);
+ *yr = bw_drywet_process1(&coeffs->drywet_coeffs, xr, pd);
+}
+
+static inline void bw_reverb_process(bw_reverb_coeffs *BW_RESTRICT coeffs, bw_reverb_state *BW_RESTRICT state, const float *xl, const float *xr, float *yl, float *yr, int n_samples) {
+ bw_reverb_update_coeffs_ctrl(coeffs);
+ for (int i = 0; i < n_samples; i++) {
+ bw_reverb_update_coeffs_audio(coeffs);
+ bw_reverb_process1(coeffs, state, xl[i], xr[i], yl + i, yr + i);
+ }
+}
+
+static inline void bw_reverb_set_predelay(bw_reverb_coeffs *BW_RESTRICT coeffs, float value) {
+ bw_delay_set_delay(&coeffs->predelay_coeffs, value);
+}
+
+static inline void bw_reverb_set_bandwidth(bw_reverb_coeffs *BW_RESTRICT coeffs, float value) {
+}
+
+static inline void bw_reverb_set_damping(bw_reverb_coeffs *BW_RESTRICT coeffs, float value) {
+}
+
+static inline void bw_reverb_set_decay(bw_reverb_coeffs *BW_RESTRICT coeffs, float value) {
+}
+
+static inline void bw_reverb_set_wet(bw_reverb_coeffs *BW_RESTRICT coeffs, float value) {
+ bw_drywet_set_wet(&coeffs->drywet_coeffs, value);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif