refactored DSP modules APIs to avoid dynamic memory allocations
This commit is contained in:
parent
61d0c690e9
commit
0402576e84
7
ChangeLog
Normal file
7
ChangeLog
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
0.2.0
|
||||||
|
-----
|
||||||
|
Refactored API of DSP modules to avoid dynamic memory allocation.
|
||||||
|
|
||||||
|
0.1.0
|
||||||
|
-----
|
||||||
|
First release.
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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_set_sample_rate(bw_env_follow *instance, float sample_rate) {
|
||||||
|
bw_one_pole_set_sample_rate(&instance->one_pole, sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bw_env_follow_free(bw_env_follow instance) {
|
void bw_env_follow_reset(bw_env_follow *instance) {
|
||||||
bw_one_pole_free(instance->one_pole);
|
bw_one_pole_reset(&instance->one_pole);
|
||||||
BW_FREE(instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bw_env_follow_set_sample_rate(bw_env_follow instance, float sample_rate) {
|
void bw_env_follow_process(bw_env_follow *instance, const float *x, float *y, int n_samples) {
|
||||||
bw_one_pole_set_sample_rate(instance->one_pole, sample_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bw_env_follow_reset(bw_env_follow instance) {
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
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->init_val = 0.f;
|
||||||
instance->cutoff_up = INFINITY;
|
instance->cutoff_up = INFINITY;
|
||||||
instance->cutoff_down = INFINITY;
|
instance->cutoff_down = INFINITY;
|
||||||
instance->sticky_thresh = 0.f;
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
|
||||||
float T;
|
|
||||||
|
|
||||||
// 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->init_val = 0.f;
|
||||||
instance->max_inc = INFINITY;
|
instance->max_inc = INFINITY;
|
||||||
instance->max_dec = 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;
|
||||||
}
|
}
|
||||||
|
49
src/bw_svf.c
49
src/bw_svf.c
@ -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;
|
||||||
}
|
}
|
||||||
|
46
src/bw_vol.c
46
src/bw_vol.c
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user