From f89188f790adf4f83c405ed3f91dadaef00d3c05 Mon Sep 17 00:00:00 2001 From: Stefano D'Angelo Date: Sat, 12 Aug 2023 18:45:19 +0200 Subject: [PATCH] polished bw_{delay,dist,drive,drywet} + removed bwpp_{delay,dist,drive,drywet} + fixed doc in bw_{clip,comb,comp} + fixed examples --- TODO | 9 +- examples/fx_reverb/src/bw_example_fx_reverb.h | 2 + .../fxpp_delay/src/bw_example_fxpp_delay.h | 2 +- examples/fxpp_dist/src/bw_example_fxpp_dist.h | 2 +- .../fxpp_drive/src/bw_example_fxpp_drive.h | 2 +- include/bw_clip.h | 4 +- include/bw_comb.h | 4 +- include/bw_comp.h | 8 +- include/bw_delay.h | 155 ++++++++++++++++-- include/bw_dist.h | 133 +++++++++++++-- include/bw_drive.h | 133 +++++++++++++-- include/bw_drywet.h | 121 ++++++++++++-- include/bwpp_delay.h | 131 --------------- include/bwpp_dist.h | 107 ------------ include/bwpp_drive.h | 107 ------------ include/bwpp_drywet.h | 97 ----------- 16 files changed, 507 insertions(+), 510 deletions(-) delete mode 100644 include/bwpp_delay.h delete mode 100644 include/bwpp_dist.h delete mode 100644 include/bwpp_drive.h delete mode 100644 include/bwpp_drywet.h diff --git a/TODO b/TODO index aa74f1a..52d688d 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,11 @@ 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 @@ -27,13 +32,9 @@ code: * bw_fuzz gain compensation? * make gain of distortions homogeneous? * max_delay -> set sample rate? see reverb -* 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) * update state ctrl -> process ctrl? * mem req -> return value of set sample rate? * peak gain + Q ??? -* merge c++ code into c headers * sr_reduce reset_coeffs? update_coeffs? process_multi? * drywet -> dry_wet, ringmod -> ring_mod, etc? * allow nullptr in C++ wrappers where process_multi arg can be NULL diff --git a/examples/fx_reverb/src/bw_example_fx_reverb.h b/examples/fx_reverb/src/bw_example_fx_reverb.h index b2fc275..136a5e3 100644 --- a/examples/fx_reverb/src/bw_example_fx_reverb.h +++ b/examples/fx_reverb/src/bw_example_fx_reverb.h @@ -21,6 +21,8 @@ #ifndef _BW_EXAMPLE_FX_REVERB_H #define _BW_EXAMPLE_FX_REVERB_H +#include "platform.h" + #include #ifdef __cplusplus diff --git a/examples/fxpp_delay/src/bw_example_fxpp_delay.h b/examples/fxpp_delay/src/bw_example_fxpp_delay.h index d4fe92a..5d4fa71 100644 --- a/examples/fxpp_delay/src/bw_example_fxpp_delay.h +++ b/examples/fxpp_delay/src/bw_example_fxpp_delay.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include using namespace Brickworks; diff --git a/examples/fxpp_dist/src/bw_example_fxpp_dist.h b/examples/fxpp_dist/src/bw_example_fxpp_dist.h index f65b4e3..e4ebee5 100644 --- a/examples/fxpp_dist/src/bw_example_fxpp_dist.h +++ b/examples/fxpp_dist/src/bw_example_fxpp_dist.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include #include using namespace Brickworks; diff --git a/examples/fxpp_drive/src/bw_example_fxpp_drive.h b/examples/fxpp_drive/src/bw_example_fxpp_drive.h index 9d336ee..3e5d094 100644 --- a/examples/fxpp_drive/src/bw_example_fxpp_drive.h +++ b/examples/fxpp_drive/src/bw_example_fxpp_drive.h @@ -23,7 +23,7 @@ #include "platform.h" -#include +#include #include using namespace Brickworks; diff --git a/include/bw_clip.h b/include/bw_clip.h index a2bb7a7..7fc4db6 100644 --- a/include/bw_clip.h +++ b/include/bw_clip.h @@ -327,7 +327,9 @@ static inline void bw_clip_set_gain_compensation(bw_clip_coeffs *BW_RESTRICT coe namespace Brickworks { -/*! api {{{ +/*** Public C++ API ***/ + +/*! api_cpp {{{ * ##### Brickworks::Clip * ```>>> */ template diff --git a/include/bw_comb.h b/include/bw_comb.h index 08d02d8..b282d49 100644 --- a/include/bw_comb.h +++ b/include/bw_comb.h @@ -397,7 +397,9 @@ static inline void bw_comb_set_coeff_fb(bw_comb_coeffs *BW_RESTRICT coeffs, floa namespace Brickworks { -/*! api {{{ +/*** Public C++ API ***/ + +/*! api_cpp {{{ * ##### Brickworks::Comb * ```>>> */ template diff --git a/include/bw_comp.h b/include/bw_comp.h index f4c51aa..fe746b5 100644 --- a/include/bw_comp.h +++ b/include/bw_comp.h @@ -31,8 +31,8 @@ *
    *
  • Version 1.0.0: *
      - *
    • bw_comb_process() and - * bw_comb_process_multi() now use size_t + *
    • bw_comp_process() and + * bw_comp_process_multi() now use size_t * to count samples and channels.
    • *
    • Added more const specifiers to input * arguments.
    • @@ -346,7 +346,9 @@ static inline void bw_comp_set_gain_dB(bw_comp_coeffs *BW_RESTRICT coeffs, float namespace Brickworks { -/*! api {{{ +/*** Public C++ API ***/ + +/*! api_cpp {{{ * ##### Brickworks::Comp * ```>>> */ template diff --git a/include/bw_delay.h b/include/bw_delay.h index e088440..db8c8aa 100644 --- a/include/bw_delay.h +++ b/include/bw_delay.h @@ -35,6 +35,15 @@ *
        *
      • Now using size_t instead of * BW_SIZE_T.
      • + *
      • bw_delay_process() and + * bw_delay_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: @@ -58,8 +67,8 @@ * }}} */ -#ifndef _BW_DELAY_H -#define _BW_DELAY_H +#ifndef BW_DELAY_H +#define BW_DELAY_H #include @@ -70,13 +79,13 @@ extern "C" { /*! api {{{ * #### bw_delay_coeffs * ```>>> */ -typedef struct _bw_delay_coeffs bw_delay_coeffs; +typedef struct bw_delay_coeffs bw_delay_coeffs; /*! <<<``` * Coefficients and related. * * #### bw_delay_state * ```>>> */ -typedef struct _bw_delay_state bw_delay_state; +typedef struct bw_delay_state bw_delay_state; /*! <<<``` * Internal state and related. * @@ -156,7 +165,7 @@ static inline float bw_delay_process1(const bw_delay_coeffs *BW_RESTRICT coeffs, * * #### bw_delay_process() * ```>>> */ -static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, const float *x, float *y, int n_samples); +static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_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 @@ -164,7 +173,7 @@ static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_dela * * #### bw_delay_process_multi() * ```>>> */ -static inline void bw_delay_process_multi(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples); +static inline void bw_delay_process_multi(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_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 @@ -202,7 +211,7 @@ static inline size_t bw_delay_get_length(const bw_delay_coeffs *BW_RESTRICT coef extern "C" { #endif -struct _bw_delay_coeffs { +struct bw_delay_coeffs { // Coefficients float fs; size_t len; @@ -216,7 +225,7 @@ struct _bw_delay_coeffs { char delay_changed; }; -struct _bw_delay_state { +struct bw_delay_state { float *buf; size_t idx; }; @@ -280,16 +289,16 @@ static inline float bw_delay_process1(const bw_delay_coeffs *BW_RESTRICT coeffs, return bw_delay_read(coeffs, state, coeffs->di, coeffs->df); } -static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, const float *x, float *y, int n_samples) { +static inline void bw_delay_process(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state *BW_RESTRICT state, const float *x, float *y, size_t n_samples) { bw_delay_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) + for (size_t i = 0; i < n_samples; i++) y[i] = bw_delay_process1(coeffs, state, x[i]); } -static inline void bw_delay_process_multi(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) { +static inline void bw_delay_process_multi(bw_delay_coeffs *BW_RESTRICT coeffs, bw_delay_state * const *BW_RESTRICT state, const float * const *x, float **y, size_t n_channels, size_t n_samples) { bw_delay_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) - for (int j = 0; j < n_channels; j++) + for (size_t i = 0; i < n_samples; i++) + for (size_t j = 0; j < n_channels; j++) y[j][i] = bw_delay_process1(coeffs, state[j], x[j][i]); } @@ -305,6 +314,126 @@ static inline size_t bw_delay_get_length(const bw_delay_coeffs *BW_RESTRICT coef } #ifdef __cplusplus +} + +#include + +namespace Brickworks { + +/*** Public C++ API ***/ + +/*! api_cpp {{{ + * ##### Brickworks::Delay + * ```>>> */ +template +class Delay { +public: + Delay(float maxDelay = 1.f); + ~Delay(); + + 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); + + float read(size_t channel, size_t di, float df); + void write(size_t channel, float x); + + void setDelay(float value); + + size_t getLength(); +/*! <<<... + * } + * ``` + * }}} */ + +/*** 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_delay_coeffs coeffs; + bw_delay_state states[N_CHANNELS]; + bw_delay_state *statesP[N_CHANNELS]; + void *mem; +}; + +template +inline Delay::Delay(float maxDelay) { + bw_delay_init(&coeffs, maxDelay); + for (size_t i = 0; i < N_CHANNELS; i++) + statesP[i] = states + i; + mem = nullptr; +} + +template +inline Delay::~Delay() { + if (mem != nullptr) + operator delete(mem); +} + +template +inline void Delay::setSampleRate(float sampleRate) { + bw_delay_set_sample_rate(&coeffs, sampleRate); + size_t req = bw_delay_mem_req(&coeffs); + if (mem != nullptr) + operator delete(mem); + mem = operator new(req * N_CHANNELS); + void *m = mem; + for (size_t i = 0; i < N_CHANNELS; i++, m = static_cast(m) + req) + bw_delay_mem_set(&coeffs, states + i, m); +} + +template +inline void Delay::reset() { + bw_delay_reset_coeffs(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + bw_delay_reset_state(&coeffs, states + i); +} + +template +inline void Delay::process( + const float * const *x, + float **y, + size_t nSamples) { + bw_delay_process_multi(&coeffs, statesP, x, y, N_CHANNELS, nSamples); +} + +template +inline void Delay::process( + std::array x, + std::array y, + size_t nSamples) { + process(x.data(), y.data(), nSamples); +} + +template +inline float Delay::read(size_t channel, size_t di, float df) { + return bw_delay_read(&coeffs, states + channel, di, df); +} + +template +inline void Delay::write(size_t channel, float x) { + bw_delay_write(&coeffs, states + channel, x); +} + +template +inline void Delay::setDelay(float value) { + bw_delay_set_delay(&coeffs, value); +} + +template +inline size_t Delay::getLength() { + return bw_delay_get_length(&coeffs); +} + } #endif diff --git a/include/bw_dist.h b/include/bw_dist.h index 2b620df..09caaf7 100644 --- a/include/bw_dist.h +++ b/include/bw_dist.h @@ -34,8 +34,15 @@ *
        *
      • Version 1.0.0: *
          - *
        • Now using size_t instead of - * BW_SIZE_T.
        • + *
        • bw_dist_process() and + * bw_dist_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: @@ -52,8 +59,8 @@ * }}} */ -#ifndef _BW_DIST_H -#define _BW_DIST_H +#ifndef BW_DIST_H +#define BW_DIST_H #include @@ -64,13 +71,13 @@ extern "C" { /*! api {{{ * #### bw_dist_coeffs * ```>>> */ -typedef struct _bw_dist_coeffs bw_dist_coeffs; +typedef struct bw_dist_coeffs bw_dist_coeffs; /*! <<<``` * Coefficients and related. * * #### bw_dist_state * ```>>> */ -typedef struct _bw_dist_state bw_dist_state; +typedef struct bw_dist_state bw_dist_state; /*! <<<``` * Internal state and related. * @@ -119,7 +126,7 @@ static inline float bw_dist_process1(const bw_dist_coeffs *BW_RESTRICT coeffs, b * * #### bw_dist_process() * ```>>> */ -static inline void bw_dist_process(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_state *BW_RESTRICT state, const float *x, float *y, int n_samples); +static inline void bw_dist_process(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_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 @@ -127,7 +134,7 @@ static inline void bw_dist_process(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_s * * #### bw_dist_process_multi() * ```>>> */ -static inline void bw_dist_process_multi(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples); +static inline void bw_dist_process_multi(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_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 @@ -181,7 +188,7 @@ static inline void bw_dist_set_volume(bw_dist_coeffs *BW_RESTRICT coeffs, float extern "C" { #endif -struct _bw_dist_coeffs { +struct bw_dist_coeffs { // Sub-components bw_hp1_coeffs hp1_coeffs; bw_peak_coeffs peak_coeffs; @@ -191,7 +198,7 @@ struct _bw_dist_coeffs { bw_gain_coeffs gain_coeffs; }; -struct _bw_dist_state { +struct bw_dist_state { // Sub-components bw_hp1_state hp1_state; bw_peak_state peak_state; @@ -263,19 +270,19 @@ static inline float bw_dist_process1(const bw_dist_coeffs *BW_RESTRICT coeffs, b return bw_gain_process1(&coeffs->gain_coeffs, y); } -static inline void bw_dist_process(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_state *BW_RESTRICT state, const float *x, float *y, int n_samples) { +static inline void bw_dist_process(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_state *BW_RESTRICT state, const float *x, float *y, size_t n_samples) { bw_dist_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_dist_update_coeffs_audio(coeffs); y[i] = bw_dist_process1(coeffs, state, x[i]); } } -static inline void bw_dist_process_multi(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) { +static inline void bw_dist_process_multi(bw_dist_coeffs *BW_RESTRICT coeffs, bw_dist_state * const *BW_RESTRICT state, const float * const *x, float **y, size_t n_channels, size_t n_samples) { bw_dist_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_dist_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_dist_process1(coeffs, state[j], x[j][i]); } } @@ -293,6 +300,102 @@ static inline void bw_dist_set_volume(bw_dist_coeffs *BW_RESTRICT coeffs, float } #ifdef __cplusplus +} + +#include + +namespace Brickworks { + +/*** Public C++ API ***/ + +/*! api_cpp {{{ + * ##### Brickworks::Dist + * ```>>> */ +template +class Dist { +public: + Dist(); + + 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 setDistortion(float value); + void setTone(float value); + void setVolume(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_dist_coeffs coeffs; + bw_dist_state states[N_CHANNELS]; + bw_dist_state *statesP[N_CHANNELS]; +}; + +template +inline Dist::Dist() { + bw_dist_init(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + statesP[i] = states + i; +} + +template +inline void Dist::setSampleRate(float sampleRate) { + bw_dist_set_sample_rate(&coeffs, sampleRate); +} + +template +inline void Dist::reset() { + bw_dist_reset_coeffs(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + bw_dist_reset_state(&coeffs, states + i); +} + +template +inline void Dist::process( + const float * const *x, + float **y, + size_t nSamples) { + bw_dist_process_multi(&coeffs, statesP, x, y, N_CHANNELS, nSamples); +} + +template +inline void Dist::process( + std::array x, + std::array y, + size_t nSamples) { + process(x.data(), y.data(), nSamples); +} + +template +inline void Dist::setDistortion(float value) { + bw_dist_set_distortion(&coeffs, value); +} + +template +inline void Dist::setTone(float value) { + bw_dist_set_tone(&coeffs, value); +} + +template +inline void Dist::setVolume(float value) { + bw_dist_set_volume(&coeffs, value); +} + } #endif diff --git a/include/bw_drive.h b/include/bw_drive.h index 7312e6d..e5cc704 100644 --- a/include/bw_drive.h +++ b/include/bw_drive.h @@ -33,8 +33,15 @@ *
          *
        • Version 1.0.0: *
            - *
          • Now using size_t instead of - * BW_SIZE_T.
          • + *
          • bw_drive_process() and + * bw_drive_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: @@ -51,8 +58,8 @@ * }}} */ -#ifndef _BW_DRIVE_H -#define _BW_DRIVE_H +#ifndef BW_DRIVE_H +#define BW_DRIVE_H #include @@ -63,13 +70,13 @@ extern "C" { /*! api {{{ * #### bw_drive_coeffs * ```>>> */ -typedef struct _bw_drive_coeffs bw_drive_coeffs; +typedef struct bw_drive_coeffs bw_drive_coeffs; /*! <<<``` * Coefficients and related. * * #### bw_drive_state * ```>>> */ -typedef struct _bw_drive_state bw_drive_state; +typedef struct bw_drive_state bw_drive_state; /*! <<<``` * Internal state and related. * @@ -118,7 +125,7 @@ static inline float bw_drive_process1(const bw_drive_coeffs *BW_RESTRICT coeffs, * * #### bw_drive_process() * ```>>> */ -static inline void bw_drive_process(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_state *BW_RESTRICT state, const float *x, float *y, int n_samples); +static inline void bw_drive_process(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_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 @@ -126,7 +133,7 @@ static inline void bw_drive_process(bw_drive_coeffs *BW_RESTRICT coeffs, bw_driv * * #### bw_drive_process_multi() * ```>>> */ -static inline void bw_drive_process_multi(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples); +static inline void bw_drive_process_multi(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_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 @@ -178,7 +185,7 @@ static inline void bw_drive_set_volume(bw_drive_coeffs *BW_RESTRICT coeffs, floa extern "C" { #endif -struct _bw_drive_coeffs { +struct bw_drive_coeffs { // Sub-components bw_svf_coeffs hp2_coeffs; bw_peak_coeffs peak_coeffs; @@ -187,7 +194,7 @@ struct _bw_drive_coeffs { bw_gain_coeffs gain_coeffs; }; -struct _bw_drive_state { +struct bw_drive_state { // Sub-components bw_svf_state hp2_state; bw_peak_state peak_state; @@ -252,19 +259,19 @@ static inline float bw_drive_process1(const bw_drive_coeffs *BW_RESTRICT coeffs, return bw_gain_process1(&coeffs->gain_coeffs, v_lp); } -static inline void bw_drive_process(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_state *BW_RESTRICT state, const float *x, float *y, int n_samples) { +static inline void bw_drive_process(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_state *BW_RESTRICT state, const float *x, float *y, size_t n_samples) { bw_drive_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_drive_update_coeffs_audio(coeffs); y[i] = bw_drive_process1(coeffs, state, x[i]); } } -static inline void bw_drive_process_multi(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int n_samples) { +static inline void bw_drive_process_multi(bw_drive_coeffs *BW_RESTRICT coeffs, bw_drive_state * const *BW_RESTRICT state, const float * const *x, float **y, size_t n_channels, size_t n_samples) { bw_drive_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_drive_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_drive_process1(coeffs, state[j], x[j][i]); } } @@ -282,6 +289,102 @@ static inline void bw_drive_set_volume(bw_drive_coeffs *BW_RESTRICT coeffs, floa } #ifdef __cplusplus +} + +#include + +namespace Brickworks { + +/*** Public C++ API ***/ + +/*! api_cpp {{{ + * ##### Brickworks::Drive + * ```>>> */ +template +class Drive { +public: + Drive(); + + 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 setDrive(float value); + void setTone(float value); + void setVolume(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_drive_coeffs coeffs; + bw_drive_state states[N_CHANNELS]; + bw_drive_state *statesP[N_CHANNELS]; +}; + +template +inline Drive::Drive() { + bw_drive_init(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + statesP[i] = states + i; +} + +template +inline void Drive::setSampleRate(float sampleRate) { + bw_drive_set_sample_rate(&coeffs, sampleRate); +} + +template +inline void Drive::reset() { + bw_drive_reset_coeffs(&coeffs); + for (size_t i = 0; i < N_CHANNELS; i++) + bw_drive_reset_state(&coeffs, states + i); +} + +template +inline void Drive::process( + const float * const *x, + float **y, + size_t nSamples) { + bw_drive_process_multi(&coeffs, statesP, x, y, N_CHANNELS, nSamples); +} + +template +inline void Drive::process( + std::array x, + std::array y, + size_t nSamples) { + process(x.data(), y.data(), nSamples); +} + +template +inline void Drive::setDrive(float value) { + bw_drive_set_drive(&coeffs, value); +} + +template +inline void Drive::setTone(float value) { + bw_drive_set_tone(&coeffs, value); +} + +template +inline void Drive::setVolume(float value) { + bw_drive_set_volume(&coeffs, value); +} + } #endif diff --git a/include/bw_drywet.h b/include/bw_drywet.h index f0b4e05..39067f6 100644 --- a/include/bw_drywet.h +++ b/include/bw_drywet.h @@ -29,8 +29,15 @@ *
            *
          • Version 1.0.0: *
              - *
            • Now using size_t instead of - * BW_SIZE_T.
            • + *
            • bw_drywet_process() and + * bw_drywet_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: @@ -47,8 +54,8 @@ * }}} */ -#ifndef _BW_DRYWET_H -#define _BW_DRYWET_H +#ifndef BW_DRYWET_H +#define BW_DRYWET_H #include @@ -59,7 +66,7 @@ extern "C" { /*! api {{{ * #### bw_drywet_coeffs * ```>>> */ -typedef struct _bw_drywet_coeffs bw_drywet_coeffs; +typedef struct bw_drywet_coeffs bw_drywet_coeffs; /*! <<<``` * Coefficients and related. * @@ -102,7 +109,7 @@ static inline float bw_drywet_process1(const bw_drywet_coeffs *BW_RESTRICT coeff * * #### bw_drywet_process() * ```>>> */ -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); +static inline void bw_drywet_process(bw_drywet_coeffs *BW_RESTRICT coeffs, const float *x_dry, const float *x_wet, float *y, size_t n_samples); /*! <<<``` * Processes the first `n_samples` of the dry input buffer `x_dry` and of the * wet input buffer `x_wet` and fills the first `n_samples` of the output @@ -110,7 +117,7 @@ static inline void bw_drywet_process(bw_drywet_coeffs *BW_RESTRICT coeffs, const * * #### bw_drywet_process_multi() * ```>>> */ -static inline void bw_drywet_process_multi(bw_drywet_coeffs *BW_RESTRICT coeffs, const float **x_dry, const float **x_wet, float **y, int n_channels, int n_samples); +static inline void bw_drywet_process_multi(bw_drywet_coeffs *BW_RESTRICT coeffs, const float * const *x_dry, const float * const *x_wet, float **y, size_t n_channels, size_t n_samples); /*! <<<``` * Processes the first `n_samples` of the `n_channels` dry input buffers * `x_dry` and of the `n_channels` wet input buffers `x_wet`, and fills the @@ -149,7 +156,7 @@ static inline void bw_drywet_set_smooth_tau(bw_drywet_coeffs *BW_RESTRICT coeffs extern "C" { #endif -struct _bw_drywet_coeffs { +struct bw_drywet_coeffs { // Sub-components bw_gain_coeffs gain_coeffs; }; @@ -178,19 +185,19 @@ static inline float bw_drywet_process1(const bw_drywet_coeffs *BW_RESTRICT coeff 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) { +static inline void bw_drywet_process(bw_drywet_coeffs *BW_RESTRICT coeffs, const float *x_dry, const float *x_wet, float *y, size_t n_samples) { bw_drywet_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_drywet_update_coeffs_audio(coeffs); y[i] = bw_drywet_process1(coeffs, x_dry[i], x_wet[i]); } } -static inline void bw_drywet_process_multi(bw_drywet_coeffs *BW_RESTRICT coeffs, const float **x_dry, const float **x_wet, float **y, int n_channels, int n_samples) { +static inline void bw_drywet_process_multi(bw_drywet_coeffs *BW_RESTRICT coeffs, const float * const *x_dry, const float * const *x_wet, float **y, size_t n_channels, size_t n_samples) { bw_drywet_update_coeffs_ctrl(coeffs); - for (int i = 0; i < n_samples; i++) { + for (size_t i = 0; i < n_samples; i++) { bw_drywet_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_drywet_process1(coeffs, x_dry[j][i], x_wet[j][i]); } } @@ -204,6 +211,94 @@ static inline void bw_drywet_set_smooth_tau(bw_drywet_coeffs *BW_RESTRICT coeffs } #ifdef __cplusplus +} + +#include + +namespace Brickworks { + +/*** Public C++ API ***/ + +/*! api_cpp {{{ + * ##### Brickworks::DryWet + * ```>>> */ +template +class DryWet { +public: + DryWet(); + + void setSampleRate(float sampleRate); + void reset(); + void process( + const float * const *x_dry, + const float * const *x_wet, + float **y, + size_t nSamples); + void process( + std::array x_dry, + std::array x_wet, + std::array y, + size_t nSamples); + + void setWet(float value); + void setSmoothTau(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_drywet_coeffs coeffs; +}; + +template +inline DryWet::DryWet() { + bw_drywet_init(&coeffs); +} + +template +inline void DryWet::setSampleRate(float sampleRate) { + bw_drywet_set_sample_rate(&coeffs, sampleRate); +} + +template +inline void DryWet::reset() { + bw_drywet_reset_coeffs(&coeffs); +} + +template +inline void DryWet::process( + const float * const *x_dry, + const float * const *x_wet, + float **y, + size_t nSamples) { + bw_drywet_process_multi(&coeffs, x_dry, x_wet, y, N_CHANNELS, nSamples); +} + +template +inline void DryWet::process( + std::array x_dry, + std::array x_wet, + std::array y, + size_t nSamples) { + process(x_dry.data(), x_wet.data(), y.data(), nSamples); +} + +template +inline void DryWet::setWet(float value) { + bw_drywet_set_wet(&coeffs, value); +} + +template +inline void DryWet::setSmoothTau(float value) { + bw_drywet_set_smooth_tau(&coeffs, value); +} + } #endif diff --git a/include/bwpp_delay.h b/include/bwpp_delay.h deleted file mode 100644 index db7f0e5..0000000 --- a/include/bwpp_delay.h +++ /dev/null @@ -1,131 +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_DELAY_H -#define BWPP_DELAY_H - -#include -#include - -namespace Brickworks { - -/*! api {{{ - * ##### Brickworks::Delay - * ```>>> */ -template -class Delay { -public: - Delay(float maxDelay = 1.f); - ~Delay(); - - void setSampleRate(float sampleRate); - void reset(); - void process( - std::array x, - std::array y, - int nSamples); - - float read(size_t channel, size_t di, float df); - void write(size_t channel, float x); - - void setDelay(float value); - - size_t getLength(); -/*! <<<... - * } - * ``` - * }}} */ - -/*** 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_delay_coeffs coeffs; - bw_delay_state states[N_CHANNELS]; - bw_delay_state *statesP[N_CHANNELS]; - void *mem; -}; - -template -inline Delay::Delay(float maxDelay) { - bw_delay_init(&coeffs, maxDelay); - for (size_t i = 0; i < N_CHANNELS; i++) - statesP[i] = states + i; - mem = nullptr; -} - -template -inline Delay::~Delay() { - if (mem != nullptr) - operator delete(mem); -} - -template -inline void Delay::setSampleRate(float sampleRate) { - bw_delay_set_sample_rate(&coeffs, sampleRate); - size_t req = bw_delay_mem_req(&coeffs); - if (mem != nullptr) - operator delete(mem); - mem = operator new(req * N_CHANNELS); - void *m = mem; - for (size_t i = 0; i < N_CHANNELS; i++, m = static_cast(m) + req) - bw_delay_mem_set(&coeffs, states + i, m); -} - -template -inline void Delay::reset() { - bw_delay_reset_coeffs(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - bw_delay_reset_state(&coeffs, states + i); -} - -template -inline void Delay::process( - std::array x, - std::array y, - int nSamples) { - bw_delay_process_multi(&coeffs, statesP, x.data(), y.data(), N_CHANNELS, nSamples); -} - -template -inline float Delay::read(size_t channel, size_t di, float df) { - return bw_delay_read(&coeffs, states + channel, di, df); -} - -template -inline void Delay::write(size_t channel, float x) { - bw_delay_write(&coeffs, states + channel, x); -} - -template -inline void Delay::setDelay(float value) { - bw_delay_set_delay(&coeffs, value); -} - -template -inline size_t Delay::getLength() { - return bw_delay_get_length(&coeffs); -} - -} - -#endif diff --git a/include/bwpp_dist.h b/include/bwpp_dist.h deleted file mode 100644 index e4bc8f9..0000000 --- a/include/bwpp_dist.h +++ /dev/null @@ -1,107 +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_DIST_H -#define BWPP_DIST_H - -#include -#include - -namespace Brickworks { - -/*! api {{{ - * ##### Brickworks::Dist - * ```>>> */ -template -class Dist { -public: - Dist(); - - void setSampleRate(float sampleRate); - void reset(); - void process( - std::array x, - std::array y, - int nSamples); - - void setDistortion(float value); - void setTone(float value); - void setVolume(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_dist_coeffs coeffs; - bw_dist_state states[N_CHANNELS]; - bw_dist_state *statesP[N_CHANNELS]; -}; - -template -inline Dist::Dist() { - bw_dist_init(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - statesP[i] = states + i; -} - -template -inline void Dist::setSampleRate(float sampleRate) { - bw_dist_set_sample_rate(&coeffs, sampleRate); -} - -template -inline void Dist::reset() { - bw_dist_reset_coeffs(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - bw_dist_reset_state(&coeffs, states + i); -} - -template -inline void Dist::process( - std::array x, - std::array y, - int nSamples) { - bw_dist_process_multi(&coeffs, statesP, x.data(), y.data(), N_CHANNELS, nSamples); -} - -template -inline void Dist::setDistortion(float value) { - bw_dist_set_distortion(&coeffs, value); -} - -template -inline void Dist::setTone(float value) { - bw_dist_set_tone(&coeffs, value); -} - -template -inline void Dist::setVolume(float value) { - bw_dist_set_volume(&coeffs, value); -} - -} - -#endif diff --git a/include/bwpp_drive.h b/include/bwpp_drive.h deleted file mode 100644 index 450e4b4..0000000 --- a/include/bwpp_drive.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Brickworks - * - * Copyright (C) 2023 Orastron Srl unipersonale - * - * Brickworks is free software: you can redriveribute 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 driveributed 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_DRIVE_H -#define BWPP_DRIVE_H - -#include -#include - -namespace Brickworks { - -/*! api {{{ - * ##### Brickworks::Drive - * ```>>> */ -template -class Drive { -public: - Drive(); - - void setSampleRate(float sampleRate); - void reset(); - void process( - std::array x, - std::array y, - int nSamples); - - void setDrive(float value); - void setTone(float value); - void setVolume(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_drive_coeffs coeffs; - bw_drive_state states[N_CHANNELS]; - bw_drive_state *statesP[N_CHANNELS]; -}; - -template -inline Drive::Drive() { - bw_drive_init(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - statesP[i] = states + i; -} - -template -inline void Drive::setSampleRate(float sampleRate) { - bw_drive_set_sample_rate(&coeffs, sampleRate); -} - -template -inline void Drive::reset() { - bw_drive_reset_coeffs(&coeffs); - for (size_t i = 0; i < N_CHANNELS; i++) - bw_drive_reset_state(&coeffs, states + i); -} - -template -inline void Drive::process( - std::array x, - std::array y, - int nSamples) { - bw_drive_process_multi(&coeffs, statesP, x.data(), y.data(), N_CHANNELS, nSamples); -} - -template -inline void Drive::setDrive(float value) { - bw_drive_set_drive(&coeffs, value); -} - -template -inline void Drive::setTone(float value) { - bw_drive_set_tone(&coeffs, value); -} - -template -inline void Drive::setVolume(float value) { - bw_drive_set_volume(&coeffs, value); -} - -} - -#endif diff --git a/include/bwpp_drywet.h b/include/bwpp_drywet.h deleted file mode 100644 index 11dc58b..0000000 --- a/include/bwpp_drywet.h +++ /dev/null @@ -1,97 +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_DRYWET_H -#define BWPP_DRYWET_H - -#include -#include - -namespace Brickworks { - -/*! api {{{ - * ##### Brickworks::DryWet - * ```>>> */ -template -class DryWet { -public: - DryWet(); - - void setSampleRate(float sampleRate); - void reset(); - void process( - std::array x_dry, - std::array x_wet, - std::array y, - int nSamples); - - void setWet(float value); - void setSmoothTau(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_drywet_coeffs coeffs; -}; - -template -inline DryWet::DryWet() { - bw_drywet_init(&coeffs); -} - -template -inline void DryWet::setSampleRate(float sampleRate) { - bw_drywet_set_sample_rate(&coeffs, sampleRate); -} - -template -inline void DryWet::reset() { - bw_drywet_reset_coeffs(&coeffs); -} - -template -inline void DryWet::process( - std::array x_dry, - std::array x_wet, - std::array y, - int nSamples) { - bw_drywet_process_multi(&coeffs, x_dry.data(), x_wet.data(), y.data(), N_CHANNELS, nSamples); -} - -template -inline void DryWet::setWet(float value) { - bw_drywet_set_wet(&coeffs, value); -} - -template -inline void DryWet::setSmoothTau(float value) { - bw_drywet_set_smooth_tau(&coeffs, value); -} - -} - -#endif