diff --git a/TODO b/TODO index 342336b..b3c799c 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,6 @@ 1.0.0 ----- -in progress: -* merge c++ code into c headers -* revise typedef style (see https://stackoverflow.com/questions/54752861/using-an-anonymous-struct-vs-a-named-struct-with-typedef) -* var names xy -> x_y -* don't use reserved identifiers (https://devblogs.microsoft.com/oldnewthing/20230109-00/?p=107685) code: * debugging * check all examples again diff --git a/examples/fxpp_flanger/src/bw_example_fxpp_flanger.h b/examples/fxpp_flanger/src/bw_example_fxpp_flanger.h index 6daec7c..90eb652 100644 --- a/examples/fxpp_flanger/src/bw_example_fxpp_flanger.h +++ b/examples/fxpp_flanger/src/bw_example_fxpp_flanger.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include using namespace Brickworks; diff --git a/examples/fxpp_mm1/src/bw_example_fxpp_mm1.h b/examples/fxpp_mm1/src/bw_example_fxpp_mm1.h index 95f330f..2d0055e 100644 --- a/examples/fxpp_mm1/src/bw_example_fxpp_mm1.h +++ b/examples/fxpp_mm1/src/bw_example_fxpp_mm1.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include using namespace Brickworks; diff --git a/examples/fxpp_svf/src/bw_example_fxpp_svf.h b/examples/fxpp_svf/src/bw_example_fxpp_svf.h index 3db1d37..2ee97d2 100644 --- a/examples/fxpp_svf/src/bw_example_fxpp_svf.h +++ b/examples/fxpp_svf/src/bw_example_fxpp_svf.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include using namespace Brickworks; diff --git a/examples/fxpp_vibrato/src/bw_example_fxpp_vibrato.h b/examples/fxpp_vibrato/src/bw_example_fxpp_vibrato.h index 6175a6e..b3bb0a5 100644 --- a/examples/fxpp_vibrato/src/bw_example_fxpp_vibrato.h +++ b/examples/fxpp_vibrato/src/bw_example_fxpp_vibrato.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include using namespace Brickworks; diff --git a/examples/fxpp_wah/src/bw_example_fxpp_wah.h b/examples/fxpp_wah/src/bw_example_fxpp_wah.h index 674c3a7..ef224d8 100644 --- a/examples/fxpp_wah/src/bw_example_fxpp_wah.h +++ b/examples/fxpp_wah/src/bw_example_fxpp_wah.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include using namespace Brickworks; diff --git a/examples/synthpp_mono/src/bw_example_synthpp_mono.h b/examples/synthpp_mono/src/bw_example_synthpp_mono.h index f8efce6..59d9eb6 100644 --- a/examples/synthpp_mono/src/bw_example_synthpp_mono.h +++ b/examples/synthpp_mono/src/bw_example_synthpp_mono.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/synthpp_poly/src/bw_example_synthpp_poly.h b/examples/synthpp_poly/src/bw_example_synthpp_poly.h index becd786..bdf3a8d 100644 --- a/examples/synthpp_poly/src/bw_example_synthpp_poly.h +++ b/examples/synthpp_poly/src/bw_example_synthpp_poly.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/examples/synthpp_simple/src/bw_example_synthpp_simple.h b/examples/synthpp_simple/src/bw_example_synthpp_simple.h index 25a2a97..98214a2 100644 --- a/examples/synthpp_simple/src/bw_example_synthpp_simple.h +++ b/examples/synthpp_simple/src/bw_example_synthpp_simple.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/bw_svf.h b/include/bw_svf.h index d363cb8..4275b55 100644 --- a/include/bw_svf.h +++ b/include/bw_svf.h @@ -30,8 +30,15 @@ *
    *
  • Version 1.0.0: *
      - *
    • Now using size_t instead of - * BW_SIZE_T.
    • + *
    • bw_svf_process() and + * bw_svf_process_multi() now use size_t + * to count samples and channels.
    • + *
    • Added more const specifiers to input + * arguments.
    • + *
    • Moved C++ code to C header.
    • + *
    • Added overladed C++ process() function taking + * C-style arrays as arguments.
    • + *
    • Removed usage of reserved identifiers.
    • *
    *
  • *
  • Version 0.6.0: @@ -79,8 +86,8 @@ * }}} */ -#ifndef _BW_SVF_H -#define _BW_SVF_H +#ifndef BW_SVF_H +#define BW_SVF_H #include @@ -91,13 +98,13 @@ extern "C" { /*! api {{{ * #### bw_svf_coeffs * ```>>> */ -typedef struct _bw_svf_coeffs bw_svf_coeffs; +typedef struct bw_svf_coeffs bw_svf_coeffs; /*! <<<``` * Coefficients and related. * * #### bw_svf_state * ```>>> */ -typedef struct _bw_svf_state bw_svf_state; +typedef struct bw_svf_state bw_svf_state; /*! <<<``` * Internal state and related. * @@ -121,10 +128,10 @@ static inline void bw_svf_reset_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs); * * #### bw_svf_reset_state() * ```>>> */ -static inline void bw_svf_reset_state(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, float x0); +static inline void bw_svf_reset_state(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, float x_0); /*! <<<``` * Resets the given `state` to its initial values using the given `coeffs` - * and the quiescent/initial input value `x0`. + * and the quiescent/initial input value `x_0`. * * #### bw_svf_update_coeffs_ctrl() * ```>>> */ @@ -148,7 +155,7 @@ static inline void bw_svf_process1(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_s * * #### bw_svf_process() * ```>>> */ -static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, const float *x, float *y_lp, float *y_bp, float *y_hp, int n_samples); +static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, const float *x, float *y_lp, float *y_bp, float *y_hp, size_t n_samples); /*! <<<``` * Processes the first `n_samples` of the input buffer `x` and fills the * first `n_samples` of the output buffers `y_lp` (lowpass), `y_bp` @@ -157,7 +164,7 @@ static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_stat * * #### bw_svf_process_multi() * ```>>> */ -static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state **BW_RESTRICT state, const float **x, float **y_lp, float **y_bp, float **y_hp, int n_channels, int n_samples); +static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state * const *BW_RESTRICT state, const float * const *x, float **y_lp, float **y_bp, float **y_hp, size_t n_channels, size_t n_samples); /*! <<<``` * Processes the first `n_samples` of the `n_channels` input buffers `x` and * fills the first `n_samples` of the `n_channels` output buffers `y_lp` @@ -224,7 +231,7 @@ static inline void bw_svf_set_prewarp_freq(bw_svf_coeffs *BW_RESTRICT coeffs, fl extern "C" { #endif -struct _bw_svf_coeffs { +struct bw_svf_coeffs { // Sub-components bw_one_pole_coeffs smooth_coeffs; bw_one_pole_state smooth_cutoff_state; @@ -248,7 +255,7 @@ struct _bw_svf_coeffs { float prewarp_freq; }; -struct _bw_svf_state { +struct bw_svf_state { float hp_z1; float lp_z1; float bp_z1; @@ -271,7 +278,7 @@ static inline void bw_svf_set_sample_rate(bw_svf_coeffs *BW_RESTRICT coeffs, flo coeffs->t_k = 3.141592653589793f / sample_rate; } -static inline void _bw_svf_do_update_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs, char force) { +static inline void bw_svf_do_update_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs, char force) { const float prewarp_freq = coeffs->prewarp_freq + coeffs->prewarp_k * (coeffs->cutoff - coeffs->prewarp_freq); float cutoff_cur = bw_one_pole_get_y_z1(&coeffs->smooth_cutoff_state); float prewarp_freq_cur = bw_one_pole_get_y_z1(&coeffs->smooth_prewarp_freq_state); @@ -303,12 +310,12 @@ static inline void bw_svf_reset_coeffs(bw_svf_coeffs *BW_RESTRICT coeffs) { bw_one_pole_reset_state(&coeffs->smooth_coeffs, &coeffs->smooth_cutoff_state, coeffs->cutoff); bw_one_pole_reset_state(&coeffs->smooth_coeffs, &coeffs->smooth_Q_state, coeffs->Q); bw_one_pole_reset_state(&coeffs->smooth_coeffs, &coeffs->smooth_prewarp_freq_state, coeffs->prewarp_freq + coeffs->prewarp_k * (coeffs->cutoff - coeffs->prewarp_freq)); - _bw_svf_do_update_coeffs(coeffs, 1); + bw_svf_do_update_coeffs(coeffs, 1); } -static inline void bw_svf_reset_state(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, float x0) { +static inline void bw_svf_reset_state(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, float x_0) { state->hp_z1 = 0.f; - state->lp_z1 = x0; + state->lp_z1 = x_0; state->bp_z1 = 0.f; state->cutoff_z1 = coeffs->cutoff; } @@ -318,7 +325,7 @@ static inline void bw_svf_update_coeffs_ctrl(bw_svf_coeffs *BW_RESTRICT coeffs) } static inline void bw_svf_update_coeffs_audio(bw_svf_coeffs *BW_RESTRICT coeffs) { - _bw_svf_do_update_coeffs(coeffs, 0); + bw_svf_do_update_coeffs(coeffs, 0); } static inline void bw_svf_process1(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, float x, float *BW_RESTRICT y_lp, float *BW_RESTRICT y_bp, float *BW_RESTRICT y_hp) { @@ -334,16 +341,16 @@ static inline void bw_svf_process1(const bw_svf_coeffs *BW_RESTRICT coeffs, bw_s state->cutoff_z1 = bw_one_pole_get_y_z1(&coeffs->smooth_cutoff_state); } -static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, const float *x, float *y_lp, float *y_bp, float *y_hp, int n_samples) { +static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state *BW_RESTRICT state, const float *x, float *y_lp, float *y_bp, float *y_hp, size_t n_samples) { if (y_lp != NULL) { if (y_bp != NULL) { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); bw_svf_process1(coeffs, state, x[i], y_lp + i, y_bp + i, y_hp + i); } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_hp; bw_svf_process1(coeffs, state, x[i], y_lp + i, y_bp + i, &v_hp); @@ -351,13 +358,13 @@ static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_stat } } else { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_bp; bw_svf_process1(coeffs, state, x[i], y_lp + i, &v_bp, y_hp + i); } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_bp, v_hp; bw_svf_process1(coeffs, state, x[i], y_lp + i, &v_bp, &v_hp); @@ -367,13 +374,13 @@ static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_stat } else { if (y_bp != NULL) { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_lp; bw_svf_process1(coeffs, state, x[i], &v_lp, y_bp + i, y_hp + i); } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_lp, v_hp; bw_svf_process1(coeffs, state, x[i], &v_lp, y_bp + i, &v_hp); @@ -381,13 +388,13 @@ static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_stat } } else { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_lp, v_bp; bw_svf_process1(coeffs, state, x[i], &v_lp, &v_bp, y_hp + i); } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state, x[i], &v_lp, &v_bp, &v_hp); @@ -397,13 +404,13 @@ static inline void bw_svf_process(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_stat } } -static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state **BW_RESTRICT state, const float **x, float **y_lp, float **y_bp, float **y_hp, int n_channels, int n_samples) { +static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_svf_state * const *BW_RESTRICT state, const float * const *x, float **y_lp, float **y_bp, float **y_hp, size_t n_channels, size_t n_samples) { if (y_lp != NULL) { if (y_bp != NULL) { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_lp[j]) @@ -415,9 +422,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_lp[j]) @@ -429,9 +436,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } } else { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_lp[j]) @@ -441,9 +448,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_lp[j]) @@ -455,9 +462,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } else { if (y_bp != NULL) { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_bp[j]) @@ -467,9 +474,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_bp[j]) @@ -479,9 +486,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } } else { if (y_hp != NULL) { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); if (y_hp[j]) @@ -489,9 +496,9 @@ static inline void bw_svf_process_multi(bw_svf_coeffs *BW_RESTRICT coeffs, bw_sv } } } else { - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_svf_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) { + for (size_t j = 0; j < n_channels; j++) { float v_lp, v_bp, v_hp; bw_svf_process1(coeffs, state[j], x[j][i], &v_lp, &v_bp, &v_hp); } @@ -518,6 +525,116 @@ static inline void bw_svf_set_prewarp_freq(bw_svf_coeffs *BW_RESTRICT coeffs, fl } #ifdef __cplusplus +} + +#include + +namespace Brickworks { + +/*** Public C++ API ***/ + +/*! api_cpp {{{ + * ##### Brickworks::SVF + * ```>>> */ +template +class SVF { +public: + SVF(); + + void setSampleRate(float sampleRate); + void reset(float x_0 = 0.f); + void process( + const float * const *x, + float **y_lp, + float **y_bp, + float **y_hp, + size_t nSamples); + void process( + std::array x, + std::array y_lp, + std::array y_bp, + std::array y_hp, + size_t nSamples); + + void setCutoff(float value); + void setQ(float value); + void setPrewarpAtCutoff(bool value); + void setPrewarpFreq(float value); +/*! <<<... + * } + * ``` + * }}} */ + +/*** 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. */ + +private: + bw_svf_coeffs coeffs; + bw_svf_state states[N_CHANNELS]; + bw_svf_state *statesP[N_CHANNELS]; +}; + +template +inline SVF::SVF() { + bw_svf_init(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + statesP[i] = states + i; +} + +template +inline void SVF::setSampleRate(float sampleRate) { + bw_svf_set_sample_rate(&coeffs, sampleRate); +} + +template +inline void SVF::reset(float x_0) { + bw_svf_reset_coeffs(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + bw_svf_reset_state(&coeffs, states + i, x_0); +} + +template +inline void SVF::process( + const float * const *x, + float **y_lp, + float **y_bp, + float **y_hp, + size_t nSamples) { + bw_svf_process_multi(&coeffs, statesP, x, y_lp, y_bp, y_hp, N_CHANNELS, nSamples); +} + +template +inline void SVF::process( + std::array x, + std::array y_lp, + std::array y_bp, + std::array y_hp, + size_t nSamples) { + process(x.data(), y_lp.data(), y_bp.data(), y_hp.data(), nSamples); +} + +template +inline void SVF::setCutoff(float value) { + bw_svf_set_cutoff(&coeffs, value); +} + +template +inline void SVF::setQ(float value) { + bw_svf_set_Q(&coeffs, value); +} + +template +inline void SVF::setPrewarpAtCutoff(bool value) { + bw_svf_set_prewarp_at_cutoff(&coeffs, value); +} + +template +inline void SVF::setPrewarpFreq(float value) { + bw_svf_set_prewarp_freq(&coeffs, value); +} + } #endif diff --git a/include/bw_wah.h b/include/bw_wah.h index a45fdfd..a0e58f0 100644 --- a/include/bw_wah.h +++ b/include/bw_wah.h @@ -31,8 +31,15 @@ *
      *
    • Version 1.0.0: *
        - *
      • Now using size_t instead of - * BW_SIZE_T.
      • + *
      • bw_wah_process() and + * bw_wah_process_multi() now use size_t + * to count samples and channels.
      • + *
      • Added more const specifiers to input + * arguments.
      • + *
      • Moved C++ code to C header.
      • + *
      • Added overladed C++ process() function taking + * C-style arrays as arguments.
      • + *
      • Removed usage of reserved identifiers.
      • *
      *
    • *
    • Version 0.6.0: @@ -69,8 +76,8 @@ * }}} */ -#ifndef _BW_WAH_H -#define _BW_WAH_H +#ifndef BW_WAH_H +#define BW_WAH_H #include @@ -81,13 +88,13 @@ extern "C" { /*! api {{{ * #### bw_wah_coeffs * ```>>> */ -typedef struct _bw_wah_coeffs bw_wah_coeffs; +typedef struct bw_wah_coeffs bw_wah_coeffs; /*! <<<``` * Coefficients and related. * * #### bw_wah_state * ```>>> */ -typedef struct _bw_wah_state bw_wah_state; +typedef struct bw_wah_state bw_wah_state; /*! <<<``` * Internal state and related. * @@ -136,7 +143,7 @@ static inline float bw_wah_process1(const bw_wah_coeffs *BW_RESTRICT coeffs, bw_ * * #### bw_wah_process() * ```>>> */ -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); +static inline void bw_wah_process(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state, const float *x, float *y, size_t n_samples); /*! <<<``` * Processes the first `n_samples` of the input buffer `x` and fills the * first `n_samples` of the output buffer `y`, while using and updating both @@ -144,7 +151,7 @@ static inline void bw_wah_process(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_stat * * #### bw_wah_process_multi() * ```>>> */ -static inline void bw_wah_process_multi(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples); +static inline void bw_wah_process_multi(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state * const *BW_RESTRICT state, const float * const *x, float **y, size_t n_channels, size_t n_samples); /*! <<<``` * Processes the first `n_samples` of the `n_channels` input buffers `x` and * fills the first `n_samples` of the `n_channels` output buffers `y`, while @@ -176,12 +183,12 @@ static inline void bw_wah_set_wah(bw_wah_coeffs *BW_RESTRICT coeffs, float value extern "C" { #endif -struct _bw_wah_coeffs { +struct bw_wah_coeffs { // Sub-components bw_svf_coeffs svf_coeffs; }; -struct _bw_wah_state { +struct bw_wah_state { // Sub-components bw_svf_state svf_state; }; @@ -218,19 +225,19 @@ static inline float bw_wah_process1(const bw_wah_coeffs *BW_RESTRICT coeffs, bw_ return v_bp; } -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) { +static inline void bw_wah_process(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state *BW_RESTRICT state, const float *x, float *y, size_t n_samples) { bw_wah_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t 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_process_multi(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) { +static inline void bw_wah_process_multi(bw_wah_coeffs *BW_RESTRICT coeffs, bw_wah_state * const *BW_RESTRICT state, const float * const *x, float **y, size_t n_channels, size_t n_samples) { bw_wah_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_wah_update_coeffs_audio(coeffs); - for (int j = 0; j < n_channels; j++) + for (size_t j = 0; j < n_channels; j++) y[j][i] = bw_wah_process1(coeffs, state[j], x[j][i]); } } @@ -240,6 +247,90 @@ static inline void bw_wah_set_wah(bw_wah_coeffs *BW_RESTRICT coeffs, float value } #ifdef __cplusplus +} + +#include + +namespace Brickworks { + +/*** Public C++ API ***/ + +/*! api_cpp {{{ + * ##### Brickworks::Wah + * ```>>> */ +template +class Wah { +public: + Wah(); + + void setSampleRate(float sampleRate); + void reset(); + void process( + const float * const *x, + float **y, + size_t nSamples); + void process( + std::array x, + std::array y, + size_t nSamples); + + void setWah(float value); +/*! <<<... + * } + * ``` + * }}} */ + +/*** 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. */ + +private: + bw_wah_coeffs coeffs; + bw_wah_state states[N_CHANNELS]; + bw_wah_state *statesP[N_CHANNELS]; +}; + +template +inline Wah::Wah() { + bw_wah_init(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + statesP[i] = states + i; +} + +template +inline void Wah::setSampleRate(float sampleRate) { + bw_wah_set_sample_rate(&coeffs, sampleRate); +} + +template +inline void Wah::reset() { + bw_wah_reset_coeffs(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + bw_wah_reset_state(&coeffs, states + i); +} + +template +inline void Wah::process( + const float * const *x, + float **y, + size_t nSamples) { + bw_wah_process_multi(&coeffs, statesP, x, y, N_CHANNELS, nSamples); +} + +template +inline void Wah::process( + std::array x, + std::array y, + size_t nSamples) { + process(x.data(), y.data(), nSamples); +} + +template +inline void Wah::setWah(float value) { + bw_wah_set_wah(&coeffs, value); +} + } #endif diff --git a/include/bwpp_svf.h b/include/bwpp_svf.h deleted file mode 100644 index cf4448c..0000000 --- a/include/bwpp_svf.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 BWPP_SVF_H -#define BWPP_SVF_H - -#include -#include - -namespace Brickworks { - -/*! api {{{ - * ##### Brickworks::SVF - * ```>>> */ -template -class SVF { -public: - SVF(); - - void setSampleRate(float sampleRate); - void reset(float x0 = 0.f); - void process( - std::array x, - std::array y_lp, - std::array y_bp, - std::array y_hp, - int nSamples); - - void setCutoff(float value); - void setQ(float value); - void setPrewarpAtCutoff(bool value); - void setPrewarpFreq(float value); -/*! <<<... - * } - * ``` - * }}} */ - -/*** 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. */ - -private: - bw_svf_coeffs coeffs; - bw_svf_state states[N_CHANNELS]; - bw_svf_state *statesP[N_CHANNELS]; -}; - -template -inline SVF::SVF() { - bw_svf_init(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - statesP[i] = states + i; -} - -template -inline void SVF::setSampleRate(float sampleRate) { - bw_svf_set_sample_rate(&coeffs, sampleRate); -} - -template -inline void SVF::reset(float x0) { - bw_svf_reset_coeffs(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - bw_svf_reset_state(&coeffs, states + i, x0); -} - -template -inline void SVF::process( - std::array x, - std::array y_lp, - std::array y_bp, - std::array y_hp, - int nSamples) { - bw_svf_process_multi(&coeffs, statesP, x.data(), y_lp.data(), y_bp.data(), y_hp.data(), N_CHANNELS, nSamples); -} - -template -inline void SVF::setCutoff(float value) { - bw_svf_set_cutoff(&coeffs, value); -} - -template -inline void SVF::setQ(float value) { - bw_svf_set_Q(&coeffs, value); -} - -template -inline void SVF::setPrewarpAtCutoff(bool value) { - bw_svf_set_prewarp_at_cutoff(&coeffs, value); -} - -template -inline void SVF::setPrewarpFreq(float value) { - bw_svf_set_prewarp_freq(&coeffs, value); -} - -} - -#endif diff --git a/include/bwpp_wah.h b/include/bwpp_wah.h deleted file mode 100644 index dbd5f42..0000000 --- a/include/bwpp_wah.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 BWPP_WAH_H -#define BWPP_WAH_H - -#include -#include - -namespace Brickworks { - -/*! api {{{ - * ##### Brickworks::Wah - * ```>>> */ -template -class Wah { -public: - Wah(); - - void setSampleRate(float sampleRate); - void reset(); - void process( - std::array x, - std::array y, - int nSamples); - - void setWah(float value); -/*! <<<... - * } - * ``` - * }}} */ - -/*** 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. */ - -private: - bw_wah_coeffs coeffs; - bw_wah_state states[N_CHANNELS]; - bw_wah_state *statesP[N_CHANNELS]; -}; - -template -inline Wah::Wah() { - bw_wah_init(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - statesP[i] = states + i; -} - -template -inline void Wah::setSampleRate(float sampleRate) { - bw_wah_set_sample_rate(&coeffs, sampleRate); -} - -template -inline void Wah::reset() { - bw_wah_reset_coeffs(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - bw_wah_reset_state(&coeffs, states + i); -} - -template -inline void Wah::process( - std::array x, - std::array y, - int nSamples) { - bw_wah_process_multi(&coeffs, statesP, x.data(), y.data(), N_CHANNELS, nSamples); -} - -template -inline void Wah::setWah(float value) { - bw_wah_set_wah(&coeffs, value); -} - -} - -#endif