From 6202235c4880e00e225af4553ad6cfe6a6d808c1 Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Wed, 23 Nov 2022 11:38:41 +0100 Subject: [PATCH] refactored bw_wah to new API + fixed fx examples --- ChangeLog | 4 +- examples/common/web/bw_config.h | 6 -- examples/fx_svf/src/bw_example_fx_svf.c | 6 +- examples/fx_svf/web/Makefile | 1 + examples/fx_wah/src/bw_example_fx_wah.c | 25 +++-- examples/fx_wah/vst3/Makefile.linux | 2 - examples/fx_wah/vst3/Makefile.macos | 2 - examples/fx_wah/vst3/Makefile.win32 | 2 - examples/fx_wah/web/Makefile | 3 +- include/bw_wah.h | 118 ++++++++++++++++++------ src/bw_wah.c | 44 --------- 11 files changed, 113 insertions(+), 100 deletions(-) delete mode 100644 src/bw_wah.c diff --git a/ChangeLog b/ChangeLog index 7e0b4da..e6c8f89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,8 +5,8 @@ * Added bw_wah and bw_example_fx_wah. * Added BW_RESTRICT and removed BW_MALLOC, BW_REALLOC, and BW_FREE from bw_common. - * Renamed bw_example_fx to bw_example_fx_svf. - * Removed output "Level" parameter from bw_example_fx_svf. + * Renamed bw_example_fx to bw_example_fx_svf are removed output "Level" + parameter from it. * Using correct "Fx|Filter" VST3 subcategory for bw_example_fx_svf. * Using official logo as VST3 plugin icon. diff --git a/examples/common/web/bw_config.h b/examples/common/web/bw_config.h index f9a874e..7777d5b 100644 --- a/examples/common/web/bw_config.h +++ b/examples/common/web/bw_config.h @@ -20,12 +20,6 @@ #ifndef _BW_CONFIG_H #define _BW_CONFIG_H -#include "walloc.h" - -#define BW_MALLOC malloc -#define BW_REALLOC realloc -#define BW_FREE free - #define INFINITY (__builtin_inff()) #endif diff --git a/examples/fx_svf/src/bw_example_fx_svf.c b/examples/fx_svf/src/bw_example_fx_svf.c index 3576dab..538f5ad 100644 --- a/examples/fx_svf/src/bw_example_fx_svf.c +++ b/examples/fx_svf/src/bw_example_fx_svf.c @@ -20,7 +20,11 @@ #include "bw_example_fx_svf.h" #include -#include +#ifdef __WASM__ +# include "walloc.h" +#else +# include +#endif enum { p_cutoff, diff --git a/examples/fx_svf/web/Makefile b/examples/fx_svf/web/Makefile index 78edcbc..a919dbe 100644 --- a/examples/fx_svf/web/Makefile +++ b/examples/fx_svf/web/Makefile @@ -1,5 +1,6 @@ CC=clang CFLAGS= \ + -D__WASM__ \ -I${ROOT_DIR}/../src \ -I${ROOT_DIR}/../../common/web \ -I${ROOT_DIR}/../../../include \ diff --git a/examples/fx_wah/src/bw_example_fx_wah.c b/examples/fx_wah/src/bw_example_fx_wah.c index fbd4caa..edfed7f 100644 --- a/examples/fx_wah/src/bw_example_fx_wah.c +++ b/examples/fx_wah/src/bw_example_fx_wah.c @@ -19,8 +19,13 @@ #include "bw_example_fx_wah.h" -#include #include +#ifdef __WASM__ +# include "walloc.h" +#else +# include +#endif + enum { p_wah, @@ -29,37 +34,39 @@ enum { struct _bw_example_fx_wah { // Sub-components - bw_wah wah; + bw_wah_coeffs wah_coeffs; + bw_wah_state wah_state; // Parameters float params[p_n]; }; bw_example_fx_wah bw_example_fx_wah_new() { - bw_example_fx_wah instance = (bw_example_fx_wah)BW_MALLOC(sizeof(struct _bw_example_fx_wah)); + bw_example_fx_wah instance = (bw_example_fx_wah)malloc(sizeof(struct _bw_example_fx_wah)); if (instance != NULL) - bw_wah_init(&instance->wah); + bw_wah_init(&instance->wah_coeffs); return instance; } void bw_example_fx_wah_free(bw_example_fx_wah instance) { - BW_FREE(instance); + free(instance); } void bw_example_fx_wah_set_sample_rate(bw_example_fx_wah instance, float sample_rate) { - bw_wah_set_sample_rate(&instance->wah, sample_rate); + bw_wah_set_sample_rate(&instance->wah_coeffs, sample_rate); } void bw_example_fx_wah_reset(bw_example_fx_wah instance) { - bw_wah_reset(&instance->wah); + bw_wah_reset_coeffs(&instance->wah_coeffs); + bw_wah_reset_state(&instance->wah_coeffs, &instance->wah_state); } void bw_example_fx_wah_process(bw_example_fx_wah instance, const float** x, float** y, int n_samples) { - bw_wah_process(&instance->wah, x[0], y[0], n_samples); + bw_wah_process(&instance->wah_coeffs, &instance->wah_state, x[0], y[0], n_samples); } void bw_example_fx_wah_set_parameter(bw_example_fx_wah instance, int index, float value) { - bw_wah_set_wah(&instance->wah, value); + bw_wah_set_wah(&instance->wah_coeffs, value); } float bw_example_fx_wah_get_parameter(bw_example_fx_wah instance, int index) { diff --git a/examples/fx_wah/vst3/Makefile.linux b/examples/fx_wah/vst3/Makefile.linux index 3ae3409..84fed50 100644 --- a/examples/fx_wah/vst3/Makefile.linux +++ b/examples/fx_wah/vst3/Makefile.linux @@ -19,8 +19,6 @@ INSTALL_PREFIX=/usr/local ROOT_DIR=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) SOURCES= \ - ${ROOT_DIR}/../../../src/bw_wah.c \ - ${ROOT_DIR}/../../../src/bw_svf.c \ ${ROOT_DIR}/../src/bw_example_fx_wah.c \ \ ${ROOT_DIR}/../../common/vst3/entry.cpp \ diff --git a/examples/fx_wah/vst3/Makefile.macos b/examples/fx_wah/vst3/Makefile.macos index faf28d0..d6293ef 100644 --- a/examples/fx_wah/vst3/Makefile.macos +++ b/examples/fx_wah/vst3/Makefile.macos @@ -17,8 +17,6 @@ LDFLAGS= \ ROOT_DIR=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) SOURCES= \ - ${ROOT_DIR}/../../../src/bw_wah.c \ - ${ROOT_DIR}/../../../src/bw_svf.c \ ${ROOT_DIR}/../src/bw_example_fx_wah.c \ \ ${ROOT_DIR}/../../common/vst3/entry.cpp \ diff --git a/examples/fx_wah/vst3/Makefile.win32 b/examples/fx_wah/vst3/Makefile.win32 index dc5b8b9..3d37422 100644 --- a/examples/fx_wah/vst3/Makefile.win32 +++ b/examples/fx_wah/vst3/Makefile.win32 @@ -25,8 +25,6 @@ ARCH=x86_64 ROOT_DIR=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) SOURCES= \ - ${ROOT_DIR}/../../../src/bw_wah.c \ - ${ROOT_DIR}/../../../src/bw_svf.c \ ${ROOT_DIR}/../src/bw_example_fx_wah.c \ \ ${ROOT_DIR}/../../common/vst3/entry.cpp \ diff --git a/examples/fx_wah/web/Makefile b/examples/fx_wah/web/Makefile index c4accc0..81a3fe9 100644 --- a/examples/fx_wah/web/Makefile +++ b/examples/fx_wah/web/Makefile @@ -1,5 +1,6 @@ CC=clang CFLAGS= \ + -D__WASM__ \ -I${ROOT_DIR}/../src \ -I${ROOT_DIR}/../../common/web \ -I${ROOT_DIR}/../../../include \ @@ -25,8 +26,6 @@ LDFLAGS= \ ROOT_DIR=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) SOURCES= \ - ${ROOT_DIR}/../../../src/bw_wah.c \ - ${ROOT_DIR}/../../../src/bw_svf.c \ ${ROOT_DIR}/../src/bw_example_fx_wah.c \ ${ROOT_DIR}/../../common/web/walloc.c \ ${ROOT_DIR}/../../common/web/wrapper.c diff --git a/include/bw_wah.h b/include/bw_wah.h index 901c290..2bb63a7 100644 --- a/include/bw_wah.h +++ b/include/bw_wah.h @@ -20,7 +20,7 @@ /*! * module_type {{{ dsp }}} * version {{{ 0.2.0 }}} - * requires {{{ bw_config bw_common bw_one_pole bw_math bw_wah }}} + * requires {{{ bw_config bw_common bw_one_pole bw_math bw_svf }}} * description {{{ * Wah effect. * @@ -44,42 +44,51 @@ extern "C" { #endif -/*! api {{{ - * #### bw_wah - * ```>>> */ -typedef struct _bw_wah bw_wah; -/*! <<<``` - * Instance object. - * >>> */ +#include -/*! ... +/*! api {{{ + * #### bw_wah_coeffs + * ```>>> */ +typedef struct _bw_wah_coeffs bw_wah_coeffs; +/*! <<<``` + * Coefficients. + * + * ### bw_svf_state + * ```>>> */ +typedef struct _bw_wah_state bw_wah_state; +/*! <<<``` + * State. + * * #### bw_wah_init() * ```>>> */ -void bw_wah_init(bw_wah *instance); +static inline void bw_wah_init(bw_wah_coeffs *BW_RESTRICT coeffs); /*! <<<``` - * Initializes the `instance` object. - * >>> */ - -/*! ... + * Initializes `coeffs`. + * * #### bw_wah_set_sample_rate() * ```>>> */ -void bw_wah_set_sample_rate(bw_wah *instance, float sample_rate); +static inline void bw_wah_set_sample_rate(bw_wah_coeffs *BW_RESTRICT coeffs, float sample_rate); /*! <<<``` - * Sets the `sample_rate` (Hz) value for the given `instance`. + * Sets the `sample_rate` (Hz) value for the given `coeffs`. + * + * #### bw_wah_reset_state() + * ```>>> */ +static inline void bw_wah_reset_state(const bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state); +/*! <<<``` + * Resets the given `state` to the initial state using the given `coeffs`. * >>> */ -/*! ... - * #### bw_wah_reset() - * ```>>> */ -void bw_wah_reset(bw_wah *instance); -/*! <<<``` - * Resets the given `instance` to its initial state. - * >>> */ +static inline void bw_wah_reset_coeffs(bw_wah_coeffs *BW_RESTRICT coeffs); + +static inline void bw_wah_update_coeffs_ctrl(bw_wah_coeffs *BW_RESTRICT coeffs); +static inline void bw_wah_update_coeffs_audio(bw_wah_coeffs *BW_RESTRICT coeffs); + +static inline float bw_wah_process1(const bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state, float x); /*! ... * #### bw_wah_process() * ```>>> */ -void bw_wah_process(bw_wah *instance, const float *x, float *y, int n_samples); +static inline void bw_wah_process(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state, const float *x, float *y, int n_samples); /*! <<<``` * Lets the given `instance` process `n_samples` samples from the input * buffer `x` and fills the corresponding `n_samples` samples in the output @@ -89,7 +98,7 @@ void bw_wah_process(bw_wah *instance, const float *x, float *y, int n_samples); /*! ... * #### bw_wah_set_wah() * ```>>> */ -void bw_wah_set_wah(bw_wah *instance, float value); +static inline void bw_wah_set_wah(bw_wah_coeffs *BW_RESTRICT coeffs, float value); /*! <<<``` * Sets the wah pedal position to the given `value` in [`0.f` (low cutoff), * `1.f` (high cutoff)]. @@ -97,16 +106,65 @@ void bw_wah_set_wah(bw_wah *instance, float value); * 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 -/* WARNING: the internal definition of this struct is not part of the public - * API. Its content may change at any time in future versions. Please, do not - * access its members directly. */ -struct _bw_wah { +struct _bw_wah_coeffs { // Sub-components - bw_svf svf; + bw_svf_coeffs svf_coeffs; }; +struct _bw_wah_state { + // Sub-components + bw_svf_state svf_state; +}; + +static inline void bw_wah_init(bw_wah_coeffs *BW_RESTRICT coeffs) { + bw_svf_init(&coeffs->svf_coeffs); + bw_wah_set_wah(coeffs, 0.5f); + bw_svf_set_Q(&coeffs->svf_coeffs, 9.f); +} + +static inline void bw_wah_set_sample_rate(bw_wah_coeffs *BW_RESTRICT coeffs, float sample_rate) { + bw_svf_set_sample_rate(&coeffs->svf_coeffs, sample_rate); +} + +static inline void bw_wah_reset_coeffs(bw_wah_coeffs *BW_RESTRICT coeffs) { + bw_svf_reset_coeffs(&coeffs->svf_coeffs); +} + +static inline void bw_wah_reset_state(const bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state) { + bw_svf_reset_state(&coeffs->svf_coeffs, &state->svf_state); +} + +static inline void bw_wah_update_coeffs_ctrl(bw_wah_coeffs *BW_RESTRICT coeffs) { + bw_svf_update_coeffs_ctrl(&coeffs->svf_coeffs); +} + +static inline void bw_wah_update_coeffs_audio(bw_wah_coeffs *BW_RESTRICT coeffs) { + bw_svf_update_coeffs_audio(&coeffs->svf_coeffs); +} + +static inline float bw_wah_process1(const bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state, float x) { + return bw_svf_process1_bp(&coeffs->svf_coeffs, &state->svf_state, x); +} + +static inline void bw_wah_process(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state, const float *x, float *y, int n_samples) { + bw_wah_update_coeffs_ctrl(coeffs); + for (int i = 0; i < n_samples; i++) { + bw_wah_update_coeffs_audio(coeffs); + y[i] = bw_wah_process1(coeffs, state, x[i]); + } +} + +static inline void bw_wah_set_wah(bw_wah_coeffs *BW_RESTRICT coeffs, float value) { + bw_svf_set_cutoff(&coeffs->svf_coeffs, 400.f + (2e3f - 400.f) * value * value * value); +} + #ifdef __cplusplus } #endif diff --git a/src/bw_wah.c b/src/bw_wah.c deleted file mode 100644 index a175890..0000000 --- a/src/bw_wah.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Brickworks - * - * Copyright (C) 2022 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 - * - * File author: Stefano D'Angelo - */ - -#include - -#include - -void bw_wah_init(bw_wah *instance) { - bw_svf_init(&instance->svf); - bw_wah_set_wah(instance, 0.5f); - bw_svf_set_Q(&instance->svf, 9.f); -} - -void bw_wah_set_sample_rate(bw_wah *instance, float sample_rate) { - bw_svf_set_sample_rate(&instance->svf, sample_rate); -} - -void bw_wah_reset(bw_wah *instance) { - bw_svf_reset(&instance->svf); -} - -void bw_wah_process(bw_wah *instance, const float *x, float *y, int n_samples) { - bw_svf_process(&instance->svf, x, NULL, y, NULL, n_samples); -} - -void bw_wah_set_wah(bw_wah *instance, float value) { - bw_svf_set_cutoff(&instance->svf, 400.f + (2e3f - 400.f) * value * value * value); -}