refactored DSP modules APIs to avoid dynamic memory allocations

This commit is contained in:
Stefano D'Angelo 2022-11-19 02:25:38 +01:00
parent 61d0c690e9
commit 0402576e84
29 changed files with 593 additions and 792 deletions

7
ChangeLog Normal file
View File

@ -0,0 +1,7 @@
0.2.0
-----
Refactored API of DSP modules to avoid dynamic memory allocation.
0.1.0
-----
First release.

View File

@ -51,48 +51,36 @@ bw_example_fx bw_example_fx_new() {
if (instance == NULL) if (instance == NULL)
return NULL; return NULL;
instance->svf = bw_svf_new(); bw_svf_init(&instance->svf);
if (instance->svf == NULL) { bw_env_follow_init(&instance->env_follow);
BW_FREE(instance);
return NULL;
}
instance->env_follow = bw_env_follow_new(); bw_one_pole_set_cutoff_down(bw_env_follow_get_one_pole(&instance->env_follow), 1.f);
if (instance->env_follow == NULL) {
bw_svf_free(instance->svf);
BW_FREE(instance);
return NULL;
}
bw_one_pole_set_cutoff_down(bw_env_follow_get_one_pole(instance->env_follow), 1.f);
return instance; return instance;
} }
void bw_example_fx_free(bw_example_fx instance) { void bw_example_fx_free(bw_example_fx instance) {
bw_env_follow_free(instance->env_follow);
bw_svf_free(instance->svf);
BW_FREE(instance); BW_FREE(instance);
} }
void bw_example_fx_set_sample_rate(bw_example_fx instance, float sample_rate) { void bw_example_fx_set_sample_rate(bw_example_fx instance, float sample_rate) {
bw_svf_set_sample_rate(instance->svf, sample_rate); bw_svf_set_sample_rate(&instance->svf, sample_rate);
bw_env_follow_set_sample_rate(instance->env_follow, sample_rate); bw_env_follow_set_sample_rate(&instance->env_follow, sample_rate);
} }
void bw_example_fx_reset(bw_example_fx instance) { void bw_example_fx_reset(bw_example_fx instance) {
bw_svf_reset(instance->svf); bw_svf_reset(&instance->svf);
bw_env_follow_reset(instance->env_follow); bw_env_follow_reset(&instance->env_follow);
} }
void bw_example_fx_process(bw_example_fx instance, const float** x, float** y, int n_samples) { void bw_example_fx_process(bw_example_fx instance, const float** x, float** y, int n_samples) {
float a[n_samples]; float a[n_samples];
bw_svf_process(instance->svf, x[0], y[0], NULL, NULL, n_samples); bw_svf_process(&instance->svf, x[0], y[0], NULL, NULL, n_samples);
for (int i = 0; i < n_samples; i += BUFFER_SIZE) { for (int i = 0; i < n_samples; i += BUFFER_SIZE) {
const uint32_t n = bw_minu32(n_samples - i, BUFFER_SIZE); const uint32_t n = bw_minu32(n_samples - i, BUFFER_SIZE);
bw_env_follow_process(instance->env_follow, y[0] + i, instance->buf, n); bw_env_follow_process(&instance->env_follow, y[0] + i, instance->buf, n);
instance->level = instance->buf[i + n - 1]; instance->level = instance->buf[i + n - 1];
} }
} }
@ -100,10 +88,10 @@ void bw_example_fx_process(bw_example_fx instance, const float** x, float** y, i
void bw_example_fx_set_parameter(bw_example_fx instance, int index, float value) { void bw_example_fx_set_parameter(bw_example_fx instance, int index, float value) {
switch (index) { switch (index) {
case p_cutoff: case p_cutoff:
bw_svf_set_cutoff(instance->svf, (20e3f - 20.f) * value * value * value + 20.f); bw_svf_set_cutoff(&instance->svf, (20e3f - 20.f) * value * value * value + 20.f);
break; break;
case p_Q: case p_Q:
bw_svf_set_Q(instance->svf, 0.5f + 9.5f * value); bw_svf_set_Q(&instance->svf, 0.5f + 9.5f * value);
break; break;
} }
} }

View File

@ -50,7 +50,7 @@ struct config_parameter {
#define COMPANY_MAILTO "mailto:info@orastron.com" #define COMPANY_MAILTO "mailto:info@orastron.com"
#define PLUGIN_NAME "bw_example_fx" #define PLUGIN_NAME "bw_example_fx"
#define PLUGIN_VERSION "0.1.0" #define PLUGIN_VERSION "0.2.0"
#define NUM_BUSES_IN 1 #define NUM_BUSES_IN 1
#define NUM_BUSES_OUT 1 #define NUM_BUSES_OUT 1

View File

@ -48,7 +48,7 @@ struct _bw_example_synth {
// Sub-components // Sub-components
bw_phase_gen phase_gen; bw_phase_gen phase_gen;
bw_osc_pulse osc_pulse; bw_osc_pulse osc_pulse;
bw_osc_filt osc_filt; bw_osc_filt osc_filt;
bw_svf svf; bw_svf svf;
bw_env_gen env_gen; bw_env_gen env_gen;
bw_vol vol; bw_vol vol;
@ -70,108 +70,65 @@ bw_example_synth bw_example_synth_new() {
if (instance == NULL) if (instance == NULL)
return NULL; return NULL;
instance->phase_gen = bw_phase_gen_new(); bw_phase_gen_init(&instance->phase_gen);
if (instance->phase_gen == NULL) bw_osc_pulse_init(&instance->osc_pulse);
goto err_phase_gen; bw_osc_filt_init(&instance->osc_filt);
bw_svf_init(&instance->svf);
bw_env_gen_init(&instance->env_gen);
bw_vol_init(&instance->vol);
bw_env_follow_init(&instance->env_follow);
instance->osc_pulse = bw_osc_pulse_new(); bw_osc_pulse_set_antialiasing(&instance->osc_pulse, 1);
if (instance->osc_pulse == NULL) bw_one_pole_set_cutoff_down(bw_env_follow_get_one_pole(&instance->env_follow), 1.f);
goto err_osc_pulse;
instance->osc_filt = bw_osc_filt_new();
if (instance->osc_filt == NULL)
goto err_osc_filt;
instance->svf = bw_svf_new();
if (instance->svf == NULL)
goto err_svf;
instance->env_gen = bw_env_gen_new();
if (instance->env_gen == NULL)
goto err_env_gen;
instance->vol = bw_vol_new();
if (instance->vol == NULL)
goto err_vol;
instance->env_follow = bw_env_follow_new();
if (instance->env_follow == NULL)
goto err_env_follow;
bw_osc_pulse_set_antialiasing(instance->osc_pulse, 1);
bw_one_pole_set_cutoff_down(bw_env_follow_get_one_pole(instance->env_follow), 1.f);
return instance; return instance;
err_env_follow:
bw_vol_free(instance->vol);
err_vol:
bw_env_gen_free(instance->env_gen);
err_env_gen:
bw_svf_free(instance->svf);
err_svf:
bw_osc_filt_free(instance->osc_filt);
err_osc_filt:
bw_osc_pulse_free(instance->osc_pulse);
err_osc_pulse:
bw_phase_gen_free(instance->phase_gen);
err_phase_gen:
BW_FREE(instance);
return NULL;
} }
void bw_example_synth_free(bw_example_synth instance) { void bw_example_synth_free(bw_example_synth instance) {
bw_env_follow_free(instance->env_follow);
bw_vol_free(instance->vol);
bw_env_gen_free(instance->env_gen);
bw_svf_free(instance->svf);
bw_osc_filt_free(instance->osc_filt);
bw_osc_pulse_free(instance->osc_pulse);
bw_phase_gen_free(instance->phase_gen);
BW_FREE(instance); BW_FREE(instance);
} }
void bw_example_synth_set_sample_rate(bw_example_synth instance, float sample_rate) { void bw_example_synth_set_sample_rate(bw_example_synth instance, float sample_rate) {
bw_phase_gen_set_sample_rate(instance->phase_gen, sample_rate); bw_phase_gen_set_sample_rate(&instance->phase_gen, sample_rate);
bw_osc_pulse_set_sample_rate(instance->osc_pulse, sample_rate); bw_osc_pulse_set_sample_rate(&instance->osc_pulse, sample_rate);
bw_svf_set_sample_rate(instance->svf, sample_rate); bw_svf_set_sample_rate(&instance->svf, sample_rate);
bw_env_gen_set_sample_rate(instance->env_gen, sample_rate); bw_env_gen_set_sample_rate(&instance->env_gen, sample_rate);
bw_vol_set_sample_rate(instance->vol, sample_rate); bw_vol_set_sample_rate(&instance->vol, sample_rate);
bw_env_follow_set_sample_rate(instance->env_follow, sample_rate); bw_env_follow_set_sample_rate(&instance->env_follow, sample_rate);
} }
void bw_example_synth_reset(bw_example_synth instance) { void bw_example_synth_reset(bw_example_synth instance) {
bw_phase_gen_reset(instance->phase_gen); bw_phase_gen_reset(&instance->phase_gen);
bw_osc_pulse_reset(instance->osc_pulse); bw_osc_pulse_reset(&instance->osc_pulse);
bw_osc_filt_reset(instance->osc_filt); bw_osc_filt_reset(&instance->osc_filt);
bw_svf_reset(instance->svf); bw_svf_reset(&instance->svf);
bw_env_gen_reset(instance->env_gen); bw_env_gen_reset(&instance->env_gen);
bw_vol_reset(instance->vol); bw_vol_reset(&instance->vol);
bw_env_follow_reset(instance->env_follow); bw_env_follow_reset(&instance->env_follow);
instance->note = -1; instance->note = -1;
} }
void bw_example_synth_process(bw_example_synth instance, const float** x, float** y, int n_samples) { void bw_example_synth_process(bw_example_synth instance, const float** x, float** y, int n_samples) {
// TODO: I was too lazy to keep track of master tune and note and only update when needed, could be improved // TODO: I was too lazy to keep track of master tune and note and only update when needed, could be improved
if (instance->note != -1) { if (instance->note != -1) {
bw_phase_gen_set_frequency(instance->phase_gen, bw_phase_gen_set_frequency(&instance->phase_gen,
440.f * bw_pow2f_3(8.333333333333333e-2f * ((instance->note - 69) + 2.f * instance->params[p_master_tune] - 1.f))); 440.f * bw_pow2f_3(8.333333333333333e-2f * ((instance->note - 69) + 2.f * instance->params[p_master_tune] - 1.f)));
bw_env_gen_set_gate(instance->env_gen, 1); bw_env_gen_set_gate(&instance->env_gen, 1);
} else } else
bw_env_gen_set_gate(instance->env_gen, 0); bw_env_gen_set_gate(&instance->env_gen, 0);
for (int i = 0; i < n_samples; i += BUFFER_SIZE) { for (int i = 0; i < n_samples; i += BUFFER_SIZE) {
float *out = y[0] + i; float *out = y[0] + i;
const uint32_t n = bw_minu32(n_samples - i, BUFFER_SIZE); const uint32_t n = bw_minu32(n_samples - i, BUFFER_SIZE);
bw_phase_gen_process(instance->phase_gen, NULL, out, instance->buf, n); bw_phase_gen_process(&instance->phase_gen, NULL, out, instance->buf, n);
bw_osc_pulse_process(instance->osc_pulse, out, instance->buf, out, n); bw_osc_pulse_process(&instance->osc_pulse, out, instance->buf, out, n);
bw_osc_filt_process(instance->osc_filt, out, out, n); bw_osc_filt_process(&instance->osc_filt, out, out, n);
bw_svf_process(instance->svf, out, out, NULL, NULL, n); bw_svf_process(&instance->svf, out, out, NULL, NULL, n);
bw_env_gen_process(instance->env_gen, instance->buf, n); bw_env_gen_process(&instance->env_gen, instance->buf, n);
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
out[j] *= instance->buf[j]; out[j] *= instance->buf[j];
bw_vol_process(instance->vol, (const float **)&out, &out, 1, n); bw_vol_process(&instance->vol, (const float **)&out, &out, 1, n);
bw_env_follow_process(instance->env_follow, out, instance->buf, n); bw_env_follow_process(&instance->env_follow, out, instance->buf, n);
instance->level = instance->buf[i + n - 1]; instance->level = instance->buf[i + n - 1];
} }
} }
@ -179,34 +136,34 @@ void bw_example_synth_process(bw_example_synth instance, const float** x, float*
void bw_example_synth_set_parameter(bw_example_synth instance, int index, float value) { void bw_example_synth_set_parameter(bw_example_synth instance, int index, float value) {
switch (index) { switch (index) {
case p_volume: case p_volume:
bw_vol_set_volume(instance->vol, value); bw_vol_set_volume(&instance->vol, value);
break; break;
case p_master_tune: case p_master_tune:
instance->params[p_master_tune] = value; instance->params[p_master_tune] = value;
break; break;
case p_portamento: case p_portamento:
bw_phase_gen_set_portamento_tau(instance->phase_gen, value); bw_phase_gen_set_portamento_tau(&instance->phase_gen, value);
break; break;
case p_pulse_width: case p_pulse_width:
bw_osc_pulse_set_pulse_width(instance->osc_pulse, value); bw_osc_pulse_set_pulse_width(&instance->osc_pulse, value);
break; break;
case p_cutoff: case p_cutoff:
bw_svf_set_cutoff(instance->svf, 20.f + (20e3f - 20.f) * value * value * value); bw_svf_set_cutoff(&instance->svf, 20.f + (20e3f - 20.f) * value * value * value);
break; break;
case p_Q: case p_Q:
bw_svf_set_Q(instance->svf, 0.5f + 9.5f * value); bw_svf_set_Q(&instance->svf, 0.5f + 9.5f * value);
break; break;
case p_attack: case p_attack:
bw_env_gen_set_attack(instance->env_gen, value); bw_env_gen_set_attack(&instance->env_gen, value);
break; break;
case p_decay: case p_decay:
bw_env_gen_set_decay(instance->env_gen, value); bw_env_gen_set_decay(&instance->env_gen, value);
break; break;
case p_sustain: case p_sustain:
bw_env_gen_set_sustain(instance->env_gen, value); bw_env_gen_set_sustain(&instance->env_gen, value);
break; break;
case p_release: case p_release:
bw_env_gen_set_release(instance->env_gen, value); bw_env_gen_set_release(&instance->env_gen, value);
break; break;
} }
} }

View File

@ -50,7 +50,7 @@ struct config_parameter {
#define COMPANY_MAILTO "mailto:info@orastron.com" #define COMPANY_MAILTO "mailto:info@orastron.com"
#define PLUGIN_NAME "bw_example_synth" #define PLUGIN_NAME "bw_example_synth"
#define PLUGIN_VERSION "0.1.0" #define PLUGIN_VERSION "0.2.0"
#define NUM_BUSES_IN 0 #define NUM_BUSES_IN 0
#define NUM_BUSES_OUT 1 #define NUM_BUSES_OUT 1

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_math bw_one_pole }}} * requires {{{ bw_config bw_common bw_math bw_one_pole }}}
* description {{{ * description {{{
* Envelope follower made of a full-wave rectifier followed by * Envelope follower made of a full-wave rectifier followed by
@ -30,6 +30,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -51,34 +56,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_env_follow * #### bw_env_follow
* ```>>> */ * ```>>> */
typedef struct _bw_env_follow *bw_env_follow; typedef struct _bw_env_follow bw_env_follow;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_env_follow_new() * #### bw_env_follow_init()
* ```>>> */ * ```>>> */
bw_env_follow bw_env_follow_new(); void bw_env_follow_init(bw_env_follow *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_env_follow_free()
* ```>>> */
void bw_env_follow_free(bw_env_follow instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_env_follow_set_sample_rate() * #### bw_env_follow_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_env_follow_set_sample_rate(bw_env_follow instance, float sample_rate); void bw_env_follow_set_sample_rate(bw_env_follow *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -86,7 +80,7 @@ void bw_env_follow_set_sample_rate(bw_env_follow instance, float sample_rate);
/*! ... /*! ...
* #### bw_env_follow_reset() * #### bw_env_follow_reset()
* ```>>> */ * ```>>> */
void bw_env_follow_reset(bw_env_follow instance); void bw_env_follow_reset(bw_env_follow *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -94,7 +88,7 @@ void bw_env_follow_reset(bw_env_follow instance);
/*! ... /*! ...
* #### bw_env_follow_process() * #### bw_env_follow_process()
* ```>>> */ * ```>>> */
void bw_env_follow_process(bw_env_follow instance, const float *x, float *y, int n_samples); void bw_env_follow_process(bw_env_follow *instance, const float *x, float *y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` and fills the corresponding `n_samples` samples in the output * buffer `x` and fills the corresponding `n_samples` samples in the output
@ -104,13 +98,13 @@ void bw_env_follow_process(bw_env_follow instance, const float *x, float *y, int
/*! ... /*! ...
* #### bw_env_follow_get_one_pole() * #### bw_env_follow_get_one_pole()
* ```>>> */ * ```>>> */
bw_one_pole bw_env_follow_get_one_pole(bw_env_follow instance); bw_one_pole *bw_env_follow_get_one_pole(bw_env_follow *instance);
/*! <<<``` /*! <<<```
* Returns the handle to the internal one-pole filter of the given * Returns a pointer to the internal one-pole filter of the given
* `instance`. * `instance`.
* *
* The returned handle must not be used for any other purpose than setting * The returned pointer must not be used for any other purpose than setting
* its parameters. * parameters.
* *
* This is **NOT** a function that gets an output parameter as described in * This is **NOT** a function that gets an output parameter as described in
* the [documentation for DSP modules](api#dsp). * the [documentation for DSP modules](api#dsp).
@ -121,6 +115,14 @@ bw_one_pole bw_env_follow_get_one_pole(bw_env_follow instance);
* [no side effects](api#no-side-effects). * [no side effects](api#no-side-effects).
* }}} */ * }}} */
/* 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_env_follow {
// Sub-components
bw_one_pole one_pole;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}} * requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}}
* description {{{ * description {{{
* Linear ADSR envelope generator. * Linear ADSR envelope generator.
@ -39,6 +39,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -58,34 +63,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_env_gen * #### bw_env_gen
* ```>>> */ * ```>>> */
typedef struct _bw_env_gen *bw_env_gen; typedef struct _bw_env_gen bw_env_gen;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_env_gen_new() * #### bw_env_gen_init()
* ```>>> */ * ```>>> */
bw_env_gen bw_env_gen_new(); void bw_env_gen_init(bw_env_gen *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_env_gen_free()
* ```>>> */
void bw_env_gen_free(bw_env_gen instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_env_gen_set_sample_rate() * #### bw_env_gen_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_env_gen_set_sample_rate(bw_env_gen instance, float sample_rate); void bw_env_gen_set_sample_rate(bw_env_gen *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -93,7 +87,7 @@ void bw_env_gen_set_sample_rate(bw_env_gen instance, float sample_rate);
/*! ... /*! ...
* #### bw_env_gen_reset() * #### bw_env_gen_reset()
* ```>>> */ * ```>>> */
void bw_env_gen_reset(bw_env_gen instance); void bw_env_gen_reset(bw_env_gen *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -101,7 +95,7 @@ void bw_env_gen_reset(bw_env_gen instance);
/*! ... /*! ...
* #### bw_env_gen_process() * #### bw_env_gen_process()
* ```>>> */ * ```>>> */
void bw_env_gen_process(bw_env_gen instance, float* y, int n_samples); void bw_env_gen_process(bw_env_gen *instance, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` generate `n_samples` samples and puts them in * Lets the given `instance` generate `n_samples` samples and puts them in
* the output buffer `y`. * the output buffer `y`.
@ -110,7 +104,7 @@ void bw_env_gen_process(bw_env_gen instance, float* y, int n_samples);
/*! ... /*! ...
* #### bw_env_gen_set_gate() * #### bw_env_gen_set_gate()
* ```>>> */ * ```>>> */
void bw_env_gen_set_gate(bw_env_gen instance, char value); void bw_env_gen_set_gate(bw_env_gen *instance, char value);
/*! <<<``` /*! <<<```
* Sets the input gate to be either off (`0`) or on (non-`0`) for the given * Sets the input gate to be either off (`0`) or on (non-`0`) for the given
* `instance`. * `instance`.
@ -121,7 +115,7 @@ void bw_env_gen_set_gate(bw_env_gen instance, char value);
/*! ... /*! ...
* #### bw_env_gen_set_attack() * #### bw_env_gen_set_attack()
* ```>>> */ * ```>>> */
void bw_env_gen_set_attack(bw_env_gen instance, float value); void bw_env_gen_set_attack(bw_env_gen *instance, float value);
/*! <<<``` /*! <<<```
* Sets the attack time to `value` (s) for the given `instance`. * Sets the attack time to `value` (s) for the given `instance`.
* *
@ -133,7 +127,7 @@ void bw_env_gen_set_attack(bw_env_gen instance, float value);
/*! ... /*! ...
* #### bw_env_gen_set_decay() * #### bw_env_gen_set_decay()
* ```>>> */ * ```>>> */
void bw_env_gen_set_decay(bw_env_gen instance, float value); void bw_env_gen_set_decay(bw_env_gen *instance, float value);
/*! <<<``` /*! <<<```
* Sets the decay time to `value` (s) for the given `instance`. * Sets the decay time to `value` (s) for the given `instance`.
* *
@ -145,7 +139,7 @@ void bw_env_gen_set_decay(bw_env_gen instance, float value);
/*! ... /*! ...
* #### bw_env_gen_set_sustain() * #### bw_env_gen_set_sustain()
* ```>>> */ * ```>>> */
void bw_env_gen_set_sustain(bw_env_gen instance, float value); void bw_env_gen_set_sustain(bw_env_gen *instance, float value);
/*! <<<``` /*! <<<```
* Sets the sustain level to `value` for the given `instance`. * Sets the sustain level to `value` for the given `instance`.
* *
@ -155,7 +149,7 @@ void bw_env_gen_set_sustain(bw_env_gen instance, float value);
/*! ... /*! ...
* #### bw_env_gen_set_release() * #### bw_env_gen_set_release()
* ```>>> */ * ```>>> */
void bw_env_gen_set_release(bw_env_gen instance, float value); void bw_env_gen_set_release(bw_env_gen *instance, float value);
/*! <<<``` /*! <<<```
* Sets the release time to `value` (s) for the given `instance`. * Sets the release time to `value` (s) for the given `instance`.
* *
@ -167,11 +161,46 @@ void bw_env_gen_set_release(bw_env_gen instance, float value);
/*! ... /*! ...
* #### bw_env_gen_get_is_off() * #### bw_env_gen_get_is_off()
* ```>>> */ * ```>>> */
char bw_env_gen_get_is_off(bw_env_gen instance); char bw_env_gen_get_is_off(bw_env_gen *instance);
/*! <<<``` /*! <<<```
* Returns `0` if the given `instance` is in the off state, non-`0` otherwise. * Returns `0` if the given `instance` is in the off state, non-`0` otherwise.
* }}} */ * }}} */
/* WARNING: this enum is not part of the public API. Please, do not use it. */
typedef enum {
_bw_env_gen_state_off,
_bw_env_gen_state_attack,
_bw_env_gen_state_decay,
_bw_env_gen_state_sustain,
_bw_env_gen_state_release
} _bw_env_gen_state;
/* 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_env_gen {
// Coefficients
float T;
float smooth_mA1;
float attack_inc;
float decay_inc;
float release_inc;
// Parameters
char gate;
float attack;
float decay;
float sustain;
float release;
int param_changed;
// State
char first_run;
_bw_env_gen_state state;
float y_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,13 +19,18 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_math bw_rand }}} * requires {{{ bw_config bw_common bw_math bw_rand }}}
* description {{{ * description {{{
* Generator of white noise with uniform distribution. * Generator of white noise with uniform distribution.
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -47,35 +52,24 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_noise_gen * #### bw_noise_gen
* ```>>> */ * ```>>> */
typedef struct _bw_noise_gen *bw_noise_gen; typedef struct _bw_noise_gen bw_noise_gen;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_noise_gen_new() * #### bw_noise_gen_init()
* ```>>> */ * ```>>> */
bw_noise_gen bw_noise_gen_new(uint64_t *state); void bw_noise_gen_init(bw_noise_gen *instance, uint64_t *state);
/*! <<<``` /*! <<<```
* Creates a new instance which uses the given `state` pointer to obtain * Initializes the `instance` object and lets it use the given `state`
* pseudo-random numbers. * pointer to obtain pseudo-random numbers.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_noise_gen_free()
* ```>>> */
void bw_noise_gen_free(bw_noise_gen instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_noise_gen_set_sample_rate() * #### bw_noise_gen_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_noise_gen_set_sample_rate(bw_noise_gen instance, float sample_rate); void bw_noise_gen_set_sample_rate(bw_noise_gen *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` value for the given `instance`. * Sets the `sample_rate` value for the given `instance`.
* >>> */ * >>> */
@ -89,7 +83,7 @@ void bw_noise_gen_set_sample_rate(bw_noise_gen instance, float sample_rate);
/*! ... /*! ...
* #### bw_noise_gen_process() * #### bw_noise_gen_process()
* ```>>> */ * ```>>> */
void bw_noise_gen_process(bw_noise_gen instance, float* y, int n_samples); void bw_noise_gen_process(bw_noise_gen *instance, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` generate `n_samples` samples and puts them in * Lets the given `instance` generate `n_samples` samples and puts them in
* the output buffer `y`. * the output buffer `y`.
@ -98,7 +92,7 @@ void bw_noise_gen_process(bw_noise_gen instance, float* y, int n_samples);
/*! ... /*! ...
* #### bw_noise_gen_set_sample_rate_scaling() * #### bw_noise_gen_set_sample_rate_scaling()
* ```>>> */ * ```>>> */
void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen instance, char value); void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen *instance, char value);
/*! <<<``` /*! <<<```
* Sets whether the output should be scaled (`value` non-`0`) or not (`0`) * Sets whether the output should be scaled (`value` non-`0`) or not (`0`)
* according to the sample rate by the given `instance`. * according to the sample rate by the given `instance`.
@ -111,6 +105,20 @@ void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen instance, char value);
* Default value: `0`. * Default value: `0`.
* }}} */ * }}} */
/* 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_noise_gen {
// Coefficients
float scaling_k;
// Parameters
char sample_rate_scaling;
// State
uint64_t *state;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_math }}} * requires {{{ bw_config bw_common bw_math }}}
* description {{{ * description {{{
* One-pole (6 dB/oct) lowpass filter with unitary DC gain, separate attack * One-pole (6 dB/oct) lowpass filter with unitary DC gain, separate attack
@ -27,6 +27,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -46,9 +51,9 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_one_pole * #### bw_one_pole
* ```>>> */ * ```>>> */
typedef struct _bw_one_pole *bw_one_pole; typedef struct _bw_one_pole bw_one_pole;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
@ -66,28 +71,17 @@ typedef enum {
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_one_pole_new() * #### bw_one_pole_init()
* ```>>> */ * ```>>> */
bw_one_pole bw_one_pole_new(); void bw_one_pole_init(bw_one_pole *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_one_pole_free()
* ```>>> */
void bw_one_pole_free(bw_one_pole instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_one_pole_set_sample_rate() * #### bw_one_pole_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_one_pole_set_sample_rate(bw_one_pole instance, float sample_rate); void bw_one_pole_set_sample_rate(bw_one_pole *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -95,7 +89,7 @@ void bw_one_pole_set_sample_rate(bw_one_pole instance, float sample_rate);
/*! ... /*! ...
* #### bw_one_pole_reset() * #### bw_one_pole_reset()
* ```>>> */ * ```>>> */
void bw_one_pole_reset(bw_one_pole instance); void bw_one_pole_reset(bw_one_pole *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -103,7 +97,7 @@ void bw_one_pole_reset(bw_one_pole instance);
/*! ... /*! ...
* #### bw_one_pole_process() * #### bw_one_pole_process()
* ```>>> */ * ```>>> */
void bw_one_pole_process(bw_one_pole instance, const float* x, float* y, int n_samples); void bw_one_pole_process(bw_one_pole *instance, const float* x, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` and fills the corresponding `n_samples` samples in the output * buffer `x` and fills the corresponding `n_samples` samples in the output
@ -113,7 +107,7 @@ void bw_one_pole_process(bw_one_pole instance, const float* x, float* y, int n_s
/*! ... /*! ...
* #### bw_one_pole_set_init_val() * #### bw_one_pole_set_init_val()
* ```>>> */ * ```>>> */
void bw_one_pole_set_init_val(bw_one_pole instance, float value); void bw_one_pole_set_init_val(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets the initial/quiescent `value` for the given `instance`. * Sets the initial/quiescent `value` for the given `instance`.
* *
@ -127,7 +121,7 @@ void bw_one_pole_set_init_val(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_cutoff() * #### bw_one_pole_set_cutoff()
* ```>>> */ * ```>>> */
void bw_one_pole_set_cutoff(bw_one_pole instance, float value); void bw_one_pole_set_cutoff(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets both the upgoing (attack) and downgoing (decay) cutoff frequency to * Sets both the upgoing (attack) and downgoing (decay) cutoff frequency to
* the given `value` (Hz) for the given `instance`. * the given `value` (Hz) for the given `instance`.
@ -143,7 +137,7 @@ void bw_one_pole_set_cutoff(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_cutoff_up() * #### bw_one_pole_set_cutoff_up()
* ```>>> */ * ```>>> */
void bw_one_pole_set_cutoff_up(bw_one_pole instance, float value); void bw_one_pole_set_cutoff_up(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets the upgoing (attack) cutoff frequency to the given `value` (Hz) for * Sets the upgoing (attack) cutoff frequency to the given `value` (Hz) for
* the given `instance`. * the given `instance`.
@ -157,7 +151,7 @@ void bw_one_pole_set_cutoff_up(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_cutoff_down() * #### bw_one_pole_set_cutoff_down()
* ```>>> */ * ```>>> */
void bw_one_pole_set_cutoff_down(bw_one_pole instance, float value); void bw_one_pole_set_cutoff_down(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets the downgoing (attack) cutoff frequency to the given `value` (Hz) * Sets the downgoing (attack) cutoff frequency to the given `value` (Hz)
* for the given `instance`. * for the given `instance`.
@ -171,7 +165,7 @@ void bw_one_pole_set_cutoff_down(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_tau() * #### bw_one_pole_set_tau()
* ```>>> */ * ```>>> */
void bw_one_pole_set_tau(bw_one_pole instance, float value); void bw_one_pole_set_tau(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets both the upgoing (attack) and downgoing (decay) time constant to the * Sets both the upgoing (attack) and downgoing (decay) time constant to the
* given `value` (s) for the given `instance`. * given `value` (s) for the given `instance`.
@ -187,7 +181,7 @@ void bw_one_pole_set_tau(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_tau_up() * #### bw_one_pole_set_tau_up()
* ```>>> */ * ```>>> */
void bw_one_pole_set_tau_up(bw_one_pole instance, float value); void bw_one_pole_set_tau_up(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets the upgoing (attack) time constant to the given `value` (s) for the * Sets the upgoing (attack) time constant to the given `value` (s) for the
* given `instance`. * given `instance`.
@ -201,7 +195,7 @@ void bw_one_pole_set_tau_up(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_tau_down() * #### bw_one_pole_set_tau_down()
* ```>>> */ * ```>>> */
void bw_one_pole_set_tau_down(bw_one_pole instance, float value); void bw_one_pole_set_tau_down(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets the downgoing (decay) time constant to the given `value` (s) for the * Sets the downgoing (decay) time constant to the given `value` (s) for the
* given `instance`. * given `instance`.
@ -215,7 +209,7 @@ void bw_one_pole_set_tau_down(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_sticky_thresh() * #### bw_one_pole_set_sticky_thresh()
* ```>>> */ * ```>>> */
void bw_one_pole_set_sticky_thresh(bw_one_pole instance, float value); void bw_one_pole_set_sticky_thresh(bw_one_pole *instance, float value);
/*! <<<``` /*! <<<```
* Sets the target-reach threshold specified by `value` for the given * Sets the target-reach threshold specified by `value` for the given
* `instance`. * `instance`.
@ -231,11 +225,36 @@ void bw_one_pole_set_sticky_thresh(bw_one_pole instance, float value);
/*! ... /*! ...
* #### bw_one_pole_set_sticky_mode() * #### bw_one_pole_set_sticky_mode()
* ```>>> */ * ```>>> */
void bw_one_pole_set_sticky_mode(bw_one_pole instance, bw_one_pole_sticky_mode value); void bw_one_pole_set_sticky_mode(bw_one_pole *instance, bw_one_pole_sticky_mode value);
/*! <<<``` /*! <<<```
* Sets the current distance metric for sticky behavior. * Sets the current distance metric for sticky behavior.
* }}} */ * }}} */
/* 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_one_pole {
// Coefficients
float Ttm2pi;
float mA1u;
float mA1d;
float st2;
// Parameters
float init_val;
float cutoff_up;
float cutoff_down;
float sticky_thresh;
bw_one_pole_sticky_mode sticky_mode;
int param_changed;
// State
char first_run;
float x_z1;
float y_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common }}} * requires {{{ bw_config bw_common }}}
* description {{{ * description {{{
* Post-filter to decolorate oscillator waveshapers when antialiasing is on. * Post-filter to decolorate oscillator waveshapers when antialiasing is on.
@ -31,6 +31,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -50,28 +55,17 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_osc_filt * #### bw_osc_filt
* ```>>> */ * ```>>> */
typedef struct _bw_osc_filt *bw_osc_filt; typedef struct _bw_osc_filt bw_osc_filt;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_osc_filt_new() * #### bw_osc_filt_init()
* ```>>> */ * ```>>> */
bw_osc_filt bw_osc_filt_new(); void bw_osc_filt_init(bw_osc_filt *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_osc_filt_free()
* ```>>> */
void bw_osc_filt_free(bw_osc_filt instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
@ -83,7 +77,7 @@ void bw_osc_filt_free(bw_osc_filt instance);
/*! ... /*! ...
* #### bw_osc_filt_reset() * #### bw_osc_filt_reset()
* ```>>> */ * ```>>> */
void bw_osc_filt_reset(bw_osc_filt instance); void bw_osc_filt_reset(bw_osc_filt *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -91,7 +85,7 @@ void bw_osc_filt_reset(bw_osc_filt instance);
/*! ... /*! ...
* #### bw_osc_filt_process() * #### bw_osc_filt_process()
* ```>>> */ * ```>>> */
void bw_osc_filt_process(bw_osc_filt instance, const float *x, float* y, int n_samples); void bw_osc_filt_process(bw_osc_filt *instance, const float *x, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` and fills the corresponding `n_samples` samples in the output * buffer `x` and fills the corresponding `n_samples` samples in the output
@ -101,7 +95,7 @@ void bw_osc_filt_process(bw_osc_filt instance, const float *x, float* y, int n_s
/*! ... /*! ...
* #### bw_osc_filt_set_enabled() * #### bw_osc_filt_set_enabled()
* ```>>> */ * ```>>> */
void bw_osc_filt_set_enabled(bw_osc_filt instance, char value); void bw_osc_filt_set_enabled(bw_osc_filt *instance, char value);
/*! <<<``` /*! <<<```
* Sets whether the filter is enabled (`value` non-`0`) or bypassed (`0`) * Sets whether the filter is enabled (`value` non-`0`) or bypassed (`0`)
* for the given `instance`. * for the given `instance`.
@ -109,6 +103,19 @@ void bw_osc_filt_set_enabled(bw_osc_filt instance, char value);
* Default value: non-`0`. * Default value: non-`0`.
* }}} */ * }}} */
/* 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_osc_filt {
// Parameters
char enabled;
// State
float x_z1;
float y_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}} * requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}}
* description {{{ * description {{{
* Pulse oscillator waveshaper with variable pulse width (actually, duty * Pulse oscillator waveshaper with variable pulse width (actually, duty
@ -27,6 +27,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -46,34 +51,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_osc_pulse * #### bw_osc_pulse
* ```>>> */ * ```>>> */
typedef struct _bw_osc_pulse *bw_osc_pulse; typedef struct _bw_osc_pulse bw_osc_pulse;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_osc_pulse_new() * #### bw_osc_pulse_init()
* ```>>> */ * ```>>> */
bw_osc_pulse bw_osc_pulse_new(); void bw_osc_pulse_init(bw_osc_pulse *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_osc_pulse_free()
* ```>>> */
void bw_osc_pulse_free(bw_osc_pulse instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_osc_pulse_set_sample_rate() * #### bw_osc_pulse_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_osc_pulse_set_sample_rate(bw_osc_pulse instance, float sample_rate); void bw_osc_pulse_set_sample_rate(bw_osc_pulse *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -81,7 +75,7 @@ void bw_osc_pulse_set_sample_rate(bw_osc_pulse instance, float sample_rate);
/*! ... /*! ...
* #### bw_osc_pulse_reset() * #### bw_osc_pulse_reset()
* ```>>> */ * ```>>> */
void bw_osc_pulse_reset(bw_osc_pulse instance); void bw_osc_pulse_reset(bw_osc_pulse *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -89,7 +83,7 @@ void bw_osc_pulse_reset(bw_osc_pulse instance);
/*! ... /*! ...
* #### bw_osc_pulse_process() * #### bw_osc_pulse_process()
* ```>>> */ * ```>>> */
void bw_osc_pulse_process(bw_osc_pulse instance, const float *x, const float *x_phase_inc, float* y, int n_samples); void bw_osc_pulse_process(bw_osc_pulse *instance, const float *x, const float *x_phase_inc, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` containing the normalized phase signal and fills the * buffer `x` containing the normalized phase signal and fills the
@ -102,7 +96,7 @@ void bw_osc_pulse_process(bw_osc_pulse instance, const float *x, const float *x_
/*! ... /*! ...
* #### bw_osc_pulse_set_antialiasing() * #### bw_osc_pulse_set_antialiasing()
* ```>>> */ * ```>>> */
void bw_osc_pulse_set_antialiasing(bw_osc_pulse instance, char value); void bw_osc_pulse_set_antialiasing(bw_osc_pulse *instance, char value);
/*! <<<``` /*! <<<```
* Sets whether the antialiasing is on (`value` non-`0`) or off (`0`) for the * Sets whether the antialiasing is on (`value` non-`0`) or off (`0`) for the
* given `instance`. * given `instance`.
@ -113,7 +107,7 @@ void bw_osc_pulse_set_antialiasing(bw_osc_pulse instance, char value);
/*! ... /*! ...
* #### bw_osc_pulse_set_pulse_width() * #### bw_osc_pulse_set_pulse_width()
* ```>>> */ * ```>>> */
void bw_osc_pulse_set_pulse_width(bw_osc_pulse instance, float value); void bw_osc_pulse_set_pulse_width(bw_osc_pulse *instance, float value);
/*! <<<``` /*! <<<```
* Sets the pulse width (actually, the duty cycle) to `value` (range * Sets the pulse width (actually, the duty cycle) to `value` (range
* [`0.f`, `1.f`]) for the given `instance`. * [`0.f`, `1.f`]) for the given `instance`.
@ -121,6 +115,22 @@ void bw_osc_pulse_set_pulse_width(bw_osc_pulse instance, float value);
* Default value: `0.5f`. * Default value: `0.5f`.
* }}} */ * }}} */
/* 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_osc_pulse {
// Coefficients
float smooth_mA1;
// Parameters
char first_run;
char antialiasing;
float pulse_width;
// State
float pw_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,13 +19,18 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_math }}} * requires {{{ bw_config bw_common bw_math }}}
* description {{{ * description {{{
* Sawtooth oscillator waveshaper with PolyBLEP antialiasing. * Sawtooth oscillator waveshaper with PolyBLEP antialiasing.
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -45,28 +50,17 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_osc_saw * #### bw_osc_saw
* ```>>> */ * ```>>> */
typedef struct _bw_osc_saw *bw_osc_saw; typedef struct _bw_osc_saw bw_osc_saw;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_osc_saw_new() * #### bw_osc_saw_init()
* ```>>> */ * ```>>> */
bw_osc_saw bw_osc_saw_new(); void bw_osc_saw_init(bw_osc_saw *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_osc_saw_free()
* ```>>> */
void bw_osc_saw_free(bw_osc_saw instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
@ -78,7 +72,7 @@ void bw_osc_saw_free(bw_osc_saw instance);
/*! ... /*! ...
* #### bw_osc_saw_process() * #### bw_osc_saw_process()
* ```>>> */ * ```>>> */
void bw_osc_saw_process(bw_osc_saw instance, const float *x, const float *x_phase_inc, float* y, int n_samples); void bw_osc_saw_process(bw_osc_saw *instance, const float *x, const float *x_phase_inc, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` containing the normalized phase signal and fills the * buffer `x` containing the normalized phase signal and fills the
@ -88,7 +82,7 @@ void bw_osc_saw_process(bw_osc_saw instance, const float *x, const float *x_phas
/*! ... /*! ...
* #### bw_osc_saw_set_antialiasing() * #### bw_osc_saw_set_antialiasing()
* ```>>> */ * ```>>> */
void bw_osc_saw_set_antialiasing(bw_osc_saw instance, char value); void bw_osc_saw_set_antialiasing(bw_osc_saw *instance, char value);
/*! <<<``` /*! <<<```
* Sets whether the antialiasing is on (`value` non-`0`) or off (`0`) for the * Sets whether the antialiasing is on (`value` non-`0`) or off (`0`) for the
* given `instance`. * given `instance`.
@ -96,6 +90,14 @@ void bw_osc_saw_set_antialiasing(bw_osc_saw instance, char value);
* Default value: `0`. * Default value: `0`.
* }}} */ * }}} */
/* 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_osc_saw {
// Parameters
char antialiasing;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}} * requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}}
* description {{{ * description {{{
* Triangle oscillator waveshaper with variable slope (increasing time over * Triangle oscillator waveshaper with variable slope (increasing time over
@ -27,6 +27,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -46,34 +51,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_osc_tri * #### bw_osc_tri
* ```>>> */ * ```>>> */
typedef struct _bw_osc_tri *bw_osc_tri; typedef struct _bw_osc_tri bw_osc_tri;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_osc_tri_new() * #### bw_osc_tri_init()
* ```>>> */ * ```>>> */
bw_osc_tri bw_osc_tri_new(); void bw_osc_tri_init(bw_osc_tri *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_osc_tri_free()
* ```>>> */
void bw_osc_tri_free(bw_osc_tri instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_osc_tri_set_sample_rate() * #### bw_osc_tri_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_osc_tri_set_sample_rate(bw_osc_tri instance, float sample_rate); void bw_osc_tri_set_sample_rate(bw_osc_tri *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -81,7 +75,7 @@ void bw_osc_tri_set_sample_rate(bw_osc_tri instance, float sample_rate);
/*! ... /*! ...
* #### bw_osc_tri_reset() * #### bw_osc_tri_reset()
* ```>>> */ * ```>>> */
void bw_osc_tri_reset(bw_osc_tri instance); void bw_osc_tri_reset(bw_osc_tri *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -89,7 +83,7 @@ void bw_osc_tri_reset(bw_osc_tri instance);
/*! ... /*! ...
* #### bw_osc_tri_process() * #### bw_osc_tri_process()
* ```>>> */ * ```>>> */
void bw_osc_tri_process(bw_osc_tri instance, const float *x, const float *x_phase_inc, float* y, int n_samples); void bw_osc_tri_process(bw_osc_tri *instance, const float *x, const float *x_phase_inc, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` containing the normalized phase signal and fills the * buffer `x` containing the normalized phase signal and fills the
@ -102,7 +96,7 @@ void bw_osc_tri_process(bw_osc_tri instance, const float *x, const float *x_phas
/*! ... /*! ...
* #### bw_osc_tri_set_antialiasing() * #### bw_osc_tri_set_antialiasing()
* ```>>> */ * ```>>> */
void bw_osc_tri_set_antialiasing(bw_osc_tri instance, char value); void bw_osc_tri_set_antialiasing(bw_osc_tri *instance, char value);
/*! <<<``` /*! <<<```
* Sets whether the antialiasing is on (`value` non-`0`) or off (`0`) for the * Sets whether the antialiasing is on (`value` non-`0`) or off (`0`) for the
* given `instance`. * given `instance`.
@ -113,7 +107,7 @@ void bw_osc_tri_set_antialiasing(bw_osc_tri instance, char value);
/*! ... /*! ...
* #### bw_osc_tri_set_slope() * #### bw_osc_tri_set_slope()
* ```>>> */ * ```>>> */
void bw_osc_tri_set_slope(bw_osc_tri instance, float value); void bw_osc_tri_set_slope(bw_osc_tri *instance, float value);
/*! <<<``` /*! <<<```
* Sets the slope (increasing time over period) to `value` (range [`0.f`, * Sets the slope (increasing time over period) to `value` (range [`0.f`,
* `1.f`]) for the given `instance`. * `1.f`]) for the given `instance`.
@ -121,6 +115,22 @@ void bw_osc_tri_set_slope(bw_osc_tri instance, float value);
* Default value: `0.5f`. * Default value: `0.5f`.
* }}} */ * }}} */
/* 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_osc_tri {
// Coefficients
float smooth_mA1;
// Parameters
char first_run;
char antialiasing;
float slope;
// State
float slope_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_math }}} * requires {{{ bw_config bw_common bw_math }}}
* description {{{ * description {{{
* Phase generator with portamento and exponential frequency modulation. * Phase generator with portamento and exponential frequency modulation.
@ -28,6 +28,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -47,34 +52,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_phase_gen * #### bw_phase_gen
* ```>>> */ * ```>>> */
typedef struct _bw_phase_gen *bw_phase_gen; typedef struct _bw_phase_gen bw_phase_gen;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_phase_gen_new() * #### bw_phase_gen_init()
* ```>>> */ * ```>>> */
bw_phase_gen bw_phase_gen_new(); void bw_phase_gen_init(bw_phase_gen *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_phase_gen_free()
* ```>>> */
void bw_phase_gen_free(bw_phase_gen instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_phase_gen_set_sample_rate() * #### bw_phase_gen_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_phase_gen_set_sample_rate(bw_phase_gen instance, float sample_rate); void bw_phase_gen_set_sample_rate(bw_phase_gen *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -82,7 +76,7 @@ void bw_phase_gen_set_sample_rate(bw_phase_gen instance, float sample_rate);
/*! ... /*! ...
* #### bw_phase_gen_reset() * #### bw_phase_gen_reset()
* ```>>> */ * ```>>> */
void bw_phase_gen_reset(bw_phase_gen instance); void bw_phase_gen_reset(bw_phase_gen *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -90,7 +84,7 @@ void bw_phase_gen_reset(bw_phase_gen instance);
/*! ... /*! ...
* #### bw_phase_gen_process() * #### bw_phase_gen_process()
* ```>>> */ * ```>>> */
void bw_phase_gen_process(bw_phase_gen instance, const float *x_mod, float* y, float *y_phase_inc, int n_samples); void bw_phase_gen_process(bw_phase_gen *instance, const float *x_mod, float* y, float *y_phase_inc, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` generate `n_samples` samples and puts them in * Lets the given `instance` generate `n_samples` samples and puts them in
* the output buffer `y`. * the output buffer `y`.
@ -104,7 +98,7 @@ void bw_phase_gen_process(bw_phase_gen instance, const float *x_mod, float* y, f
/*! ... /*! ...
* #### bw_phase_gen_set_frequency() * #### bw_phase_gen_set_frequency()
* ```>>> */ * ```>>> */
void bw_phase_gen_set_frequency(bw_phase_gen instance, float value); void bw_phase_gen_set_frequency(bw_phase_gen *instance, float value);
/*! <<<``` /*! <<<```
* Sets the base frequency to `value` (Hz) for the given `instance`. * Sets the base frequency to `value` (Hz) for the given `instance`.
* *
@ -114,13 +108,34 @@ void bw_phase_gen_set_frequency(bw_phase_gen instance, float value);
/*! ... /*! ...
* #### bw_phase_gen_set_portamento_tau() * #### bw_phase_gen_set_portamento_tau()
* ```>>> */ * ```>>> */
void bw_phase_gen_set_portamento_tau(bw_phase_gen instance, float value); void bw_phase_gen_set_portamento_tau(bw_phase_gen *instance, float value);
/*! <<<``` /*! <<<```
* Sets the portamento time constant `value` (s) for the given `instance`. * Sets the portamento time constant `value` (s) for the given `instance`.
* *
* Default value: `0.f`. * Default value: `0.f`.
* }}} */ * }}} */
/* 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_phase_gen {
// Coefficients
float T;
float portamento_target;
float portamento_mA1;
// Parameters
float frequency;
float portamento_tau;
int param_changed;
// State
char first_run;
float phase;
float portamento_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,13 +19,18 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_math }}} * requires {{{ bw_config bw_common bw_math }}}
* description {{{ * description {{{
* Slew-rate limiter with separate maximum increasing and decreasing rates. * Slew-rate limiter with separate maximum increasing and decreasing rates.
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -45,34 +50,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_slew_lim * #### bw_slew_lim
* ```>>> */ * ```>>> */
typedef struct _bw_slew_lim *bw_slew_lim; typedef struct _bw_slew_lim bw_slew_lim;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_slew_lim_new() * #### bw_slew_lim_init()
* ```>>> */ * ```>>> */
bw_slew_lim bw_slew_lim_new(); void bw_slew_lim_new(bw_slew_lim *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_slew_lim_free()
* ```>>> */
void bw_slew_lim_free(bw_slew_lim instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_slew_lim_set_sample_rate() * #### bw_slew_lim_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_slew_lim_set_sample_rate(bw_slew_lim instance, float sample_rate); void bw_slew_lim_set_sample_rate(bw_slew_lim *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -80,7 +74,7 @@ void bw_slew_lim_set_sample_rate(bw_slew_lim instance, float sample_rate);
/*! ... /*! ...
* #### bw_slew_lim_reset() * #### bw_slew_lim_reset()
* ```>>> */ * ```>>> */
void bw_slew_lim_reset(bw_slew_lim instance); void bw_slew_lim_reset(bw_slew_lim *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -88,7 +82,7 @@ void bw_slew_lim_reset(bw_slew_lim instance);
/*! ... /*! ...
* #### bw_slew_lim_process() * #### bw_slew_lim_process()
* ```>>> */ * ```>>> */
void bw_slew_lim_process(bw_slew_lim instance, const float* x, float* y, int n_samples); void bw_slew_lim_process(bw_slew_lim *instance, const float* x, float* y, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` and fills the corresponding `n_samples` samples in the output * buffer `x` and fills the corresponding `n_samples` samples in the output
@ -98,7 +92,7 @@ void bw_slew_lim_process(bw_slew_lim instance, const float* x, float* y, int n_s
/*! ... /*! ...
* #### bw_slew_lim_set_init_val() * #### bw_slew_lim_set_init_val()
* ```>>> */ * ```>>> */
void bw_slew_lim_set_init_val(bw_slew_lim instance, float value); void bw_slew_lim_set_init_val(bw_slew_lim *instance, float value);
/*! <<<``` /*! <<<```
* Sets the initial/quiescent `value` for the given `instance`. * Sets the initial/quiescent `value` for the given `instance`.
* *
@ -112,7 +106,7 @@ void bw_slew_lim_set_init_val(bw_slew_lim instance, float value);
/*! ... /*! ...
* #### bw_slew_lim_set_max_rate() * #### bw_slew_lim_set_max_rate()
* ```>>> */ * ```>>> */
void bw_slew_lim_set_max_rate(bw_slew_lim instance, float value); void bw_slew_lim_set_max_rate(bw_slew_lim *instance, float value);
/*! <<<``` /*! <<<```
* Sets both the maximum increasing and decreasing variation rate to the * Sets both the maximum increasing and decreasing variation rate to the
* given `value` (1/s) for the given `instance`. * given `value` (1/s) for the given `instance`.
@ -129,7 +123,7 @@ void bw_slew_lim_set_max_rate(bw_slew_lim instance, float value);
/*! ... /*! ...
* #### bw_slew_lim_set_max_inc_rate() * #### bw_slew_lim_set_max_inc_rate()
* ```>>> */ * ```>>> */
void bw_slew_lim_set_max_inc_rate(bw_slew_lim instance, float value); void bw_slew_lim_set_max_inc_rate(bw_slew_lim *instance, float value);
/*! <<<``` /*! <<<```
* Sets the maximum increasing variation rate to the given `value` (1/s) for * Sets the maximum increasing variation rate to the given `value` (1/s) for
* the given `instance`. * the given `instance`.
@ -143,7 +137,7 @@ void bw_slew_lim_set_max_inc_rate(bw_slew_lim instance, float value);
/*! ... /*! ...
* #### bw_slew_lim_set_max_inc_rate() * #### bw_slew_lim_set_max_inc_rate()
* ```>>> */ * ```>>> */
void bw_slew_lim_set_max_dec_rate(bw_slew_lim instance, float value); void bw_slew_lim_set_max_dec_rate(bw_slew_lim *instance, float value);
/*! <<<``` /*! <<<```
* Sets the maximum decreasing variation rate to the given `value` (1/s) for * Sets the maximum decreasing variation rate to the given `value` (1/s) for
* the given `instance`. * the given `instance`.
@ -154,6 +148,23 @@ void bw_slew_lim_set_max_dec_rate(bw_slew_lim instance, float value);
* Default value: `INFINITY`. * Default value: `INFINITY`.
* }}} */ * }}} */
/* 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_slew_lim {
// Coefficients
float T;
// Parameters
float init_val;
float max_inc_rate;
float max_dec_rate;
// State
char first_run;
float y_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,7 +19,7 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}} * requires {{{ bw_config bw_common bw_inline_one_pole bw_math }}}
* description {{{ * description {{{
* State variable filter (2nd order, 12 dB/oct) model with separated lowpass, * State variable filter (2nd order, 12 dB/oct) model with separated lowpass,
@ -27,6 +27,11 @@
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -46,34 +51,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_svf * #### bw_svf
* ```>>> */ * ```>>> */
typedef struct _bw_svf *bw_svf; typedef struct _bw_svf bw_svf;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_svf_new() * #### bw_svf_init()
* ```>>> */ * ```>>> */
bw_svf bw_svf_new(); void bw_svf_init(bw_svf *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_svf_free()
* ```>>> */
void bw_svf_free(bw_svf instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_svf_set_sample_rate() * #### bw_svf_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_svf_set_sample_rate(bw_svf instance, float sample_rate); void bw_svf_set_sample_rate(bw_svf *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -81,7 +75,7 @@ void bw_svf_set_sample_rate(bw_svf instance, float sample_rate);
/*! ... /*! ...
* #### bw_svf_reset() * #### bw_svf_reset()
* ```>>> */ * ```>>> */
void bw_svf_reset(bw_svf instance); void bw_svf_reset(bw_svf *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -89,7 +83,7 @@ void bw_svf_reset(bw_svf instance);
/*! ... /*! ...
* #### bw_svf_process() * #### bw_svf_process()
* ```>>> */ * ```>>> */
void bw_svf_process(bw_svf instance, const float *x, float* y_lp, float *y_bp, float *y_hp, int n_samples); void bw_svf_process(bw_svf *instance, const float *x, float* y_lp, float *y_bp, float *y_hp, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from the input * Lets the given `instance` process `n_samples` samples from the input
* buffer `x` and fills the corresponding `n_samples` samples in the output * buffer `x` and fills the corresponding `n_samples` samples in the output
@ -100,7 +94,7 @@ void bw_svf_process(bw_svf instance, const float *x, float* y_lp, float *y_bp, f
/*! ... /*! ...
* #### bw_svf_set_cutoff() * #### bw_svf_set_cutoff()
* ```>>> */ * ```>>> */
void bw_svf_set_cutoff(bw_svf instance, float value); void bw_svf_set_cutoff(bw_svf *instance, float value);
/*! <<<``` /*! <<<```
* Sets the cutoff frequency to the given `value` (Hz) for the given * Sets the cutoff frequency to the given `value` (Hz) for the given
* `instance`. * `instance`.
@ -111,7 +105,7 @@ void bw_svf_set_cutoff(bw_svf instance, float value);
/*! ... /*! ...
* #### bw_svf_set_Q() * #### bw_svf_set_Q()
* ```>>> */ * ```>>> */
void bw_svf_set_Q(bw_svf instance, float value); void bw_svf_set_Q(bw_svf *instance, float value);
/*! <<<``` /*! <<<```
* Sets the quality factor to the given `value` (Hz) for the given * Sets the quality factor to the given `value` (Hz) for the given
* `instance`. * `instance`.
@ -119,6 +113,34 @@ void bw_svf_set_Q(bw_svf instance, float value);
* Default value: `0.5f`. * Default value: `0.5f`.
* }}} */ * }}} */
/* 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_svf {
// Coefficients
float t_k;
float smooth_mA1;
float t;
float k;
float hp_hp_z1;
float hp_bp_z1;
float hp_x;
// Parameters
float cutoff;
float Q;
float cutoff_cur;
float Q_cur;
// State
char first_run;
float hp_z1;
float lp_z1;
float bp_z1;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -19,13 +19,18 @@
/*! /*!
* module_type {{{ dsp }}} * module_type {{{ dsp }}}
* version {{{ 0.1.0 }}} * version {{{ 0.2.0 }}}
* requires {{{ bw_config bw_common bw_inline_slew_lim bw_math }}} * requires {{{ bw_config bw_common bw_inline_slew_lim bw_math }}}
* description {{{ * description {{{
* Volume control for an arbitrary number of channels. * Volume control for an arbitrary number of channels.
* }}} * }}}
* changelog {{{ * changelog {{{
* <ul> * <ul>
* <li>Version <strong>0.2.0</strong>:
* <ul>
* <li>Refactored API to avoid dynamic memory allocation.</li>
* </ul>
* </li>
* <li>Version <strong>0.1.0</strong>: * <li>Version <strong>0.1.0</strong>:
* <ul> * <ul>
* <li>First release.</li> * <li>First release.</li>
@ -45,34 +50,23 @@ extern "C" {
/*! api {{{ /*! api {{{
* #### bw_vol * #### bw_vol
* ```>>> */ * ```>>> */
typedef struct _bw_vol *bw_vol; typedef struct _bw_vol bw_vol;
/*! <<<``` /*! <<<```
* Instance handle. * Instance object.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_vol_new() * #### bw_vol_init()
* ```>>> */ * ```>>> */
bw_vol bw_vol_new(); void bw_vol_init(bw_vol *instance);
/*! <<<``` /*! <<<```
* Creates a new instance. * Initializes the `instance` object.
*
* Returns the newly-created instance handle or `NULL` if there was not
* enough memory.
* >>> */
/*! ...
* #### bw_vol_free()
* ```>>> */
void bw_vol_free(bw_vol instance);
/*! <<<```
* Destroys an `instance`.
* >>> */ * >>> */
/*! ... /*! ...
* #### bw_vol_set_sample_rate() * #### bw_vol_set_sample_rate()
* ```>>> */ * ```>>> */
void bw_vol_set_sample_rate(bw_vol instance, float sample_rate); void bw_vol_set_sample_rate(bw_vol *instance, float sample_rate);
/*! <<<``` /*! <<<```
* Sets the `sample_rate` (Hz) value for the given `instance`. * Sets the `sample_rate` (Hz) value for the given `instance`.
* >>> */ * >>> */
@ -80,7 +74,7 @@ void bw_vol_set_sample_rate(bw_vol instance, float sample_rate);
/*! ... /*! ...
* #### bw_vol_reset() * #### bw_vol_reset()
* ```>>> */ * ```>>> */
void bw_vol_reset(bw_vol instance); void bw_vol_reset(bw_vol *instance);
/*! <<<``` /*! <<<```
* Resets the given `instance` to its initial state. * Resets the given `instance` to its initial state.
* >>> */ * >>> */
@ -88,7 +82,7 @@ void bw_vol_reset(bw_vol instance);
/*! ... /*! ...
* #### bw_vol_process() * #### bw_vol_process()
* ```>>> */ * ```>>> */
void bw_vol_process(bw_vol instance, const float **x, float **y, int n_channels, int n_samples); void bw_vol_process(bw_vol *instance, const float **x, float **y, int n_channels, int n_samples);
/*! <<<``` /*! <<<```
* Lets the given `instance` process `n_samples` samples from each of the * Lets the given `instance` process `n_samples` samples from each of the
* `n_channels` input buffers and fills the corresponding `n_samples` samples * `n_channels` input buffers and fills the corresponding `n_samples` samples
@ -101,7 +95,7 @@ void bw_vol_process(bw_vol instance, const float **x, float **y, int n_channels,
/*! ... /*! ...
* #### bw_vol_set_volume() * #### bw_vol_set_volume()
* ```>>> */ * ```>>> */
void bw_vol_set_volume(bw_vol instance, float value); void bw_vol_set_volume(bw_vol *instance, float value);
/*! <<<``` /*! <<<```
* Sets the volume parameter to the given `value` (range [`0.f`, `1.f`]) for * Sets the volume parameter to the given `value` (range [`0.f`, `1.f`]) for
* the given `instance`. * the given `instance`.
@ -112,6 +106,29 @@ void bw_vol_set_volume(bw_vol instance, float value);
* Default value: `1.f`. * Default value: `1.f`.
* }}} */ * }}} */
/* WARNING: this definition is not part of the public API. Please, do not use
* it. */
#define _BW_VOL_BUFFER_SIZE 32
/* 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_vol {
// Coefficients
float max_var;
// Parameters
float volume;
float volume_cur;
// State
char first_run;
// Buffers
float buf[_BW_VOL_BUFFER_SIZE];
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -21,44 +21,24 @@
#include <bw_math.h> #include <bw_math.h>
struct _bw_env_follow { void bw_env_follow_init(bw_env_follow *instance) {
// Sub-components bw_one_pole_init(&instance->one_pole);
bw_one_pole one_pole;
};
bw_env_follow bw_env_follow_new() {
bw_env_follow instance = (bw_env_follow)BW_MALLOC(sizeof(struct _bw_env_follow));
if (instance == NULL)
return NULL;
instance->one_pole = bw_one_pole_new();
if (instance->one_pole == NULL) {
BW_FREE(instance);
return NULL;
}
return instance;
} }
void bw_env_follow_free(bw_env_follow instance) { void bw_env_follow_set_sample_rate(bw_env_follow *instance, float sample_rate) {
bw_one_pole_free(instance->one_pole); bw_one_pole_set_sample_rate(&instance->one_pole, sample_rate);
BW_FREE(instance);
} }
void bw_env_follow_set_sample_rate(bw_env_follow instance, float sample_rate) { void bw_env_follow_reset(bw_env_follow *instance) {
bw_one_pole_set_sample_rate(instance->one_pole, sample_rate); bw_one_pole_reset(&instance->one_pole);
} }
void bw_env_follow_reset(bw_env_follow instance) { void bw_env_follow_process(bw_env_follow *instance, const float *x, float *y, int n_samples) {
bw_one_pole_reset(instance->one_pole);
}
void bw_env_follow_process(bw_env_follow instance, const float *x, float *y, int n_samples) {
for (int i = 0; i < n_samples; i++) for (int i = 0; i < n_samples; i++)
y[i] = bw_absf(x[i]); y[i] = bw_absf(x[i]);
bw_one_pole_process(instance->one_pole, y, y, n_samples); bw_one_pole_process(&instance->one_pole, y, y, n_samples);
} }
bw_one_pole bw_env_follow_get_one_pole(bw_env_follow instance) { bw_one_pole *bw_env_follow_get_one_pole(bw_env_follow *instance) {
return instance->one_pole; return &instance->one_pole;
} }

View File

@ -22,61 +22,20 @@
#include <bw_math.h> #include <bw_math.h>
#include <bw_inline_one_pole.h> #include <bw_inline_one_pole.h>
typedef enum { void bw_env_gen_init(bw_env_gen *instance) {
state_off,
state_attack,
state_decay,
state_sustain,
state_release
} state_t;
struct _bw_env_gen {
// Coefficients
float T;
float smooth_mA1;
float attack_inc;
float decay_inc;
float release_inc;
// Parameters
char gate;
float attack;
float decay;
float sustain;
float release;
int param_changed;
// State
char first_run;
state_t state;
float y_z1;
};
bw_env_gen bw_env_gen_new() {
bw_env_gen instance = (bw_env_gen)BW_MALLOC(sizeof(struct _bw_env_gen));
if (instance == NULL)
return NULL;
instance->gate = 0; instance->gate = 0;
instance->attack = 0.f; instance->attack = 0.f;
instance->decay = 0.f; instance->decay = 0.f;
instance->sustain = 1.f; instance->sustain = 1.f;
instance->release = 0.f; instance->release = 0.f;
return instance;
} }
void bw_env_gen_free(bw_env_gen instance) { void bw_env_gen_set_sample_rate(bw_env_gen *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_env_gen_set_sample_rate(bw_env_gen instance, float sample_rate) {
instance->T = 1.f / sample_rate; instance->T = 1.f / sample_rate;
instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.05f); instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.05f);
} }
void bw_env_gen_reset(bw_env_gen instance) { void bw_env_gen_reset(bw_env_gen *instance) {
instance->first_run = 1; instance->first_run = 1;
instance->param_changed = ~0; instance->param_changed = ~0;
} }
@ -86,7 +45,7 @@ void bw_env_gen_reset(bw_env_gen instance) {
#define PARAM_SUSTAIN (1<<2) #define PARAM_SUSTAIN (1<<2)
#define PARAM_RELEASE (1<<3) #define PARAM_RELEASE (1<<3)
void bw_env_gen_process(bw_env_gen instance, float* y, int n_samples) { void bw_env_gen_process(bw_env_gen *instance, float* y, int n_samples) {
if (instance->param_changed) { if (instance->param_changed) {
// 1 ns considered instantaneous // 1 ns considered instantaneous
if (instance->param_changed & PARAM_ATTACK) if (instance->param_changed & PARAM_ATTACK)
@ -98,47 +57,47 @@ void bw_env_gen_process(bw_env_gen instance, float* y, int n_samples) {
} }
if (instance->first_run) { if (instance->first_run) {
instance->state = state_off; instance->state = _bw_env_gen_state_off;
instance->y_z1 = 0.f; instance->y_z1 = 0.f;
instance->first_run = 0; instance->first_run = 0;
} }
if (instance->gate) { if (instance->gate) {
if (instance->state == state_off || instance->state == state_release) if (instance->state == _bw_env_gen_state_off || instance->state == _bw_env_gen_state_release)
instance->state = state_attack; instance->state = _bw_env_gen_state_attack;
} else { } else {
if (instance->state != state_off) if (instance->state != _bw_env_gen_state_off)
instance->state = state_release; instance->state = _bw_env_gen_state_release;
} }
for (int i = 0; i < n_samples; i++) { for (int i = 0; i < n_samples; i++) {
float v; float v;
switch (instance->state) { switch (instance->state) {
case state_attack: case _bw_env_gen_state_attack:
v = instance->y_z1 + instance->attack_inc; v = instance->y_z1 + instance->attack_inc;
if (v >= 1.f) { if (v >= 1.f) {
v = 1.f; v = 1.f;
instance->state = state_decay; instance->state = _bw_env_gen_state_decay;
} }
break; break;
case state_decay: case _bw_env_gen_state_decay:
v = instance->y_z1 + instance->decay_inc; v = instance->y_z1 + instance->decay_inc;
if (v <= instance->sustain) { if (v <= instance->sustain) {
v = instance->sustain; v = instance->sustain;
instance->state = state_sustain; instance->state = _bw_env_gen_state_sustain;
} }
break; break;
case state_sustain: case _bw_env_gen_state_sustain:
v = bw_inline_one_pole(instance->sustain, instance->y_z1, instance->smooth_mA1); v = bw_inline_one_pole(instance->sustain, instance->y_z1, instance->smooth_mA1);
break; break;
case state_release: case _bw_env_gen_state_release:
v = instance->y_z1 + instance->release_inc; v = instance->y_z1 + instance->release_inc;
if (v <= 0.f) { if (v <= 0.f) {
v = 0.f; v = 0.f;
instance->state = state_off; instance->state = _bw_env_gen_state_off;
} }
break; break;
case state_off: case _bw_env_gen_state_off:
v = 0.f; v = 0.f;
break; break;
} }
@ -148,38 +107,38 @@ void bw_env_gen_process(bw_env_gen instance, float* y, int n_samples) {
} }
} }
void bw_env_gen_set_gate(bw_env_gen instance, char value) { void bw_env_gen_set_gate(bw_env_gen *instance, char value) {
instance->gate = value; instance->gate = value;
} }
void bw_env_gen_set_attack(bw_env_gen instance, float value) { void bw_env_gen_set_attack(bw_env_gen *instance, float value) {
if (instance->attack != value) { if (instance->attack != value) {
instance->attack = value; instance->attack = value;
instance->param_changed |= PARAM_ATTACK; instance->param_changed |= PARAM_ATTACK;
} }
} }
void bw_env_gen_set_decay(bw_env_gen instance, float value) { void bw_env_gen_set_decay(bw_env_gen *instance, float value) {
if (instance->decay != value) { if (instance->decay != value) {
instance->decay = value; instance->decay = value;
instance->param_changed |= PARAM_DECAY; instance->param_changed |= PARAM_DECAY;
} }
} }
void bw_env_gen_set_sustain(bw_env_gen instance, float value) { void bw_env_gen_set_sustain(bw_env_gen *instance, float value) {
if (instance->sustain != value) { if (instance->sustain != value) {
instance->sustain = value; instance->sustain = value;
instance->param_changed |= PARAM_SUSTAIN; instance->param_changed |= PARAM_SUSTAIN;
} }
} }
void bw_env_gen_set_release(bw_env_gen instance, float value) { void bw_env_gen_set_release(bw_env_gen *instance, float value) {
if (instance->release != value) { if (instance->release != value) {
instance->release = value; instance->release = value;
instance->param_changed |= PARAM_RELEASE; instance->param_changed |= PARAM_RELEASE;
} }
} }
char bw_env_gen_get_is_off(bw_env_gen instance) { char bw_env_gen_get_is_off(bw_env_gen *instance) {
return instance->state == state_off; return instance->state == _bw_env_gen_state_off;
} }

View File

@ -22,36 +22,16 @@
#include <bw_rand.h> #include <bw_rand.h>
#include <bw_math.h> #include <bw_math.h>
struct _bw_noise_gen { void bw_noise_gen_init(bw_noise_gen *instance, uint64_t *state) {
// Coefficients
float scaling_k;
// Parameters
char sample_rate_scaling;
// State
uint64_t *state;
};
bw_noise_gen bw_noise_gen_new(uint64_t *state) {
bw_noise_gen instance = (bw_noise_gen)BW_MALLOC(sizeof(struct _bw_noise_gen));
if (instance == NULL)
return NULL;
instance->state = state; instance->state = state;
instance->sample_rate_scaling = 0; instance->sample_rate_scaling = 0;
return instance;
} }
void bw_noise_gen_free(bw_noise_gen instance) { void bw_noise_gen_set_sample_rate(bw_noise_gen *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_noise_gen_set_sample_rate(bw_noise_gen instance, float sample_rate) {
instance->scaling_k = 0.004761904761904762f * bw_sqrtf_2(sample_rate); instance->scaling_k = 0.004761904761904762f * bw_sqrtf_2(sample_rate);
} }
void bw_noise_gen_process(bw_noise_gen instance, float* y, int n_samples) { void bw_noise_gen_process(bw_noise_gen *instance, float* y, int n_samples) {
for (int i = 0; i < n_samples; i++) for (int i = 0; i < n_samples; i++)
y[i] = bw_rand_f(instance->state); y[i] = bw_rand_f(instance->state);
@ -60,6 +40,6 @@ void bw_noise_gen_process(bw_noise_gen instance, float* y, int n_samples) {
y[i] *= instance->scaling_k; y[i] *= instance->scaling_k;
} }
void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen instance, char value) { void bw_noise_gen_set_sample_rate_scaling(bw_noise_gen *instance, char value) {
instance->sample_rate_scaling = value; instance->sample_rate_scaling = value;
} }

View File

@ -21,48 +21,18 @@
#include <bw_math.h> #include <bw_math.h>
struct _bw_one_pole { void bw_one_pole_init(bw_one_pole *instance) {
// Coefficients instance->init_val = 0.f;
float Ttm2pi; instance->cutoff_up = INFINITY;
instance->cutoff_down = INFINITY;
float mA1u; instance->sticky_thresh = 0.f;
float mA1d;
float st2;
// Parameters
float init_val;
float cutoff_up;
float cutoff_down;
float sticky_thresh;
bw_one_pole_sticky_mode sticky_mode;
int param_changed;
// State
char first_run;
float x_z1;
float y_z1;
};
bw_one_pole bw_one_pole_new() {
bw_one_pole instance = (bw_one_pole)BW_MALLOC(sizeof(struct _bw_one_pole));
if (instance != NULL) {
instance->init_val = 0.f;
instance->cutoff_up = INFINITY;
instance->cutoff_down = INFINITY;
instance->sticky_thresh = 0.f;
}
return instance;
} }
void bw_one_pole_free(bw_one_pole instance) { void bw_one_pole_set_sample_rate(bw_one_pole *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_one_pole_set_sample_rate(bw_one_pole instance, float sample_rate) {
instance->Ttm2pi = -6.283185307179586f / sample_rate; instance->Ttm2pi = -6.283185307179586f / sample_rate;
} }
void bw_one_pole_reset(bw_one_pole instance) { void bw_one_pole_reset(bw_one_pole *instance) {
instance->first_run = 1; instance->first_run = 1;
instance->param_changed = ~0; instance->param_changed = ~0;
} }
@ -71,7 +41,7 @@ void bw_one_pole_reset(bw_one_pole instance) {
#define PARAM_CUTOFF_DOWN (1<<1) #define PARAM_CUTOFF_DOWN (1<<1)
#define PARAM_STICKY_THRESH (1<<2) #define PARAM_STICKY_THRESH (1<<2)
void bw_one_pole_process(bw_one_pole instance, const float* x, float* y, int n_samples) { void bw_one_pole_process(bw_one_pole *instance, const float* x, float* y, int n_samples) {
if (instance->param_changed) { if (instance->param_changed) {
if (instance->param_changed & PARAM_CUTOFF_UP) if (instance->param_changed & PARAM_CUTOFF_UP)
instance->mA1u = bw_expf_3(instance->Ttm2pi * instance->cutoff_up); instance->mA1u = bw_expf_3(instance->Ttm2pi * instance->cutoff_up);
@ -160,51 +130,51 @@ void bw_one_pole_process(bw_one_pole instance, const float* x, float* y, int n_s
} }
} }
void bw_one_pole_set_init_val(bw_one_pole instance, float value) { void bw_one_pole_set_init_val(bw_one_pole *instance, float value) {
instance->init_val = value; instance->init_val = value;
} }
void bw_one_pole_set_cutoff(bw_one_pole instance, float value) { void bw_one_pole_set_cutoff(bw_one_pole *instance, float value) {
bw_one_pole_set_cutoff_up(instance, value); bw_one_pole_set_cutoff_up(instance, value);
bw_one_pole_set_cutoff_down(instance, value); bw_one_pole_set_cutoff_down(instance, value);
} }
void bw_one_pole_set_cutoff_up(bw_one_pole instance, float value) { void bw_one_pole_set_cutoff_up(bw_one_pole *instance, float value) {
if (instance->cutoff_up != value) { if (instance->cutoff_up != value) {
instance->cutoff_up = value; instance->cutoff_up = value;
instance->param_changed |= PARAM_CUTOFF_UP; instance->param_changed |= PARAM_CUTOFF_UP;
} }
} }
void bw_one_pole_set_cutoff_down(bw_one_pole instance, float value) { void bw_one_pole_set_cutoff_down(bw_one_pole *instance, float value) {
if (instance->cutoff_down != value) { if (instance->cutoff_down != value) {
instance->cutoff_down = value; instance->cutoff_down = value;
instance->param_changed |= PARAM_CUTOFF_DOWN; instance->param_changed |= PARAM_CUTOFF_DOWN;
} }
} }
void bw_one_pole_set_tau(bw_one_pole instance, float value) { void bw_one_pole_set_tau(bw_one_pole *instance, float value) {
bw_one_pole_set_tau_up(instance, value); bw_one_pole_set_tau_up(instance, value);
bw_one_pole_set_tau_down(instance, value); bw_one_pole_set_tau_down(instance, value);
} }
void bw_one_pole_set_tau_up(bw_one_pole instance, float value) { void bw_one_pole_set_tau_up(bw_one_pole *instance, float value) {
bw_one_pole_set_cutoff_up(instance, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value)); bw_one_pole_set_cutoff_up(instance, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value));
// tau < 1 ns is instantaneous for any practical purpose // tau < 1 ns is instantaneous for any practical purpose
} }
void bw_one_pole_set_tau_down(bw_one_pole instance, float value) { void bw_one_pole_set_tau_down(bw_one_pole *instance, float value) {
bw_one_pole_set_cutoff_down(instance, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value)); bw_one_pole_set_cutoff_down(instance, value < 1e-9f ? INFINITY : 0.1591549430918953f * bw_rcpf_2(value));
// as before // as before
} }
void bw_one_pole_set_sticky_thresh(bw_one_pole instance, float value) { void bw_one_pole_set_sticky_thresh(bw_one_pole *instance, float value) {
if (instance->sticky_thresh != value) { if (instance->sticky_thresh != value) {
instance->sticky_thresh = value; instance->sticky_thresh = value;
instance->param_changed |= PARAM_STICKY_THRESH; instance->param_changed |= PARAM_STICKY_THRESH;
} }
} }
void bw_one_pole_set_sticky_mode(bw_one_pole instance, bw_one_pole_sticky_mode value) { void bw_one_pole_set_sticky_mode(bw_one_pole *instance, bw_one_pole_sticky_mode value) {
instance->sticky_mode = value; instance->sticky_mode = value;
} }

View File

@ -21,35 +21,16 @@
#include <bw_common.h> #include <bw_common.h>
struct _bw_osc_filt { void bw_osc_filt_init(bw_osc_filt *instance) {
// Parameters
char enabled;
// State
float x_z1;
float y_z1;
};
bw_osc_filt bw_osc_filt_new() {
bw_osc_filt instance = (bw_osc_filt)BW_MALLOC(sizeof(struct _bw_osc_filt));
if (instance == NULL)
return NULL;
instance->enabled = 1; instance->enabled = 1;
return instance;
} }
void bw_osc_filt_free(bw_osc_filt instance) { void bw_osc_filt_reset(bw_osc_filt *instance) {
BW_FREE(instance);
}
void bw_osc_filt_reset(bw_osc_filt instance) {
instance->x_z1 = 0.f; instance->x_z1 = 0.f;
instance->y_z1 = 0.f; instance->y_z1 = 0.f;
} }
void bw_osc_filt_process(bw_osc_filt instance, const float *x, float* y, int n_samples) { void bw_osc_filt_process(bw_osc_filt *instance, const float *x, float* y, int n_samples) {
if (instance->enabled) if (instance->enabled)
for (int i = 0; i < n_samples; i++) { for (int i = 0; i < n_samples; i++) {
const float v = 1.371308261611209f * x[i] + 0.08785458027104826f * instance->x_z1 - 4.591628418822578e-1f * instance->y_z1; const float v = 1.371308261611209f * x[i] + 0.08785458027104826f * instance->x_z1 - 4.591628418822578e-1f * instance->y_z1;
@ -65,6 +46,6 @@ void bw_osc_filt_process(bw_osc_filt instance, const float *x, float* y, int n_s
} }
void bw_osc_filt_set_enabled(bw_osc_filt instance, char value) { void bw_osc_filt_set_enabled(bw_osc_filt *instance, char value) {
instance->enabled = value; instance->enabled = value;
} }

View File

@ -22,39 +22,16 @@
#include <bw_math.h> #include <bw_math.h>
#include <bw_inline_one_pole.h> #include <bw_inline_one_pole.h>
struct _bw_osc_pulse { void bw_osc_pulse_init(bw_osc_pulse *instance) {
// Coefficients
float smooth_mA1;
// Parameters
char first_run;
char antialiasing;
float pulse_width;
// State
float pw_z1;
};
bw_osc_pulse bw_osc_pulse_new() {
bw_osc_pulse instance = (bw_osc_pulse)BW_MALLOC(sizeof(struct _bw_osc_pulse));
if (instance == NULL)
return NULL;
instance->antialiasing = 0; instance->antialiasing = 0;
instance->pulse_width = 0.5f; instance->pulse_width = 0.5f;
return instance;
} }
void bw_osc_pulse_free(bw_osc_pulse instance) { void bw_osc_pulse_set_sample_rate(bw_osc_pulse *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_osc_pulse_set_sample_rate(bw_osc_pulse instance, float sample_rate) {
instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.005f); instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.005f);
} }
void bw_osc_pulse_reset(bw_osc_pulse instance) { void bw_osc_pulse_reset(bw_osc_pulse *instance) {
instance->first_run = 1; instance->first_run = 1;
} }
@ -65,7 +42,7 @@ static inline float blep_diff(float x) {
: x * (x * ((0.6666666666666666f - 0.08333333333333333f * x) * x - 2.0f) + 2.666666666666667f) - 1.333333333333333f; : x * (x * ((0.6666666666666666f - 0.08333333333333333f * x) * x - 2.0f) + 2.666666666666667f) - 1.333333333333333f;
} }
void bw_osc_pulse_process(bw_osc_pulse instance, const float *x, const float *x_phase_inc, float* y, int n_samples) { void bw_osc_pulse_process(bw_osc_pulse *instance, const float *x, const float *x_phase_inc, float* y, int n_samples) {
if (instance->first_run) { if (instance->first_run) {
instance->pw_z1 = instance->pulse_width; instance->pw_z1 = instance->pulse_width;
instance->first_run = 0; instance->first_run = 0;
@ -107,10 +84,10 @@ void bw_osc_pulse_process(bw_osc_pulse instance, const float *x, const float *x_
} }
} }
void bw_osc_pulse_set_antialiasing(bw_osc_pulse instance, char value) { void bw_osc_pulse_set_antialiasing(bw_osc_pulse *instance, char value) {
instance->antialiasing = value; instance->antialiasing = value;
} }
void bw_osc_pulse_set_pulse_width(bw_osc_pulse instance, float value) { void bw_osc_pulse_set_pulse_width(bw_osc_pulse *instance, float value) {
instance->pulse_width = value; instance->pulse_width = value;
} }

View File

@ -21,23 +21,8 @@
#include <bw_math.h> #include <bw_math.h>
struct _bw_osc_saw { void bw_osc_saw_init(bw_osc_saw *instance) {
// Parameters
char antialiasing;
};
bw_osc_saw bw_osc_saw_new() {
bw_osc_saw instance = (bw_osc_saw)BW_MALLOC(sizeof(struct _bw_osc_saw));
if (instance == NULL)
return NULL;
instance->antialiasing = 0; instance->antialiasing = 0;
return instance;
}
void bw_osc_saw_free(bw_osc_saw instance) {
BW_FREE(instance);
} }
// PolyBLEP residual based on Parzen window (4th-order B-spline), one-sided (x in [0, 2]) // PolyBLEP residual based on Parzen window (4th-order B-spline), one-sided (x in [0, 2])
@ -47,7 +32,7 @@ static inline float blep_diff(float x) {
: x * (x * ((0.6666666666666666f - 0.08333333333333333f * x) * x - 2.0f) + 2.666666666666667f) - 1.333333333333333f; : x * (x * ((0.6666666666666666f - 0.08333333333333333f * x) * x - 2.0f) + 2.666666666666667f) - 1.333333333333333f;
} }
void bw_osc_saw_process(bw_osc_saw instance, const float *x, const float *x_phase_inc, float* y, int n_samples) { void bw_osc_saw_process(bw_osc_saw *instance, const float *x, const float *x_phase_inc, float* y, int n_samples) {
if (instance->antialiasing) { if (instance->antialiasing) {
for (int i = 0; i < n_samples; i++) { for (int i = 0; i < n_samples; i++) {
const float s_1_m_phase = 1.f - x[i]; const float s_1_m_phase = 1.f - x[i];
@ -70,6 +55,6 @@ void bw_osc_saw_process(bw_osc_saw instance, const float *x, const float *x_phas
} }
} }
void bw_osc_saw_set_antialiasing(bw_osc_saw instance, char value) { void bw_osc_saw_set_antialiasing(bw_osc_saw *instance, char value) {
instance->antialiasing = value; instance->antialiasing = value;
} }

View File

@ -22,39 +22,16 @@
#include <bw_math.h> #include <bw_math.h>
#include <bw_inline_one_pole.h> #include <bw_inline_one_pole.h>
struct _bw_osc_tri { void bw_osc_tri_init(bw_osc_tri *instance) {
// Coefficients
float smooth_mA1;
// Parameters
char first_run;
char antialiasing;
float slope;
// State
float slope_z1;
};
bw_osc_tri bw_osc_tri_new() {
bw_osc_tri instance = (bw_osc_tri)BW_MALLOC(sizeof(struct _bw_osc_tri));
if (instance == NULL)
return NULL;
instance->antialiasing = 0; instance->antialiasing = 0;
instance->slope = 0.5f; instance->slope = 0.5f;
return instance;
} }
void bw_osc_tri_free(bw_osc_tri instance) { void bw_osc_tri_set_sample_rate(bw_osc_tri *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_osc_tri_set_sample_rate(bw_osc_tri instance, float sample_rate) {
instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.005f); instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.005f);
} }
void bw_osc_tri_reset(bw_osc_tri instance) { void bw_osc_tri_reset(bw_osc_tri *instance) {
instance->first_run = 1; instance->first_run = 1;
} }
@ -65,7 +42,7 @@ static inline float blamp_diff(float x) {
: x * (x * (x * ((0.1666666666666667f - 0.01666666666666667f * x) * x - 0.6666666666666666f) + 1.333333333333333f) - 1.333333333333333f) + 0.5333333333333333f; : x * (x * (x * ((0.1666666666666667f - 0.01666666666666667f * x) * x - 0.6666666666666666f) + 1.333333333333333f) - 1.333333333333333f) + 0.5333333333333333f;
} }
void bw_osc_tri_process(bw_osc_tri instance, const float *x, const float *x_phase_inc, float* y, int n_samples) { void bw_osc_tri_process(bw_osc_tri *instance, const float *x, const float *x_phase_inc, float* y, int n_samples) {
if (instance->first_run) { if (instance->first_run) {
instance->slope_z1 = instance->slope; instance->slope_z1 = instance->slope;
instance->first_run = 0; instance->first_run = 0;
@ -113,10 +90,10 @@ void bw_osc_tri_process(bw_osc_tri instance, const float *x, const float *x_phas
} }
} }
void bw_osc_tri_set_antialiasing(bw_osc_tri instance, char value) { void bw_osc_tri_set_antialiasing(bw_osc_tri *instance, char value) {
instance->antialiasing = value; instance->antialiasing = value;
} }
void bw_osc_tri_set_slope(bw_osc_tri instance, float value) { void bw_osc_tri_set_slope(bw_osc_tri *instance, float value) {
instance->slope = value; instance->slope = value;
} }

View File

@ -21,43 +21,16 @@
#include <bw_math.h> #include <bw_math.h>
struct _bw_phase_gen { void bw_phase_gen_init(bw_phase_gen *instance) {
// Coefficients
float T;
float portamento_target;
float portamento_mA1;
// Parameters
float frequency;
float portamento_tau;
int param_changed;
// State
char first_run;
float phase;
float portamento_z1;
};
bw_phase_gen bw_phase_gen_new() {
bw_phase_gen instance = (bw_phase_gen)BW_MALLOC(sizeof(struct _bw_phase_gen));
if (instance == NULL)
return NULL;
instance->frequency = 1.f; instance->frequency = 1.f;
instance->portamento_tau = 0.f; instance->portamento_tau = 0.f;
return instance;
} }
void bw_phase_gen_free(bw_phase_gen instance) { void bw_phase_gen_set_sample_rate(bw_phase_gen *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_phase_gen_set_sample_rate(bw_phase_gen instance, float sample_rate) {
instance->T = 1.f / sample_rate; instance->T = 1.f / sample_rate;
} }
void bw_phase_gen_reset(bw_phase_gen instance) { void bw_phase_gen_reset(bw_phase_gen *instance) {
instance->first_run = 1; instance->first_run = 1;
instance->param_changed = ~0; instance->param_changed = ~0;
} }
@ -65,7 +38,7 @@ void bw_phase_gen_reset(bw_phase_gen instance) {
#define PARAM_FREQUENCY 1 #define PARAM_FREQUENCY 1
#define PARAM_PORTAMENTO_TAU (1<<1) #define PARAM_PORTAMENTO_TAU (1<<1)
void bw_phase_gen_process(bw_phase_gen instance, const float *x_mod, float* y, float *y_phase_inc, int n_samples) { void bw_phase_gen_process(bw_phase_gen *instance, const float *x_mod, float* y, float *y_phase_inc, int n_samples) {
if (instance->param_changed) { if (instance->param_changed) {
if (instance->param_changed & PARAM_FREQUENCY) if (instance->param_changed & PARAM_FREQUENCY)
instance->portamento_target = instance->T * instance->frequency; instance->portamento_target = instance->T * instance->frequency;
@ -107,14 +80,14 @@ void bw_phase_gen_process(bw_phase_gen instance, const float *x_mod, float* y, f
} }
} }
void bw_phase_gen_set_frequency(bw_phase_gen instance, float value) { void bw_phase_gen_set_frequency(bw_phase_gen *instance, float value) {
if (instance->frequency != value) { if (instance->frequency != value) {
instance->frequency = value; instance->frequency = value;
instance->param_changed |= PARAM_FREQUENCY; instance->param_changed |= PARAM_FREQUENCY;
} }
} }
void bw_phase_gen_set_portamento_tau(bw_phase_gen instance, float value) { void bw_phase_gen_set_portamento_tau(bw_phase_gen *instance, float value) {
if (instance->portamento_tau != value) { if (instance->portamento_tau != value) {
instance->portamento_tau = value; instance->portamento_tau = value;
instance->param_changed |= PARAM_PORTAMENTO_TAU; instance->param_changed |= PARAM_PORTAMENTO_TAU;

View File

@ -21,44 +21,22 @@
#include <bw_math.h> #include <bw_math.h>
struct _bw_slew_lim { void bw_slew_lim_init(bw_slew_lim *instance) {
// Coefficients instance->init_val = 0.f;
float T; instance->max_inc = INFINITY;
instance->max_dec = INFINITY;
// Parameters
float init_val;
float max_inc_rate;
float max_dec_rate;
// State
char first_run;
float y_z1;
};
bw_slew_lim bw_slew_lim_new() {
bw_slew_lim instance = (bw_slew_lim)BW_MALLOC(sizeof(struct _bw_slew_lim));
if (instance != NULL) {
instance->init_val = 0.f;
instance->max_inc = INFINITY;
instance->max_dec = INFINITY;
}
return instance;
} }
void bw_slew_lim_free(bw_slew_lim instance) { void bw_slew_lim_set_sample_rate(bw_slew_lim *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_slew_lim_set_sample_rate(bw_slew_lim instance, float sample_rate) {
instance->T = 1.f / sample_rate; instance->T = 1.f / sample_rate;
} }
void bw_slew_lim_reset(bw_slew_lim instance) { void bw_slew_lim_reset(bw_slew_lim *instance) {
instance->first_run = 1; instance->first_run = 1;
instance->param_changed = ~0; instance->param_changed = ~0;
} }
void bw_slew_lim_process(bw_slew_lim instance, const float* x, float* y, int n_samples) { void bw_slew_lim_process(bw_slew_lim *instance, const float* x, float* y, int n_samples) {
if (instance->first_run) { if (instance->first_run) {
instance->y_z1 = instance->init_val; instance->y_z1 = instance->init_val;
instance->first_run = 0; instance->first_run = 0;
@ -93,19 +71,19 @@ void bw_slew_lim_process(bw_slew_lim instance, const float* x, float* y, int n_s
} }
} }
void bw_slew_lim_set_init_val(bw_slew_lim instance, float value) { void bw_slew_lim_set_init_val(bw_slew_lim *instance, float value) {
instance->init_val = value; instance->init_val = value;
} }
void bw_slew_lim_set_max_rate(bw_slew_lim instance, float value) { void bw_slew_lim_set_max_rate(bw_slew_lim *instance, float value) {
instance->max_inc_rate = value; instance->max_inc_rate = value;
instance->max_dec_rate = value; instance->max_dec_rate = value;
} }
void bw_slew_lim_set_max_inc_rate(bw_slew_lim instance, float value) { void bw_slew_lim_set_max_inc_rate(bw_slew_lim *instance, float value) {
instance->max_inc_rate = value; instance->max_inc_rate = value;
} }
void bw_slew_lim_set_max_dec_rate(bw_slew_lim instance, float value) { void bw_slew_lim_set_max_dec_rate(bw_slew_lim *instance, float value) {
instance->max_dec_rate = value; instance->max_dec_rate = value;
} }

View File

@ -22,59 +22,24 @@
#include <bw_math.h> #include <bw_math.h>
#include <bw_inline_one_pole.h> #include <bw_inline_one_pole.h>
struct _bw_svf { void bw_svf_init(bw_svf *instance) {
// Coefficients
float t_k;
float smooth_mA1;
float t;
float k;
float hp_hp_z1;
float hp_bp_z1;
float hp_x;
// Parameters
float cutoff;
float Q;
float cutoff_cur;
float Q_cur;
// State
char first_run;
float hp_z1;
float lp_z1;
float bp_z1;
};
bw_svf bw_svf_new() {
bw_svf instance = (bw_svf)BW_MALLOC(sizeof(struct _bw_svf));
if (instance == NULL)
return NULL;
instance->cutoff = 1e3f; instance->cutoff = 1e3f;
instance->Q = 0.5f; instance->Q = 0.5f;
return instance;
} }
void bw_svf_free(bw_svf instance) { void bw_svf_set_sample_rate(bw_svf *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_svf_set_sample_rate(bw_svf instance, float sample_rate) {
instance->t_k = 3.141592653589793f / sample_rate; instance->t_k = 3.141592653589793f / sample_rate;
instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.05f); instance->smooth_mA1 = bw_inline_one_pole_get_mA1(sample_rate, 0.05f);
} }
void bw_svf_reset(bw_svf instance) { void bw_svf_reset(bw_svf *instance) {
instance->first_run = 1; instance->first_run = 1;
} }
#define PARAM_CUTOFF 1 #define PARAM_CUTOFF 1
#define PARAM_Q (1<<1) #define PARAM_Q (1<<1)
static inline void update_coefficients(bw_svf instance) { static inline void update_coefficients(bw_svf *instance) {
const char cutoff_changed = instance->cutoff != instance->cutoff_cur || instance->first_run; const char cutoff_changed = instance->cutoff != instance->cutoff_cur || instance->first_run;
const char Q_changed = instance->Q != instance->Q_cur || instance->first_run; const char Q_changed = instance->Q != instance->Q_cur || instance->first_run;
if (cutoff_changed || Q_changed) { if (cutoff_changed || Q_changed) {
@ -93,7 +58,7 @@ static inline void update_coefficients(bw_svf instance) {
} }
} }
void bw_svf_process(bw_svf instance, const float *x, float *y_lp, float *y_bp, float *y_hp, int n_samples) { void bw_svf_process(bw_svf *instance, const float *x, float *y_lp, float *y_bp, float *y_hp, int n_samples) {
if (instance->first_run) { if (instance->first_run) {
instance->cutoff_cur = instance->cutoff; instance->cutoff_cur = instance->cutoff;
instance->Q_cur = instance->Q; instance->Q_cur = instance->Q;
@ -122,10 +87,10 @@ void bw_svf_process(bw_svf instance, const float *x, float *y_lp, float *y_bp, f
} }
} }
void bw_svf_set_cutoff(bw_svf instance, float value) { void bw_svf_set_cutoff(bw_svf *instance, float value) {
instance->cutoff = value; instance->cutoff = value;
} }
void bw_svf_set_Q(bw_svf instance, float value) { void bw_svf_set_Q(bw_svf *instance, float value) {
instance->Q = value; instance->Q = value;
} }

View File

@ -21,56 +21,28 @@
#include <bw_inline_slew_lim.h> #include <bw_inline_slew_lim.h>
#define BUFFER_SIZE 32 void bw_vol_init(bw_vol *instance) {
struct _bw_vol {
// Coefficients
float max_var;
// Parameters
float volume;
float volume_cur;
// State
char first_run;
// Buffers
float buf[BUFFER_SIZE];
};
bw_vol bw_vol_new() {
bw_vol instance = (bw_vol)BW_MALLOC(sizeof(struct _bw_vol));
if (instance == NULL)
return NULL;
instance->volume = 1.f; instance->volume = 1.f;
return instance;
} }
void bw_vol_free(bw_vol instance) { void bw_vol_set_sample_rate(bw_vol *instance, float sample_rate) {
BW_FREE(instance);
}
void bw_vol_set_sample_rate(bw_vol instance, float sample_rate) {
instance->max_var = bw_inline_slew_lim_get_max_var(sample_rate, 1.f / 0.05f); instance->max_var = bw_inline_slew_lim_get_max_var(sample_rate, 1.f / 0.05f);
} }
void bw_vol_reset(bw_vol instance) { void bw_vol_reset(bw_vol *instance) {
instance->first_run = 1; instance->first_run = 1;
} }
void bw_vol_process(bw_vol instance, const float **x, float **y, int n_channels, int n_samples) { void bw_vol_process(bw_vol *instance, const float **x, float **y, int n_channels, int n_samples) {
if (instance->first_run) { if (instance->first_run) {
instance->volume_cur = instance->volume; instance->volume_cur = instance->volume;
instance->first_run = 0; instance->first_run = 0;
} }
for (int i = 0; i < n_samples; i += BUFFER_SIZE) { for (int i = 0; i < n_samples; i += _BW_VOL_BUFFER_SIZE) {
const uint32_t n = bw_minu32(n_samples - i, BUFFER_SIZE); const uint32_t n = bw_minu32(n_samples - i, _BW_VOL_BUFFER_SIZE);
for (int j = 0; j < BUFFER_SIZE; j++) { for (int j = 0; j < _BW_VOL_BUFFER_SIZE; j++) {
instance->volume_cur = bw_inline_slew_lim(instance->volume, instance->volume_cur, instance->max_var, instance->max_var); instance->volume_cur = bw_inline_slew_lim(instance->volume, instance->volume_cur, instance->max_var, instance->max_var);
instance->buf[j] = instance->volume_cur * instance->volume_cur * instance->volume_cur; instance->buf[j] = instance->volume_cur * instance->volume_cur * instance->volume_cur;
} }
@ -78,12 +50,12 @@ void bw_vol_process(bw_vol instance, const float **x, float **y, int n_channels,
for (int j = 0; j < n_channels; j++) { for (int j = 0; j < n_channels; j++) {
const float *in = x[j] + i; const float *in = x[j] + i;
float *out = y[j] + i; float *out = y[j] + i;
for (int k = 0; k < BUFFER_SIZE; k++) for (int k = 0; k < _BW_VOL_BUFFER_SIZE; k++)
out[k] = instance->buf[k] * in[k]; out[k] = instance->buf[k] * in[k];
} }
} }
} }
void bw_vol_set_volume(bw_vol instance, float value) { void bw_vol_set_volume(bw_vol *instance, float value) {
instance->volume = value; instance->volume = value;
} }